Smallest multiple
- Task
Task desciption is taken from Project Euler
(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?
ALGOL 68
Uses Algol 68G's LONG LONG INT which has specifiable precision.
<lang algol68>BEGIN # find the smallest number that is divisible by each of the numbers 1..n #
# translation of the Wren sample # PR precision 1000 PR # set the precision of LONG LONG INT # PR read "primes.incl.a68" PR # returns the lowest common multiple of the numbers 1 : n # PROC lcm = ( INT n )LONG LONG INT: BEGIN # sieve the primes to n # []BOOL prime = PRIMESIEVE n; LONG LONG INT result := 1; FOR p TO UPB prime DO IF prime[ p ] THEN LONG LONG INT f := p; # f will be set to the # WHILE f * p <= n DO f *:= p OD; # highest multiple of p <= n # result *:= f FI OD; result END # lcm # ; # returns a string representation of n with commas # PROC commatise = ( LONG LONG INT n )STRING: BEGIN STRING result := ""; STRING unformatted = whole( n, 0 ); INT ch count := 0; FOR c FROM UPB unformatted BY -1 TO LWB unformatted DO IF ch count <= 2 THEN ch count +:= 1 ELSE ch count := 1; "," +=: result FI; unformatted[ c ] +=: result OD; result END; # commatise # print( ( "The LCMs of the numbers 1 to N inclusive is:", newline ) ); []INT tests = ( 10, 20, 200, 2000 ); FOR i FROM LWB tests TO UPB tests DO print( ( whole( tests[ i ], -5 ), ": ", commatise( lcm( tests[ i ] ) ), newline ) ) OD
END</lang>
- Output:
10: 2,520 20: 232,792,560 200: 337,293,588,832,926,264,639,465,766,794,841,407,432,394,382,785,157,234,228,847,021,917,234,018,060,677,390,066,992,000 2000: 151,117,794,877,444,315,307,536,308,337,572,822,173,736,308,853,579,339,903,227,904,473,000,476,322,347,234,655,122,160,866,668,946,941,993,951,014,270,933,512,030,194,957,221,371,956,828,843,521,568,082,173,786,251,242,333,157,830,450,435,623,211,664,308,500,316,844,478,617,809,101,158,220,672,108,895,053,508,829,266,120,497,031,742,749,376,045,929,890,296,052,805,527,212,315,382,805,219,353,316,270,742,572,401,962,035,464,878,235,703,759,464,796,806,075,131,056,520,079,836,955,770,415,021,318,508,272,982,103,736,658,633,390,411,347,759,000,563,271,226,062,182,345,964,184,167,346,918,225,243,856,348,794,013,355,418,404,695,826,256,911,622,054,015,423,611,375,261,945,905,974,225,257,659,010,379,414,787,547,681,984,112,941,581,325,198,396,634,685,659,217,861,208,771,400,322,507,388,161,967,513,719,166,366,839,894,214,040,787,733,471,287,845,629,833,993,885,413,462,225,294,548,785,581,641,804,620,417,256,563,685,280,586,511,301,918,399,010,451,347,815,776,570,842,790,738,545,306,707,750,937,624,267,501,103,840,324,470,083,425,714,138,183,905,657,667,736,579,430,274,197,734,179,172,691,637,931,540,695,631,396,056,193,786,415,805,463,680,000
Go
<lang go>package main
import (
"fmt" "math/big" "rcu"
)
func lcm(n int) *big.Int {
lcm := big.NewInt(1) t := new(big.Int) for _, p := range rcu.Primes(n) { f := p for f*p <= n { f *= p } lcm.Mul(lcm, t.SetUint64(uint64(f))) } return lcm
}
func main() {
fmt.Println("The LCMs of the numbers 1 to N inclusive is:") for _, i := range []int{10, 20, 200, 2000} { fmt.Printf("%4d: %s\n", i, lcm(i)) }
}</lang>
- Output:
The LCMs of the numbers 1 to N inclusive is: 10: 2520 20: 232792560 200: 337293588832926264639465766794841407432394382785157234228847021917234018060677390066992000 2000: 151117794877444315307536308337572822173736308853579339903227904473000476322347234655122160866668946941993951014270933512030194957221371956828843521568082173786251242333157830450435623211664308500316844478617809101158220672108895053508829266120497031742749376045929890296052805527212315382805219353316270742572401962035464878235703759464796806075131056520079836955770415021318508272982103736658633390411347759000563271226062182345964184167346918225243856348794013355418404695826256911622054015423611375261945905974225257659010379414787547681984112941581325198396634685659217861208771400322507388161967513719166366839894214040787733471287845629833993885413462225294548785581641804620417256563685280586511301918399010451347815776570842790738545306707750937624267501103840324470083425714138183905657667736579430274197734179172691637931540695631396056193786415805463680000
Pascal
Here the simplest way, like Raku, check the highest exponent of every prime in range
Using harded coded primes.
<lang pascal>{$IFDEF FPC}
{$MODE DELPHI}
{$ELSE}
{$APPTAYPE CONSOLE}
{$ENDIF} const
smallprimes : array[0..10] of Uint32 = (2,3,5,7,11,13,17,19,23,29,31); MAX = 20;
function getmaxfac(pr: Uint32): Uint32; //get the pr^highest exponent of prime used in 2 .. MAX var
i,fac : integer;
Begin
result := pr; while pr*result <= MAX do result *= pr;
end;
var
n,pr,prIdx : Uint32;
BEGIN
n := 1; prIdx := 0; pr := smallprimes[prIdx]; repeat pr := smallprimes[prIdx]; n *= getmaxfac(pr); inc(prIdx); pr := smallprimes[prIdx]; until pr>MAX; writeln(n);
{$IFDEF WINDOWS}
READLN;
{$ENDIF} END. </lang>
- Output:
232792560
Raku
Exercise with some larger values as well.
<lang perl6>say "$_: ", [lcm] 2..$_ for <10 20 200 2000></lang>
- Output:
10: 2520 20: 232792560 200: 337293588832926264639465766794841407432394382785157234228847021917234018060677390066992000 2000: 151117794877444315307536308337572822173736308853579339903227904473000476322347234655122160866668946941993951014270933512030194957221371956828843521568082173786251242333157830450435623211664308500316844478617809101158220672108895053508829266120497031742749376045929890296052805527212315382805219353316270742572401962035464878235703759464796806075131056520079836955770415021318508272982103736658633390411347759000563271226062182345964184167346918225243856348794013355418404695826256911622054015423611375261945905974225257659010379414787547681984112941581325198396634685659217861208771400322507388161967513719166366839894214040787733471287845629833993885413462225294548785581641804620417256563685280586511301918399010451347815776570842790738545306707750937624267501103840324470083425714138183905657667736579430274197734179172691637931540695631396056193786415805463680000
Ring
<lang ring> see "working..." + nl see "Smallest multiple is:" + nl n = 0
while true
n++ flag = 0 for m = 1 to 20 if n % m = 0 flag += 1 ok next if flag = 20 see "" + n + nl exit ok
end
see "done..." + nl </lang>
- Output:
working... Smallest multiple is: 232792560 done...
Wren
We don't really need a computer for the task as set because it's just the product of the maximum prime powers <= 20 which is : 16 x 9 x 5 x 7 x 11 x 13 x 17 x 19 = 232,792,560.
More formally and quite quick by Wren standards at 0.017 seconds: <lang ecmascript>import "./math" for Int import "./big" for BigInt import "./fmt" for Fmt
var lcm = Fn.new { |n|
var primes = Int.primeSieve(n) var lcm = BigInt.one for (p in primes) { var f = p while (f * p <= n) f = f * p lcm = lcm * f } return lcm
}
System.print("The LCMs of the numbers 1 to N inclusive is:") for (i in [10, 20, 200, 2000]) Fmt.print("$,5d: $,i", i, lcm.call(i))</lang>
- Output:
The LCMs of the numbers 1 to N inclusive is: 10: 2,520 20: 232,792,560 200: 337,293,588,832,926,264,639,465,766,794,841,407,432,394,382,785,157,234,228,847,021,917,234,018,060,677,390,066,992,000 2,000: 151,117,794,877,444,315,307,536,308,337,572,822,173,736,308,853,579,339,903,227,904,473,000,476,322,347,234,655,122,160,866,668,946,941,993,951,014,270,933,512,030,194,957,221,371,956,828,843,521,568,082,173,786,251,242,333,157,830,450,435,623,211,664,308,500,316,844,478,617,809,101,158,220,672,108,895,053,508,829,266,120,497,031,742,749,376,045,929,890,296,052,805,527,212,315,382,805,219,353,316,270,742,572,401,962,035,464,878,235,703,759,464,796,806,075,131,056,520,079,836,955,770,415,021,318,508,272,982,103,736,658,633,390,411,347,759,000,563,271,226,062,182,345,964,184,167,346,918,225,243,856,348,794,013,355,418,404,695,826,256,911,622,054,015,423,611,375,261,945,905,974,225,257,659,010,379,414,787,547,681,984,112,941,581,325,198,396,634,685,659,217,861,208,771,400,322,507,388,161,967,513,719,166,366,839,894,214,040,787,733,471,287,845,629,833,993,885,413,462,225,294,548,785,581,641,804,620,417,256,563,685,280,586,511,301,918,399,010,451,347,815,776,570,842,790,738,545,306,707,750,937,624,267,501,103,840,324,470,083,425,714,138,183,905,657,667,736,579,430,274,197,734,179,172,691,637,931,540,695,631,396,056,193,786,415,805,463,680,000