/* Substring primes (Rosetta code) in Picat. http://rosettacode.org/wiki/Substring_primes """ Task Find all primes in which all substrings (in base ten) are also primes. This can be achieved by filtering all primes below 500 (there are 95 of them), but there are better ways. Advanced Solve by testing at most 15 numbers for primality. Show a list of all numbers tested that were not prime. """ This program was created by Hakan Kjellerstrand, hakank@gmail.com See also my Picat page: http://www.hakank.org/picat/ */ main => go. % loop approach % get all substrings of a number subs(N) = findall(S, (append(_Pre,S,_Post,N.to_string), S.len > 0) ). go => Ps = [], foreach(Prime in primes(500)) (foreach(N in subs(Prime)) prime(N.to_int) end -> Ps := Ps ++ [Prime] ; true) end, println(Ps), nl. % Picat does not have have a return statement (it's a logic programming language) % We must use cut (!) to ensure that the test does not continue. This is a "red cut" % which should be avoided if possible... t(N,false) :- not prime(N),!. t(N,true) :- N < 10,!. t(N,false) :- not prime(N mod 100), !. t(N,false) :- not prime(N mod 10),!. t(N,false) :- not prime(N // 10),!. t(N,true) :- N < 100,!. t(N,false) :- not prime(N // 100),!. t(N,false) :- not prime((N mod 100) // 10),!. t(_N,true). go2 => println(findall(N,(member(N,1..500),t(N,Status), Status == true))). % 2 3 5 7 23 37 53 73 373 go3 ?=> % is_substring_prime(731), P = [], foreach(I in 1..500) if is_substring_prime(I) then println(I), P := P ++ [I] end end, println(ps=P), nl. go3 => true. % {{trans|BASIC256}} % Picat doesn't not have have a return statement (it's a logic programming language) is_substring_prime(N) => /* (not prime(N) return False), (N < 10 return True if not prime(N mod 100) then return False if not prime(N mod 10) then return False if not prime(N // 10) then return False if n < 100 then return True if not prime(N // 100) then return False if not prime((N mod 100) // 10) then return False */ println([cond(prime(N),true,false), N < 10, N mod 100, N mod 10, N // 10, N < 100, N // 100, (N mod 100) // 10]), println([cond(not prime(N),true,false), cond(N < 10,true,false), cond(not prime(N mod 100),true,false), cond(not prime(N mod 10),true,false), cond(not prime(N // 10),true,false), cond(N < 100,true,false), cond(not prime(N // 100),true,false), cond(not prime((N mod 100) // 10),true,false)]), % Checks = $[ % [not prime(N), false], % [N < 10, true], % [not prime(N mod 100), false], % [not prime(N mod 10), false], % [not prime(N // 10), false], % [N < 100, true], % [not prime(N // 100), false], % [not prime((N mod 100) // 10),false]], % foreach([Check,Status] in Checks) % println([check=Check,status=Status]), % Cond = cond(Check,true,false), % println(cond=Cond), % Cond == Status, % println(ok) % end, Return = true, if not prime(N) then Return = false end, println(N=check1=Return), if Return, N < 10 then Return = true end, println(N=check2=Return), if Return, not prime(N mod 100) then Return = false end, println(N=check3=Return), if Return, not prime(N mod 10) then Return = false end, println(N=check4=Return), if Return, not prime(N // 10) then Return = false end, println(N=check5=Return), if Return, N < 100 then Return = true end, println(N=check6=Return), if Return, not prime(N // 100) then Return = true end, println(N=check7=Return), if Return,not prime((N mod 100) // 10) then Return = false end, println(N=check8=Return), println(N=ok).