/* Proper divisors (Rosetta code) in Picat. http://rosettacode.org/wiki/Proper_divisors """ The proper divisors of a positive integer N are those numbers, other than N itself, that divide N without remainder. For N > 1 they will always include 1, but for N == 1 their are no proper divisors. For example the proper divisors of 6 are 1, 2, and 3. The proper divisors of 100 are 1, 2, 4, 5, 10, 20, 25, and 50. Task - Create a routine to generate all the proper divisors of a number. - use it to show the proper divisors of the numbers 1 to 10 inclusive. - Find a number in the range 1 to 20,000 with the most proper divisors. Show the number and just the count of how many proper divisors it has. Show all output here. """ This Picat model was created by Hakan Kjellerstrand, hakank@gmail.com See also my Picat page: http://www.hakank.org/picat/ */ main => go. % % foreach loop: 0.24s % go => println(proper_divisors(100)), foreach(N in 1..10) println(N=proper_divisors(N)) end, MaxN = [], MaxDivisors = [], MaxLen = 1, foreach(N in 1..20_000, not prime(N)) D = proper_divisors(N), Len = D.len, % Get all number with most proper divisors if Len = MaxLen then MaxN := MaxN ++ [N], MaxDivisors := MaxDivisors ++ [[N=D]] elseif Len > MaxLen then MaxLen := Len, MaxN := [N], MaxDivisors := [N=D] end end, println(maxN=MaxN), println(divisors=MaxDivisors), println(maxLen=MaxLen), nl. % % Using list comprehension and map: 0.26s % go2 => Map = new_map([N=proper_divisors(N).len : N in 1..20_000]), MaxNum = max([D : _=D in Map]), println(maxNum=MaxNum), % println(maxN=[N : N=MaxNum in Map]), % "Warning: nonlocal_var_in_iterator_pattern" println(maxN=[N : N=M in Map, M=MaxNum]), nl. % 0.3s proper_divisors(N) = Divisors => Div1 = [ I : I in 1..ceiling(sqrt(N)), N mod I == 0], Divisors = (Div1 ++ [N div I : I in Div1]).sort_remove_dups().delete(N). % slower: 8.5s proper_divisors2(N) = [ I : I in 1..N div 2, N mod I == 0].