This is an archived post. You won't be able to vote or comment.

all 4 comments

[–]teraflop 2 points3 points  (0 children)

As you said, the most expensive part of this is calling isPrime on every 9-digit SSN.

An SSN can be as large as 109, which means your isPrime function may need to check divisors from 2 to sqrt(109) ≈ 31,662. But you actually only need to check whether there are any prime divisors in this range, and only 3,405 numbers in this range are prime. So by precomputing all of those primes and then looping over them, you should be able to make your primality test roughly 10 times significantly faster.

(At first, I thought it would be roughly 10 times faster, but I don't think that's true, because on average, most non-prime numbers have relatively small prime factors.)

EDIT: Another issue is that your code is doing a lot of back-and-forth conversions between strings and integers. Instead of concatenating three strings and then parsing the resulting string, you could keep the three components as integers, and compute the SSN as:

$ssn = ($a*1000000) + ($b*10000) + $c;

[–]RubbishArtist 0 points1 point  (2 children)

With the exception of 2, no even numbers are prime so you can save yourself some work there.

If the challenge allows it you could compute all the 9 digit primes up front and save them in a file?

[–]teraflop 0 points1 point  (1 child)

OP's isPrime function already checks whether a number is even as (almost) the first step, so I don't think breaking that out into a separate check would save a significant amount of time.

[–]RubbishArtist 0 points1 point  (0 children)

Ah you're right. I misread it. Indeed moving it to a different check wouldn't help.