/* Euler #44 in Picat. """ Pentagonal numbers are generated by the formula, P(n)=n(3nāˆ’1)/2. The first ten pentagonal numbers are: 1, 5, 12, 22, 35, 51, 70, 92, 117, 145, ... It can be seen that P(4) + P(7) = 22 + 70 = 92 = P(8). However, their difference, 70 āˆ’ 22 = 48, is not pentagonal. Find the pair of pentagonal numbers, P(j) and P(k), for which their sum and difference is pentagonal and D = |P(k) āˆ’ P(j)| is minimised; what is the value of D? """ This Picat model was created by Hakan Kjellerstrand, hakank@gmail.com See also my Picat page: http://www.hakank.org/picat/ */ import cp. main => go. go => time(euler44). euler44 => % garbage_collect(200_000_000), % S = [pent(N) : N in 1..2500], S = [N*(3*N-1) div 2 : N in 1..2500], % T = new_map(2500,[V=1 : V in S]), T = new_set(S), D = 10000000, foreach(J in S.reverse(), K in S, J < K, A = J+K, A < D, T.has_key(A), B = abs(J-K), B < D, T.has_key(B)) D := B end, println(D). % slower euler44b => garbage_collect(200_000_000), % S = [pent(N) : N in 1..2500], S = [N*(3*N-1) div 2 : N in 1..2500], % T = new_map(2500,[V=1 : V in S]), T = new_set(2500,S), D = [B : J in S, K in S, J < K, A = J+K, T.has_key(A), B = abs(J-K), T.has_key(B)], println(D.first()). % same idea, another approach, slower euler44c => garbage_collect(200_000_000), M = 2500, T = new_set(M,[N*(3*N-1) div 2 : N in 1..M]), Min = 100000000, foreach(A in T.keys(), B in T.keys(), A <= B) Diff = abs(A-B), Sum = A+B, if Diff < Min, T.has_key(Diff), T.has_key(Sum) then Min := Diff end end, println(Min), nl. % % cp approach: very slow % euler44d => S = [N*(3*N-1) div 2 : N in 1..2500], Vars = [D,A,J,K], Vars :: S, J #< K, A #= J+K, D #= abs(J-K), solve($[down,report(printf("D: %w\n",D))],Vars), println(Vars), println(d=D). pent(N) = N*(3*N-1) div 2.