Project Euler

Problem #58

Starting with 1 and spiralling anticlockwise in the following way, a square spiral with side length 7 is formed.

37 36 35 34 33 32 31
38 17 16 15 14 13 30
39 18  5  4  3 12 29
40 19  6  1  2 11 28
41 20  7  8  9 10 27
42 21 22 23 24 25 26
43 44 45 46 47 48 49

It is interesting to note that the odd squares lie along the bottom right diagonal, but what is more interesting is that 8 out of the 13 numbers lying along both diagonals are prime; that is, a ratio of 8/13 ≈ 62%.

If one complete new layer is wrapped around the spiral above, a square spiral with side length 9 will be formed. If this process is continued, what is the side length of the square spiral for which the ratio of primes along both diagonals first falls below 10%?

Erlang: Running time = 9.78s
+%echo

+%prime_list

p58()->
	p58(3,0,1,prime_list()).
p58(Side,Primes,Total,PL)->
	[A,B,C]=lists:map(fun(X)->Side*Side-(Side-1)*X end,[1,2,3]),
	PL ! {is_prime,A,self()},
	PL ! {is_prime,B,self()},
	PL ! {is_prime,C,self()},
	P=lists:sum(lists:map(fun(_)->receive {is_prime,_,true}->1;{is_prime,_,false}->0 end end,[a,a,a])),
	NPrimes=Primes+P,
	NTotal=Total+4,
	if
		NPrimes/NTotal < 0.1 -> io:format("~w~n",[Side]);
		true->p58(Side+2,NPrimes,NTotal,PL)
	end.

Ruby: Running time = 42.71s
+#PrimeList

def get_layer(n)
  b=n*n
  m=n-1
  [b-m,b-2*m,b-3*m]
end

def p58
  tot=5.0
  count=3.0
  i=3
  while(count/tot >= 0.1)
    i+=2
    tot+=4
    count+=get_layer(i).select{|j|PrimeList.isPrime? j}.length
  end
  puts i
end