死ぬことなくパフォーマンスを向上させるには、[ $(($1 % $check)) -ne 0 ];を実行できますか?

死ぬことなくパフォーマンスを向上させるには、[ $(($1 % $check)) -ne 0 ];を実行できますか?

次のコードがあれば、秒で最大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

((結果がゼロでない場合、ゼロが返されるという事実を利用できます。

if (( $1 % check )); then
  ...
fi

答え3

降順で繰り返します。ループが早く終了することがあります。

for ((check=12; check>1; --check)) {

変える

for ((check=2; check<13; check++)) {

それについて考えてみてください。 12 に分けられない数は 4、3、2 に分けられません。その逆は真実ではありません。

関連情報