Sim, você deve fazer o teste [[ $((i % 2)) -eq 0 && $((i % 3)) -eq 0 ... ... ]]
.
Ele testará se um número $i
é divisível por todos os números na lista, ao mesmo tempo .
Mas o que você está fazendo se o número coincidir com esse teste?
Imprima porque achou o número?
Não, você está incrementando, o que você precisa é reverter a ação, em outras palavras:
Increment
$i
if the test fails.
Faça o seguinte:
while ! [[ … . … ]]; do
Ou:
until [[ … . … ]]; do
Fazer isso levará uma quantidade enorme de tempo para encontrar 9699690 (o número que você procura com seu código, que também não é a resposta correta).
A maneira correta de encontrá-lo está à frente, continue lendo.
Somente primos?
No entanto, por que você não está incluindo, por exemplo, 4 ou 6 ou 9, etc ...
Porque eles não são primos? Deixe-me esclarecer com um exemplo da ideia.
O número 9699690 é divisível por todos os primos (2 3 5 7 9 11 13 17 19) em seu teste, mas não é divisível por 4
.
O código que você escreveu falha. E leva muito tempo para encontrar a resposta por força bruta (experimentando cada um dos inteiros até encontrar o correto, especialmente no shell, que é uma das línguas mais lentas que existem).
L.C.M.
Mas o problema poderia ser mais fácil se descrevêssemos isso dizendo:
find the LCM of the list {1..20}.
Esse é o L leste C que omite M ultiplas de vários números.
O LCM é: LCM(a,b) = (a*b) / gcd(a,b)
(uma equação matemática).
G.C.D.
Onde gcd id o G reatest C ommon D ivisor.
E Euclides (cerca de 2300 anos atrás) descreveu o primeiro. O algoritmo de Euclides , é um método eficiente para calcular o maior divisor comum (GCD) de dois números
Página do algoritmo de Euclides
Algoritmo de Euclides no código shell Unix
Múltiplo menos comum: um quebra-cabeça
A implementação em shells modernas como uma função é bastante simples:
gcd() { # Calculate $1 % $2 until $2 becomes zero.
until [ "$2" -eq 0 ]; do set -- "$2" "$(($1%$2))"; done
echo "$1"
}
E o código lcm também é simples:
lcm() { echo "$(( $1 / $(gcd "$1" "$2") * $2 ))"; }
O que é necessário é repetir todos os argumentos até que apenas um permaneça:
while [ $# -gt 1 ]
do
t="$(lcm "$1" "$2")"
shift 2
set -- "$t" "$@"
done
echo "$1"
Chamar todo o programa com os números que você usou indica o número que usei acima:
$ ./script 2 3 5 7 11 13 17 19
9699690
Você pode chamar o script como:
$ ./script {2..20}
Para obter a resposta final.