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打印它,因为你找到了数字?
不,您正在递增它。\xc2\xa0\n您需要的是反转该操作;换句话说:
\n\n\n\n
$i
如果测试失败则增加。
要么做:
\nwhile ! [[ \xe2\x80\xa6 . \xe2\x80\xa6 ]]; do\n
Run Code Online (Sandbox Code Playgroud)\n或者:
\nuntil [[ \xe2\x80\xa6 . \xe2\x80\xa6 ]]; do\n
Run Code Online (Sandbox Code Playgroud)\n这样做将花费大量时间才能找到 9699690(您用代码寻找的数字,这也不是正确的答案)。
\n正确的查找方法就在前面;继续阅读。
\n但是,为什么你不包括,例如 4 或 6 或 9 等......
\n因为它们不是素数?让我用一个例子来阐明这个想法。
\n数字 9699690 可被测试中的所有素数 (2 3 5 7 9 11 13 17 19) 整除,但不能被\xc2\xa04 整除。
你写的代码失败了。通过蛮力找到答案需要很长时间(尝试每一个整数,直到找到正确的整数,特别是在 shell 中,这是最慢的语言之一)。
\n但如果我们这样描述问题可能会更容易:
\n\n\n找到列表 {1..20} 的 LCM。
\n
这是几个数字的最小公倍数。 \xc2\xa0\n最小公倍数是:( 一个数学方程)。LCM(a,b) = (a\xc3\x97b) / gcd(a,b)
其中gcd是最大公约数。
\n欧几里得(大约 2300 年前)描述了第一个。\xc2\xa0\n欧几里得算法是计算两个数字的最大公约数 (GCD) 的有效方法。
\n\n现代 shell 中作为函数的实现非常简单:
\ngcd() { # 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 代码也很简单:
\nlcm() { echo "$(( $1 / $(gcd "$1" "$2") * $2 ))"; }\n
Run Code Online (Sandbox Code Playgroud)\n需要的是循环所有给定的参数,直到只剩下一个:
\nwhile [ $# -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