/* Euler #49 in Picat. """ The arithmetic sequence, 1487, 4817, 8147, in which each of the terms increases by 3330, is unusual in two ways: (i) each of the three terms are prime, and, (ii) each of the 4-digit numbers are permutations of one another. There are no arithmetic sequences made up of three 1-, 2-, or 3-digit primes, exhibiting this property, but there is one other 4-digit increasing sequence. What 12-digit number do you form by concatenating the three terms in this sequence? """ This Picat model was created by Hakan Kjellerstrand, hakank@gmail.com See also my Picat page: http://www.hakank.org/picat/ */ import util. import cp. main => go. go => time(euler49d). % % 0.034s % euler49 => Diff = 3330, Res := 0, foreach(N in 1001..2..9999, N != 1487, prime(N), C = check_perms(N, Diff), C != []) Res := C end, println(join([R.to_string():R in Res],'')). % % 0.074s % euler49b => Diff = 3330, Res := 0, foreach(N in 1001..2..9999, prime(N)) C = check_perms(N, Diff), if C != [], N != 1487 then Res := C end end, Result = "", foreach(I in Res) Result := Result ++ I.to_string() end, println(Result). % % 0.005s A different (and perhaps simpler) approach % euler49c => Primes = [P : P in primes(9999), P >= 1001, P != 1487], Found = false, foreach(A in Primes, Found == false) Map = new_map(), Perm = permutations(A.to_string), % Which of these permutations are primes? foreach(N in Perm) NN = N.to_int, if NN >= 1001, prime_cache(NN) then Map.put(NN,1) end end, % Require at least 3 permutations if Map.keys.len >= 3 then Sorted = sort(Map.keys), foreach(X in Sorted, X != 1487, Y in Sorted, X < Y, Z in Sorted, Y < Z) if Y - X == 3330, Z - Y == 3330 then Found := [X,Y,Z] end end end end, println([I.to_string : I in Found].join('')), nl. % % Using cp: 0.004s % euler49d => N = 4, L = [A,B,C], L :: 1001..9999, A #!= 1487, A #< B, B #< C, B - A #= 3330, C - B #= 3330, prime_cp(A), prime_cp(B), prime_cp(C), AL = new_list(N), AL :: 0..9, BL = new_list(N), BL :: 0..9, CL = new_list(N), CL :: 0..9, to_num(AL,10,A), to_num(BL,10,B), to_num(CL,10,C), JAB = new_list(N), JAB :: 1..N, all_distinct(JAB), permutation_cp(AL,BL,JAB), JBC = new_list(N), JBC :: 1..N, all_distinct(JBC), permutation_cp(BL,CL,JBC), Vars = L ++ AL ++ BL ++ CL ++ JAB ++ JBC, solve($[ff,split],Vars), Sol = [I.to_string : I in L], println(Sol.join('')), nl. table prime_cache(P) => prime(P). permutation_cp(A,B,Js) => Len = length(A), foreach(I in 1..Len) element(Js[I],B,A[I]) end. prime_cp(N) => N #> 1, foreach (I in [2] ++ 3..2..sqrt(N.fd_max())) N mod I #!= 0 end. to_num(List, Base, Num) => Len = length(List), Num #= sum([List[I]*Base**(Len-I) : I in 1..Len]). check_perms(N, Diff) = LL => LL := [], AllPerms := permutations([I.toint() : I in N.to_string()]), if AllPerms.length > 0 then P1 = 0, P2 = 0, P1 := get_element(N, AllPerms, Diff), if P1 > 0 then P2 := get_element(P1, AllPerms, Diff) end, if P2 > 0 then LL := [N, P1, P2] end end. get_element(N, LL, Diff) = Res => Res := 0, foreach(P in LL) PP = [I.to_string() : I in P].flatten().to_integer(), if PP > N, PP-N == Diff then Res := PP end end. table toint(I) = to_integer(I).