Korac의 추측을 테스트하는 스크립트를 만들고 싶습니다. 보다 구체적으로 목표는 1이 아닌 양의 정수를 입력할 수 있는 스크립트를 만들고 Collatz 알고리즘이 완료되면 1이 될 것으로 예상되는 최종 숫자를 인쇄하는 것입니다.
임의의 양의 정수 n을 취합니다. n이 짝수이면 n을 2로 나누어 n/2를 얻습니다. n이 홀수이면 n에 3을 곱하고 1을 더해 3n + 1이 됩니다. 이 과정을 무한정 반복하세요. 어떤 숫자로 시작하든 결국 1에 도달한다는 추측입니다.
이것이 나의 시도이다 -
echo "Enter in a positive integer greater than 1"
read n
let "r=$n%2"
if [ $n -le 1 ]
then
echo "Error: you must enter in a positive integer greater than 1"
exit
fi
while [ $n -ne 1 ]
do
if [ $r == 0 ]
then
let "n=$n/2"
echo $n
fi
if [ $r -ne 0 ]
then
let "n=3*$n + 1"
echo $n
fi
done
echo $n
2를 입력하면 1이 나오며 이는 원하는 결과입니다. 그러나 3의 값을 읽으면 다음과 같은 무한 루프가 발생합니다.
931947686741790850
2795843060225372551
8387529180676117654
6715843468318801347
1700786331246852426
5102358993740557279
-3139667092487879778
9027742796245912283
.
.
.
등.
내 정확한 질문은 다음과 같습니다.내 코드에 문제가 있나요? 큰 숫자를 인쇄하는 원인은 무엇입니까?
답변1
이것:
let "r=$n%2"
...
while [ $n -ne 1 ]
do
if [ $r == 0 ]
...
done
r
루프 외부에서 한 번만 할당합니다.
대부분의 프로그래밍 언어에서 할당과 같은 것은 y = f(x)
"현재 값을 가져 x
와서 f(x)
계산을 수행한 다음 결과를 복사 y
"하는 것을 의미합니다. 이는 "지금부터 영원까지 y
항상 동일해야 한다 " 는 수학적 설명과는 다릅니다 f(x)
. 코드 에서는 n
다음과 같이 작동하지 않습니다. 값을 수정하고 루프의 여러 반복에서 달라지도록 의존합니다.
r
따라서 초기 숫자에서 얻은 값은 루프 전체에 걸쳐 유지되며 루프가 반복될 때마다 동일한 작업을 반복할 수 있습니다. 물론, 트리플 원은 엄청난 숫자에 도달하여 넘쳐나기 시작할 것입니다.
해결책은 간단합니다. 할당을 r
루프 내부로 이동하여 n
변경될 때마다 다시 계산되도록 합니다.
또한 인용되지 않은 변수 확장의 일반적인 문제가 있지만 이는 문제가 아닙니다.