Building Primes
December 21, 2012
We begin with a function extend
that given a number and a power of ten forms all possible primes that are one digit larger than the starting number:
(define (extend n 10^k)
(filter prime?
(map (lambda (x)
(+ n (* x 10^k)))
(range 1 10))))
Then it is easy to solve the problem; keep a list of all possibilities, extending each until you reach a composite, stopping when it is not possible to extend the number further:
> (let loop ((xs (extend 0 1)) (tens 10))
(let ((next (mappend (lambda (x) (extend x tens)) xs)))
(if (null? next)
(apply max xs)
(loop next (* tens 10)))))
357686312646216567629137
We used range
and mappend
from the Standard Prelude and prime?
from any of several previous exercises. You can see the program at http://programmingpraxis.codepad.org/zP1VxyfU.
[…] Pages: 1 2 […]
A Python version.
[…] Question is from Programmingpraxis: […]
My java solution here
Here’s a J version:
Running this gives 99918918997653315499663.
Johann: Your solution is incorrect. Starting from the right, 3 is prime, but 63 is not, so your number is not prime at every step.
Paul: Your program has an extraneous P. on line 5. After removing that and adding an is_prime function, I ran it, and it produced the correct answer. However, your starting point is wrong. You should use 2, 3, 5, 7 for starters instead of 1, 3, 5, 7, 9 because two of the starters are non-prime, and the task requires that all intermediate numbers must be prime.
OK, I was lucky, as the chains for 1 and 9 give results, that are smalller than the result for 7. I omitted 2, because it is clear form the start, that all the next values will be non prime.
You’re right. I dropped out of extended precision for the last step. Line 1 should have been
“10^x” was returning a double, rather than an extended precision integer. Moving the “x:” in front of it forces it to be extended-precision. I’m still a little fuzzy on J’s extended precision rules.
Also, the last (run) line should have been:
That’s just a transcription error.
In any case, my new answer is 96686312646216567629137.
I can confirm that it’s right via:
Your answer now correctly builds primes. But your final answer 96686312646216567629137 is smaller than the one given in the suggested solution. The final 21 digits are the same, but your prefix of 96 is shorter than the correct prefix of 357.
An improved Python version. This version starts correctly from 2,3,5 and 7
My very first attempt to write something in Haskell. It works, but I still feel very uneasy.
Here’s my take in Racket:
– Nested primes
The basic algorithm is essentially the same as others here, although there is start to code that will eventually graph all of the different branches of primes. I’m curious if there’s any sort of structure to it.
Speaking of which, is anyone aware of either a quicker method for generating these branches or a reason why they terminate?
Hello.I am practically a newbie in programming.I hope C/C++ code is also ok. I am a bit confused about the suggested solution as it does follow the example given in the exercise, but as far as my understanding goes that is not also the way to get the biggest prime number. i mean from 7 u can get 97, continuing with 797 and so on(as i got in my alghorithm).
Here is my solution: http://codepad.org/b82CoYZR . As i said, im a begginer and im only looking to improve my skills so this code may not be the most elegant or best performance. I also doubt is correct, given your suggested solution, but i cant seem to get my mistake so am I curious about how i did. Looking forward to a reply. Thank you and i beg a pardon if my C code is not ?valid? here.
Haskell. I’m not sure how closely I followed your method, but it seems to work so far. The laptop I’m using is rather decrepit so I shall have to wait a while to see if I get the correct solution.
import Control.Monad (guard)
import Data.Numbers.Primes (isPrime)
largestBuildable :: Integral a => a
largestBuildable = largest [2, 3, 5, 7]
where largest xs
| null xs’ = maximum xs
| otherwise = largest xs’
where xs’ = getBuildableGen xs
getBuildableGen :: Integral a => [a] -> [a]
getBuildableGen xs = do
x <- xs
y a -> a -> a
addFront a b = b * 10 ^ ceiling ((log (fromIntegral a))/(log 10)) + a
In Ruby…
This version gives the right answer. It seems like I had to use extended precision in the “10^x” expression. In retrospect, that makes sense, but it leaves me unsatisfied with J’s handling of big numbers.
[…] Question is from Programmingpraxis: […]
[…] The task: […]