尝试完成 Project Euler #5,通过了所有语法检查,但不起作用

Egr*_*odo -1 bash algorithms math

尝试完成Project Euler #5。我的代码在逻辑上应该可以工作,并且它通过了 ShellCheck,但由于某种原因没有给出输出。代码如下。谢谢,抱歉,如果这应该在不同的堆栈交换站点中

#!/bin/bash
 i=1
 while [[ $((i % 2)) -eq 0 && $((i % 3)) -eq 0 && $((i % 5)) -eq 0 && $((i % 7)) -eq 0 && $((i % 11)) -eq 0 && $((i % 13)) -eq 0 && $((i % 17)) -eq 0 && $((i  % 19)) -eq 0 ]]
 do
     i=$((i+1))
 done
 echo $i
Run Code Online (Sandbox Code Playgroud)

小智 5

是的,您应该进行测试[[ $((i % 2)) -eq 0 && $((i % 3)) -eq 0 \xe2\x80\xa6\xe2\x80\x82\xe2\x80\xa6 ]]。\xc2\xa0\n它将同时$i测试一个数字是否可以被列表中的所有数字整除。\n 。\xc2\xa0\n但是如果该数字与该数字匹配,您会做什么test?\xc2\xa0\n打印它,因为你找到了数字?

\n

不,您正在递增它。\xc2\xa0\n您需要的是反转该操作;换句话说:

\n
\n

$i如果测试失败则增加。

\n
\n

要么做:

\n
while ! [[ \xe2\x80\xa6 . \xe2\x80\xa6 ]]; do\n
Run Code Online (Sandbox Code Playgroud)\n

或者:

\n
until [[ \xe2\x80\xa6 . \xe2\x80\xa6 ]]; do\n
Run Code Online (Sandbox Code Playgroud)\n

这样做将花费大量时间才能找到 9699690(您用代码寻找的数字,这也不是正确的答案)。

\n

正确的查找方法就在前面;继续阅读。

\n

只有素数吗?

\n

但是,为什么你不包括,例如 4 或 6 或 9 等......

\n

因为它们不是素数?让我用一个例子来阐明这个想法。
\n数字 9699690 可被测试中的所有素数 (2 3 5 7 9 11 13 17 19) 整除,但不能被\xc2\xa04 整除。

\n

你写的代码失败了。通过蛮力找到答案需要很长时间(尝试每一个整数,直到找到正确的整数,特别是在 shell 中,这是最慢的语言之一)。

\n
\n

液晶模组

\n

但如果我们这样描述问题可能会更容易:

\n
\n

找到列表 {1..20} 的 LCM。

\n
\n

这是几个数字的最小公倍数 \xc2\xa0\n最小公倍数是:( 一个数学方程)。LCM(a,b) = (a\xc3\x97b) / gcd(a,b)

\n

GCD

\n

其中gcd最大公约数。​​

\n

欧几里得(大约 2300 年前)描述了第一个。\xc2\xa0\n欧几里得算法是计算两个数字的最大公约数 (GCD) 的有效方法。

\n\n

现代 shell 中作为函数的实现非常简单:

\n
gcd() {   # Calculate $1 % $2 until $2 becomes zero.\n          until [ "$2" -eq 0 ]; do set -- "$2" "$(($1%$2))"; done\n          echo "$1"\n      }\n
Run Code Online (Sandbox Code Playgroud)\n

然后 lcm 代码也很简单:

\n
lcm() {   echo "$(( $1 / $(gcd "$1" "$2") * $2 ))";   }\n
Run Code Online (Sandbox Code Playgroud)\n

需要的是循环所有给定的参数,直到只剩下一个:

\n
while  [ $# -gt 1 ]\ndo\n       t="$(lcm "$1" "$2")"\n       shift 2\n       set -- "$t" "$@"\ndone\necho "$1"\n
Run Code Online (Sandbox Code Playgroud)\n

使用您使用的号码调用整个程序给出了我上面使用的号码:

\n
$ ./script 2 3 5 7 11 13 17 19\n9699690\n
Run Code Online (Sandbox Code Playgroud)\n

您可以将该脚本称为:

\n
$ ./script {2..20}\n
Run Code Online (Sandbox Code Playgroud)\n

才能得到最终的答案。

\n