Project Euler – Problem 72 Solution

Yan Cui

I help clients go faster for less using serverless technologies.

Problem

Consider the fraction, n/d, where n and d are positive integers. If n<d and HCF(n,d)=1, it is called a reduced proper fraction.

If we list the set of reduced proper fractions for d <= 8 in ascending order of size, we get:

1/8, 1/7, 1/6, 1/5, 1/4, 2/7, 1/3, 3/8, 2/5, 3/7, 1/2, 4/7, 3/5, 5/8, 2/3, 5/7, 3/4, 4/5, 5/6, 6/7, 7/8

It can be seen that there are 21 elements in this set.

How many elements would be contained in the set of reduced proper fractions for d <= 1,000,000?

Solution

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

let isPrime(n) = if n = 1I then false else not(hasDivisor(n))

// define the sequence of prime numbers
let primeSeq =
    Seq.unfold (fun state -> if state >= 3I then Some(state, state+2I) else Some(state, state+1I)) 1I
    |> Seq.filter isPrime |> Seq.cache

// define function to find the prime denominators for a number n
let getPrimeFactors n =
    let rec getPrimeFactorsRec denominators n =
        if n = 1I then denominators
        else
            let denominator = primeSeq |> Seq.filter (fun x -> n % x = 0I) |> Seq.head
            getPrimeFactorsRec (denominators @ [denominator]) (n/denominator)
    getPrimeFactorsRec [] n

let totient n =
    let primeFactors = getPrimeFactors n |> Seq.distinct
    n * (primeFactors |> Seq.map (fun n' -> n'-1I) |> Seq.reduce (*)) / (primeFactors |> Seq.reduce (*))

let f n = [2I..n] |> List.map totient |> List.sum
let answer = f 1000000I

This is almost identical to the solution to problem 69, with the exception of the last two steps. According to the information on Farey sequence on wikipedia:

The Farey sequence of order n contains all of the members of the Farey sequences of lower orders. In particular Fn contains all of the members of Fn?1, and also contains an additional fraction for each number that is less than n and coprime to n. Thus F6 consists of F5 together with the fractions 1?6 and 5?6. The middle term of a Farey sequence Fn is always 1?2, for n > 1.

From this, we can relate the lengths of Fn and Fn?1 using Euler’s totient function ?(n) :

image

Given that F1 = 0 in our case, F2 = 0 + totient 2, F3 = totient 2 + totient 3, and so on, and therefore Fn = totient 2 + totient 3 + … totient n.


 

Whenever you’re ready, here are 4 ways I can help you:

  1. If you want a one-stop shop to help you quickly level up your serverless skills, you should check out my Production-Ready Serverless workshop. Over 20 AWS Heroes & Community Builders have passed through this workshop, plus 1000+ students from the likes of AWS, LEGO, Booking, HBO and Siemens.
  2. If you want to learn how to test serverless applications without all the pain and hassle, you should check out my latest course, Testing Serverless Architectures.
  3. If you’re a manager or founder and want to help your team move faster and build better software, then check out my consulting services.
  4. If you just want to hang out, talk serverless, or ask for help, then you should join my FREE Community.

 


Leave a Comment

Your email address will not be published. Required fields are marked *