Menu

  • Home
  • Archives
  • Tags
  • RSS
February 14, 2015

euler 27 quadratic primes

Statutory Warning: Spoilers ahead

This turned out to be really simple, though I went through a phase of churning out complicated solutions because of a stupid mistake.

I didn't preserve intermediate versions, so here is the final solution:


import qualified Data.List as L

import qualified Data.Vector as V

import qualified Data.Function as F



sieve :: Int -> [Int] -> [Int]

sieve num list =

  if null list

  then [num]

  else let rest = filter (\x -> x `mod` num > 0) list

       in

        num : sieve (head rest) (tail rest)



eratosthenes :: Int -> [Int]

eratosthenes maxNum = sieve 2 [3 .. maxNum]



allPrimes :: Int -> V.Vector Int

allPrimes maxNum = V.fromList $ eratosthenes maxNum



eulerEqn :: Int -> Int -> Int -> Int

eulerEqn a b n = n * n + a * n + b



-- TODO(agam): replace with the "standard" way to do binary search

binSearch :: V.Vector Int -> Int -> Int -> Int -> Bool

binSearch arr min max elem =

  let low = arr V.! min

      high = arr V.! max

  in

   if max - min < 2

   then if low == elem

        then True

        else False

   else let mid = div (min + max) 2

            midElem = arr V.! mid

        in

         if midElem > elem

         then binSearch arr min mid elem

         else binSearch arr mid max elem



consecutivePrimes a b primes start length =

  let p = eulerEqn a b start

      l = V.length primes

      isPrime = binSearch primes 0 l p

  in

   if isPrime

   then consecutivePrimes a b primes (start + 1) (length + 1)

   else length



numPrimes a b primes = consecutivePrimes a b primes 0 0



euler27 maxNum =

  let ap = allPrimes maxNum

      primeLengths = [(a * b, numPrimes a b ap) | a <- [-1000 .. 1000], b <- [-1000 .. 1000]]

  in

   L.maximumBy (F.on compare snd) primeLengths

When I ran this (i.e. euler27 1000) I got the correct answer the first time! But I didn't see it. Instead, I entered the second value of the tuple, which is not the one asked for, and it was therefore obviously wrong. So I thought "hmm, we're looking at some large repeating sequence among really large primes", and tried euler27 100000 and euler27 10000000, with no luck.

The last one kept running for hours and I killed it, and then came up with the idea of "vectorizing everything" – which was perhaps a good academic exercise but did absolutely nothing for the performance here.

So I forgot about it for a while, then came back and ran euler27 1000, entered the first value of the tuple, and that was the end of this story.


Tags: old-post

« euler 28 spiral diagonals euler 26 reciprocal cycles »

Copyright © 2020 Agam Brahma

Powered by Cryogen