Project Euler Problem 37
Truncatable primes
The number 3797 has an interesting property. Being prime itself, it is possible to continuously remove digits from left to right, and remain prime at each stage: 3797, 797, 97, and 7. Similarly we can work from right to left: 3797, 379, 37, and 3.
Find the sum of the only eleven primes that are both truncatable from left to right and right to left.
NOTE: 2, 3, 5, and 7 are not considered to be truncatable primes.
Link to original description
Source code examples on Github
Erlang version
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 | #!/usr/bin/env escript %% -*- erlang -*- %%! -smp enable -sname p37 % vim:syn=erlang -mode(compile). main(_) -> Answer = lists:sum(lists:sublist([P||P<-prime(1000000), P > 7, trunc_left_Prime( integer_to_list(P)), trunc_right_Prime(integer_to_list(P))],1,11)), io:format("Answer ~p ~n", [ Answer ]). trunc_left_Prime([_|T]) when length(T) > 1 -> case is_prime(list_to_integer(T)) of true -> trunc_left_Prime(T); false -> false end; trunc_left_Prime([_|H]) -> is_prime(list_to_integer(H)). trunc_right_Prime(H) when length(H) > 1 -> {T,_} = lists:split(length(H)-1,H), case is_prime(list_to_integer(T)) of true -> trunc_right_Prime(T); false -> false end; trunc_right_Prime(H) -> is_prime(list_to_integer(H)). %------------------------------------- prime library from problem 10------------ is_prime(X) -> case ets:lookup(prim, X) of [] -> false ;_ -> true end. prime(N) -> ets:new(comp, [public, named_table, {write_concurrency, true} ]), ets:new(prim, [public, named_table, {write_concurrency, true}]), composite_mc(N), primes_mc(N), lists:sort([X||{X,_}<- ets:tab2list(prim)]). primes_mc(N) -> case erlang:system_info(schedulers) of 1 -> primes(N); C -> launch_primes(lists:seq(1,C), C, N, N div C) end. launch_primes([1|T], C, N, R) -> P = self(), spawn(fun()-> primes(2,R), P ! {ok, prm} end), launch_primes(T, C, N, R); launch_primes([H|[]], C, N, R)-> P = self(), spawn(fun()-> primes(R*(H-1)+1,N), P ! {ok, prm} end), wait_primes(C); launch_primes([H|T], C, N, R) -> P = self(), spawn(fun()-> primes(R*(H-1)+1,R*H), P ! {ok, prm} end), launch_primes(T, C, N, R). wait_primes(0) -> ok; wait_primes(C) -> receive {ok, prm} -> wait_primes(C-1) after 1000 -> wait_primes(C) end. primes(N) -> primes(2, N). primes(I,N) when I =< N -> case ets:lookup(comp, I) of [] -> ets:insert(prim, {I,1}) ;_ -> ok end, primes(I+1, N); primes(I,N) when I > N -> ok. composite_mc(N) -> composite_mc(N,2,round(math:sqrt(N)),erlang:system_info(schedulers)). composite_mc(N,I,M,C) when I =< M, C > 0 -> C1 = case ets:lookup(comp, I) of [] -> comp_i_mc(I*I, I, N), C-1 ;_ -> C end, composite_mc(N,I+1,M,C1); composite_mc(_,I,M,_) when I > M -> ok; composite_mc(N,I,M,0) -> receive {ok, cim} -> composite_mc(N,I,M,1) after 1000 -> composite_mc(N,I,M,0) end. comp_i_mc(J, I, N) -> Parent = self(), spawn(fun() -> comp_i(J, I, N), Parent ! {ok, cim} end). comp_i(J, I, N) when J =< N -> ets:insert(comp, {J, 1}), comp_i(J+I, I, N); comp_i(J, _, N) when J > N -> ok. |
Python version
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 | #!/usr/bin/python import math, prime def is_left_truncatable(i): while True: if prime.isprime(i): if i > 10: i = int(''.join(list(str(i))[1::])) else: return True else: return False def is_right_truncatable(i): while True: if prime.isprime(i): if i > 10: a = list(str(i)) a.pop() i = int(''.join(a)) else: return True else: return False def p37(): start,answer,count = 1,0,0 while True: for i,v in enumerate(prime.prime_list[start+1::], start=start+1): if v > 7 and is_left_truncatable(v) and is_right_truncatable(v): answer += v count += 1 if count == 11: return answer start = i prime._refresh(v*2) print "Answer %s" % p37() |