From f10605a4c97982721e9c0af124b7090d415b10f0 Mon Sep 17 00:00:00 2001 From: Vishal Pankaj Chandratreya <19171016+tfpf@users.noreply.github.com> Date: Mon, 25 Mar 2024 16:01:19 +0530 Subject: [PATCH] Optimised solution. Runs in 100 ms. --- src/solutions/counting_fractions.rs | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/src/solutions/counting_fractions.rs b/src/solutions/counting_fractions.rs index baa8a90..c29f2cd 100644 --- a/src/solutions/counting_fractions.rs +++ b/src/solutions/counting_fractions.rs @@ -1,4 +1,24 @@ pub fn solve() -> i64 { - assert_eq!(303963552391i64, 303963552391); - 303963552391 + // Calculate Euler's totient of every number up to the limit. + let mut totients = (0..=1000000).collect::>(); + for num in 2..totients.len() { + if totients[num] == num as i64 { + // This number is prime. The totient of each of its multiples will + // contain the term + // 1/(1 - num) + // in its product expression. Instead of multiply-assigning that + // term, we use an equivalent subtract-assign. + for multiple in (num..totients.len()).step_by(num) { + totients[multiple] -= totients[multiple] / num as i64; + } + } + } + + // The number of reduced fractions with a particular denominator is the + // totient of the denominator. Hence, the total number of fractions is the + // sum. + let result = totients[2..].iter().sum(); + + assert_eq!(result, 303963552391); + result }