Project Euler – Problem 46 Solution

Problem

It was proposed by Christian Goldbach that every odd composite number can be written as the sum of a prime and twice a square.

9 = 7 + 2×12

15 = 7 + 2×22

21 = 3 + 2×32

25 = 7 + 2×32

27 = 19 + 2×22

33 = 31 + 2×12

It turns out that the conjecture was false.

What is the smallest odd composite that cannot be written as the sum of a prime and twice a square?

Solution

let hasDivisor(n) =
    let upperBound = int64(sqrt(double(n)))
    [2L..upperBound] |> Seq.exists (fun x -> n % x = 0L)

// need to consider negative values
let isPrime(n) = if n <= 1L then false else not(hasDivisor(n))

// generate the sequence of odd composite numbers
let oddCompositeNumbers = 
    Seq.unfold (fun state -> Some(state, state+2L)) 9L 
    |> Seq.filter (fun n -> not(isPrime n))

// generate the sequence of prime numbers
let primeNumbers = Seq.unfold (fun state -> Some(state, state+2L)) 1L |> Seq.filter isPrime

// function to check if a number can be written as the sum of a prime and twice a square
let isSum(number) =
    primeNumbers
    |> Seq.takeWhile (fun n -> n < number)
    |> Seq.exists (fun n -> sqrt(double((number-n)/2L)) % 1.0 = 0.0)

let answer = oddCompositeNumbers |> Seq.filter (fun n -> not(isSum(n))) |> Seq.head

All pretty straight forward here, the only slightly confusing part of this solution is how to determine if a number can be written as the sum of a prime and twice a square:

Odd Composite Number = Prime + 2 x n2 => n = sqrt((Odd Composite Number – Prime) / 2)

As you know Math.Sqrt works with a double and returns a double, hence to find out if n above is a whole number I had to check whether it divides by 1 evenly