다음 코드가 있으면 초 안에 최대 13개(라인 2)까지 실행되지만 상위 12개와 20개를 실행하려고 하면 몇 분 후에 종료됩니다.
divisible_by () {
for ((check=2; check<13; check++)) {
if [ $(($1 % $check)) -ne 0 ]; then
return
fi
}
echo "$1 is divisible by all the numbers"
exit 0
}
d=0
while true; do
d=$((d+1))
divisible_by $d
done
나는 사용하려고
if $(($1 % $check)) -ne 0; then
하지만 난 이해해1: command not found
나는 노력했다
if $(($1 % $check)) -ne 0; then
하지만 난 1:command not found
얻었고-ne command not found
나는 노력했다
if [ $($1 % $check) -ne 0 ]; then
하지만 난 1:command not found
얻었고-ne: unary operator expected
나는 노력했다
if [ $1 % $check -ne 0 ]; then
하지만 난 얻었어[: too many arguments
답변1
여기서 목표가 2부터 n까지의 정수로 나누어지는 가장 작은 수를 찾는 것이라고 가정하면 모든 정수를 확인하는 것은 매우 비효율적입니다. 제가 생각할 수 있는 가장 간단한 알고리즘은 일련의 요소를 사용하여 결과적으로 곱하여 답을 제공하는 것입니다. 텅 빈 상태로 시작됩니다. 그런 다음 각 숫자를 순서대로 가져와 고유한 요소 집합에서 기존 요소를 제거합니다. 나머지는 고유 요소 집합에 추가되며 집합이 현재 숫자로 나누어질 것이라는 것을 알고 있습니다. 이 집합의 곱은 필요한 모든 나눗셈을 만족하는 가장 작은 소인수 집합을 포함하므로 2부터 n까지의 모든 숫자로 나누어지는 가장 작은 숫자가 보장됩니다.
upto=20
uniqueFactors=()
for ((i=2; i <= upto; i++))
do
newFactors=$i
for factor in "${uniqueFactors[@]}" #loop over array of factors
do
if [ $(($newFactors%$factor)) -eq 0 ]; then
newFactors=$(($newFactors/$factor));
fi;
done
uniqueFactors+=($newFactors);
done
product=1
for factor in "${uniqueFactors[@]}"
do
product=$(bc <<< "$product*$factor") #use bc for numbers outside integer range
done
echo $product
내 컴퓨터에서는 4밀리초 안에 2-20으로 나눌 수 있는 첫 번째 숫자(232792560)를 계산합니다. 0.425초에 100(69720375229712477164533808935312303556800)을 계산했고, 4.813초에 1000(소수점 수백 자리의 숫자)을 계산했다. 그렇게 많은 숫자를 반복하려고 한다면 우주의 열사멸로 인해 프로세스가 중단될까 봐 걱정해야 합니다. 단일 생산 라인을 최적화하면 백분율 또는 규모의 향상을 얻을 수 있습니다. 알고리즘을 변경하면 로그 개선이 가능합니다.
답변2
((
결과가 0이 아닐 때 0이 반환된다는 사실을 활용할 수 있습니다.
if (( $1 % check )); then
...
fi
답변3
내림차순으로 반복하겠습니다. 루프가 더 빨리 종료될 수 있습니다.
for ((check=12; check>1; --check)) {
바꾸다
for ((check=2; check<13; check++)) {
그것에 대해 생각해보세요. 12로 나누어지지 않는 수는 4, 3, 2로도 나누어지지 않습니다. 그 반대는 사실이 아닙니다.