5. Smallest multiple
https://projecteuler.net/problem=5
2520 is the smallest number that can be divided by each of the numbers from 1 to 10 without any remainder. What is the smallest positive number that is evenly divisible by all of the numbers from 1 to 20?
Solve
Start by reproducing the example. 10 is the smallest candidate. Start with 10 and keep incrementing; as long as any mod 1+til 10
A while-loop will do the job.
q)f:1+til10;i:10;while[anyimodf;i+:1]; i2520
We can write the same in functional form using the While form of the Over iterator, with a composition as the truth function.
q)(anymod[;1+til10]@) (1+)/102520
Improve
But we donÂ’t need to test every number. A number evenly divisible by 1+til 10
must be evenly divisible by each of the primes in that list, i.e. 2 3 5 7
, and must therefore be divisible by their product P
. We can start with P
, and test multiples of it.
q)(anymod[;1+til10]@) (P+)/P:prd23572520q)\ts:100(anymod[;1+til10]@) (1+)/102392064q)\ts:100(anymod[;1+til10]@) (P+)/P:prd235712848
With the numbers from 1 to 20, P
becomes 9699690, and the search takes very little longer.
q)\ts:100(anymod[;1+til20]@) (P+)/P:prd23571113171933168
Generalise
For a number N
we need the primes below it. Enter EratosthenesÂ’ Sieve.
kc:{(1#2;0b,1\_x#10b)} / (known primes; flag candidates)snp:{(x,n;y&count[y]#i<>tiln:1+i:y?1b)}. / sieve next primees:raze@[;1;1+where@] {{x>lastfirsty}[floorsqrtx]snp/kcx}@ / Eratosthenes' sieve
q){(anymod[;1+tilx]@) (P+)/P:prdesx}102520