From 264a0c093f0745fb4aba1cd7f17ea60a3300a59d Mon Sep 17 00:00:00 2001 From: newt Date: Wed, 9 Oct 2024 18:10:10 +0100 Subject: [PATCH] feat(problem): 14 - longest collatz sequence --- readme.md | 4 +-- src/bin/1.rs | 28 +++++++++--------- src/bin/10.rs | 30 +++++++++---------- src/bin/11.rs | 80 ++++++++++++++++++++++++++++++++++++++------------- src/bin/12.rs | 2 +- src/bin/13.rs | 6 ++-- src/bin/14.rs | 54 ++++++++++++++++++++++++++++++++++ src/bin/2.rs | 27 +++++++++-------- src/bin/3.rs | 40 +++++++++++++------------- src/bin/4.rs | 38 ++++++++++++------------ src/bin/5.rs | 58 ++++++++++++++++++------------------- src/bin/6.rs | 32 ++++++++++----------- src/bin/7.rs | 56 ++++++++++++++++++------------------ src/bin/8.rs | 62 +++++++++++++++++++-------------------- src/bin/9.rs | 4 +-- src/main.rs | 77 ++++++++++++++++++++++++++++--------------------- 16 files changed, 355 insertions(+), 243 deletions(-) create mode 100644 src/bin/14.rs diff --git a/readme.md b/readme.md index 2cc8962..ff7a266 100644 --- a/readme.md +++ b/readme.md @@ -9,7 +9,7 @@ All of the solutions here are written in rust. [main.rs](src/main.rs) is the hom ## Challenge Completion -### 13 out of 100 public challenges completed. +### 14 out of 100 public challenges completed. - [x] 1 - [Multiples of 3 or 5](src/bin/1.rs) - [x] 2 - [Even Fibonacci numbers](src/bin/2.rs) @@ -24,7 +24,7 @@ All of the solutions here are written in rust. [main.rs](src/main.rs) is the hom - [x] 11 - [Largest product in a grid](src/bin/11.rs) - [x] 12 - [Highly divisible triangular number](src/bin/12.rs) - [x] 13 - [Large sum](src/bin/13.rs) -- [ ] 14 - Longest Collatz sequence +- [x] 14 - [Longest Collatz sequence](src/bin/14.rs) - [ ] 15 - Lattice paths - [ ] 16 - Power digit sum - [ ] 17 - Number letter counts diff --git a/src/bin/1.rs b/src/bin/1.rs index 8ac4e9f..d16c02e 100644 --- a/src/bin/1.rs +++ b/src/bin/1.rs @@ -8,24 +8,24 @@ Find the sum of all the multiples of 3 or 5 below 1000. use std::collections::HashSet; fn multiples_of(multipliers: &Vec, upper_bound: usize) -> HashSet { - let mut results: HashSet = HashSet::new(); + let mut results: HashSet = HashSet::new(); - // Find all of the numbers between 1 and the upper bound that are multiples of one of the numbers - // in the multipliers vec - for i in 1..upper_bound { - for number in multipliers { - if i % number == 0 { - results.insert(i); - } - } - } + // Find all of the numbers between 1 and the upper bound that are multiples of one of the numbers + // in the multipliers vec + for i in 1..upper_bound { + for number in multipliers { + if i % number == 0 { + results.insert(i); + } + } + } - return results; + return results; } fn main() { - let multiples = multiples_of(&vec![3, 5], 1000); - let sum: usize = multiples.iter().sum(); + let multiples = multiples_of(&vec![3, 5], 1000); + let sum: usize = multiples.iter().sum(); - println!("The sum of the multiples of 3 and 5 up until 1000 is {sum}"); + println!("The sum of the multiples of 3 and 5 up until 1000 is {sum}"); } diff --git a/src/bin/10.rs b/src/bin/10.rs index 7178d0c..9cdc429 100644 --- a/src/bin/10.rs +++ b/src/bin/10.rs @@ -8,26 +8,26 @@ Find the sum of all the primes below two million. // Implementation of the Sieve of Eratosthenes // https://en.wikipedia.org/wiki/Sieve_of_Eratosthenes fn find_primes(upper_bound: usize) -> Vec { - let mut mask = vec![true; upper_bound]; - let mut primes: Vec = vec![]; + let mut mask = vec![true; upper_bound]; + let mut primes: Vec = vec![]; - mask[0] = false; - mask[1] = false; + mask[0] = false; + mask[1] = false; - for i in 2..upper_bound { - if mask[i] { - primes.push(i); + for i in 2..upper_bound { + if mask[i] { + primes.push(i); - let mut j = 2 * i; + let mut j = 2 * i; - while j < upper_bound { - mask[j] = false; - j += i; - } - } - } + while j < upper_bound { + mask[j] = false; + j += i; + } + } + } - return primes; + return primes; } fn sum_of_primes(upper_bound: usize) -> usize { diff --git a/src/bin/11.rs b/src/bin/11.rs index dd89d9d..eb76643 100644 --- a/src/bin/11.rs +++ b/src/bin/11.rs @@ -80,26 +80,66 @@ fn largest_grid_product(grid: Vec>, adjacent_digits: usize) -> usize fn main() { let grid: Vec> = vec![ - vec![8, 2, 22, 97, 38, 15, 0, 40, 0, 75, 4, 5, 7, 78, 52, 12, 50, 77, 91, 8], - vec![49, 49, 99, 40, 17, 81, 18, 57, 60, 87, 17, 40, 98, 43, 69, 48, 4, 56, 62, 0], - vec![81, 49, 31, 73, 55, 79, 14, 29, 93, 71, 40, 67, 53, 88, 30, 3, 49, 13, 36, 65], - vec![52, 70, 95, 23, 4, 60, 11, 42, 69, 24, 68, 56, 1, 32, 56, 71, 37, 2, 36, 91], - vec![22, 31, 16, 71, 51, 67, 63, 89, 41, 92, 36, 54, 22, 40, 40, 28, 66, 33, 13, 80], - vec![24, 47, 32, 60, 99, 3, 45, 2, 44, 75, 33, 53, 78, 36, 84, 20, 35, 17, 12, 50], - vec![32, 98, 81, 28, 64, 23, 67, 10, 26, 38, 40, 67, 59, 54, 70, 66, 18, 38, 64, 70], - vec![67, 26, 20, 68, 2, 62, 12, 20, 95, 63, 94, 39, 63, 8, 40, 91, 66, 49, 94, 21], - vec![24, 55, 58, 5, 66, 73, 99, 26, 97, 17, 78, 78, 96, 83, 14, 88, 34, 89, 63, 72], - vec![21, 36, 23, 9, 75, 0, 76, 44, 20, 45, 35, 14, 0, 61, 33, 97, 34, 31, 33, 95], - vec![78, 17, 53, 28, 22, 75, 31, 67, 15, 94, 3, 80, 4, 62, 16, 14, 9, 53, 56, 92], - vec![16, 39, 5, 42, 96, 35, 31, 47, 55, 58, 88, 24, 0, 17, 54, 24, 36, 29, 85, 57], - vec![86, 56, 0, 48, 35, 71, 89, 7, 5, 44, 44, 37, 44, 60, 21, 58, 51, 54, 17, 58], - vec![19, 80, 81, 68, 5, 94, 47, 69, 28, 73, 92, 13, 86, 52, 17, 77, 4, 89, 55, 40], - vec![4, 52, 8, 83, 97, 35, 99, 16, 7, 97, 57, 32, 16, 26, 26, 79, 33, 27, 98, 66], - vec![88, 36, 68, 87, 57, 62, 20, 72, 3, 46, 33, 67, 46, 55, 12, 32, 63, 93, 53, 69], - vec![4, 42, 16, 73, 38, 25, 39, 11, 24, 94, 72, 18, 8, 46, 29, 32, 40, 62, 76, 36], - vec![20, 69, 36, 41, 72, 30, 23, 88, 34, 62, 99, 69, 82, 67, 59, 85, 74, 4, 36, 16], - vec![20, 73, 35, 29, 78, 31, 90, 1, 74, 31, 49, 71, 48, 86, 81, 16, 23, 57, 5, 54], - vec![1, 70, 54, 71, 83, 51, 54, 69, 16, 92, 33, 48, 61, 43, 52, 1, 89, 19, 67, 48] + vec![ + 8, 2, 22, 97, 38, 15, 0, 40, 0, 75, 4, 5, 7, 78, 52, 12, 50, 77, 91, 8, + ], + vec![ + 49, 49, 99, 40, 17, 81, 18, 57, 60, 87, 17, 40, 98, 43, 69, 48, 4, 56, 62, 0, + ], + vec![ + 81, 49, 31, 73, 55, 79, 14, 29, 93, 71, 40, 67, 53, 88, 30, 3, 49, 13, 36, 65, + ], + vec![ + 52, 70, 95, 23, 4, 60, 11, 42, 69, 24, 68, 56, 1, 32, 56, 71, 37, 2, 36, 91, + ], + vec![ + 22, 31, 16, 71, 51, 67, 63, 89, 41, 92, 36, 54, 22, 40, 40, 28, 66, 33, 13, 80, + ], + vec![ + 24, 47, 32, 60, 99, 3, 45, 2, 44, 75, 33, 53, 78, 36, 84, 20, 35, 17, 12, 50, + ], + vec![ + 32, 98, 81, 28, 64, 23, 67, 10, 26, 38, 40, 67, 59, 54, 70, 66, 18, 38, 64, 70, + ], + vec![ + 67, 26, 20, 68, 2, 62, 12, 20, 95, 63, 94, 39, 63, 8, 40, 91, 66, 49, 94, 21, + ], + vec![ + 24, 55, 58, 5, 66, 73, 99, 26, 97, 17, 78, 78, 96, 83, 14, 88, 34, 89, 63, 72, + ], + vec![ + 21, 36, 23, 9, 75, 0, 76, 44, 20, 45, 35, 14, 0, 61, 33, 97, 34, 31, 33, 95, + ], + vec![ + 78, 17, 53, 28, 22, 75, 31, 67, 15, 94, 3, 80, 4, 62, 16, 14, 9, 53, 56, 92, + ], + vec![ + 16, 39, 5, 42, 96, 35, 31, 47, 55, 58, 88, 24, 0, 17, 54, 24, 36, 29, 85, 57, + ], + vec![ + 86, 56, 0, 48, 35, 71, 89, 7, 5, 44, 44, 37, 44, 60, 21, 58, 51, 54, 17, 58, + ], + vec![ + 19, 80, 81, 68, 5, 94, 47, 69, 28, 73, 92, 13, 86, 52, 17, 77, 4, 89, 55, 40, + ], + vec![ + 4, 52, 8, 83, 97, 35, 99, 16, 7, 97, 57, 32, 16, 26, 26, 79, 33, 27, 98, 66, + ], + vec![ + 88, 36, 68, 87, 57, 62, 20, 72, 3, 46, 33, 67, 46, 55, 12, 32, 63, 93, 53, 69, + ], + vec![ + 4, 42, 16, 73, 38, 25, 39, 11, 24, 94, 72, 18, 8, 46, 29, 32, 40, 62, 76, 36, + ], + vec![ + 20, 69, 36, 41, 72, 30, 23, 88, 34, 62, 99, 69, 82, 67, 59, 85, 74, 4, 36, 16, + ], + vec![ + 20, 73, 35, 29, 78, 31, 90, 1, 74, 31, 49, 71, 48, 86, 81, 16, 23, 57, 5, 54, + ], + vec![ + 1, 70, 54, 71, 83, 51, 54, 69, 16, 92, 33, 48, 61, 43, 52, 1, 89, 19, 67, 48, + ], ]; let value = largest_grid_product(grid, 4); diff --git a/src/bin/12.rs b/src/bin/12.rs index bf5ab46..2e98c72 100644 --- a/src/bin/12.rs +++ b/src/bin/12.rs @@ -14,7 +14,7 @@ fn factors(number: usize) -> Vec> { let mut factors: Vec> = vec![vec![1, number]]; let is_even = number % 2 == 0; - for current_factor in (if is_even {2} else {3})..(max + 1) { + for current_factor in (if is_even { 2 } else { 3 })..(max + 1) { if number % current_factor != 0 { continue; } diff --git a/src/bin/13.rs b/src/bin/13.rs index 169d6a9..cc6de1d 100644 --- a/src/bin/13.rs +++ b/src/bin/13.rs @@ -204,7 +204,7 @@ const NUMBERS: [f64; 100] = [ 77158542502016545090413245809786882778948721859617.0, 72107838435069186155435662884062257473692284509516.0, 20849603980134001723930671666823555245252804609722.0, - 53503534226472524250874054075591789781264330331690.0 + 53503534226472524250874054075591789781264330331690.0, ]; fn first_n_digits(number: f64, n: usize) -> Option { @@ -214,7 +214,9 @@ fn first_n_digits(number: f64, n: usize) -> Option { return None; } - let new_number = String::from_iter(string_number.chars().collect::>()[0..n].iter()).parse::().unwrap(); + let new_number = String::from_iter(string_number.chars().collect::>()[0..n].iter()) + .parse::() + .unwrap(); return Some(new_number); } diff --git a/src/bin/14.rs b/src/bin/14.rs new file mode 100644 index 0000000..9ca9f47 --- /dev/null +++ b/src/bin/14.rs @@ -0,0 +1,54 @@ +/* +Problem 14 - Longest Collatz sequence + +The following iterative sequence is defined for the set of positive integers: +n → n /2 ( n is even) n → 3 n + 1 ( n is odd) +Using the rule above and starting with 13, we generate the following sequence: +13 → 40 → 20 → 10 → 5 → 16 → 8 → 4 → 2 → 1 +It can be seen that this sequence (starting at 13 and finishing at 1) contains 10 terms. Although it has not been proved yet (Collatz Problem), it is thought that all starting numbers finish at 1. +Which starting number, under one million, produces the longest chain? +NOTE: Once the chain starts the terms are allowed to go above one million. +*/ + +use std::collections::HashMap; + +fn f(n: usize) -> usize { + if n % 2 == 0 { + return n / 2; + } else { + return ((3 * n) + 1) / 2; + } +} + +fn longest_collatz_sequence(greatest_start: usize) -> usize { + let mut sequence_lengths: HashMap = HashMap::new(); + + for i in 1..(greatest_start + 1) { + let mut sequence_length: usize = 0; + let mut current_number = i; + + while current_number > 1 { + current_number = f(current_number); + + // Eventually the sequence will break down into one we have already computed the length for! + if sequence_lengths.contains_key(¤t_number) { + sequence_length += *sequence_lengths.get(¤t_number).unwrap(); + break; + } + + sequence_length += 1; + } + + sequence_lengths.insert(i, sequence_length); + } + + return *sequence_lengths.iter().max_by_key(|x| x.1).unwrap().0; +} + +fn main() { + let starting_number = longest_collatz_sequence(1_000_000); + + println!( + "The starting number which produces the longest collatz sequence is {starting_number}" + ); +} diff --git a/src/bin/2.rs b/src/bin/2.rs index 26d4cdb..98ffc7b 100644 --- a/src/bin/2.rs +++ b/src/bin/2.rs @@ -7,22 +7,25 @@ By considering the terms in the Fibonacci sequence whose values do not exceed fo */ fn fibonacci(upper_bound: usize) -> Vec { - // F_0 = 1, F_1 = 2 - let mut sequence = vec![1, 2]; + // F_0 = 1, F_1 = 2 + let mut sequence = vec![1, 2]; - // F_n = F_(n - 1) + F_(n - 2) - while sequence[sequence.len() - 1] < upper_bound { - let new_value = sequence[sequence.len() - 1] + sequence[sequence.len() - 2]; - sequence.push(new_value); - } + // F_n = F_(n - 1) + F_(n - 2) + while sequence[sequence.len() - 1] < upper_bound { + let new_value = sequence[sequence.len() - 1] + sequence[sequence.len() - 2]; + sequence.push(new_value); + } - return sequence; + return sequence; } fn main() { - let sequence = fibonacci(4000000); - let even = sequence.iter().filter(|n| *n % 2 == 0); - let sum: usize = even.sum(); + let sequence = fibonacci(4000000); + let even = sequence.iter().filter(|n| *n % 2 == 0); + let sum: usize = even.sum(); - print!("The sum of the first 4000000 even fibonacci numbers is {}", sum); + print!( + "The sum of the first 4000000 even fibonacci numbers is {}", + sum + ); } diff --git a/src/bin/3.rs b/src/bin/3.rs index 6da2da6..6deed70 100644 --- a/src/bin/3.rs +++ b/src/bin/3.rs @@ -6,30 +6,30 @@ What is the largest prime factor of the number 600851475143 ? */ fn largest_prime_factor(number: usize) -> usize { - // All even numbers can be divided by 2 - if number % 2 == 0 { - return 2; - } + // All even numbers can be divided by 2 + if number % 2 == 0 { + return 2; + } - let mut i = 3; - let mut num = number.clone(); - let mut primes: Vec = vec![]; + let mut i = 3; + let mut num = number.clone(); + let mut primes: Vec = vec![]; - while num != 1 { - if num % i == 0 { - num /= i; - primes.push(i); - } else { - // Test next odd number - i += 2; - } - } + while num != 1 { + if num % i == 0 { + num /= i; + primes.push(i); + } else { + // Test next odd number + i += 2; + } + } - // The largest prime factor will be at the end of the vec - return primes[primes.len() - 1]; + // The largest prime factor will be at the end of the vec + return primes[primes.len() - 1]; } fn main() { - let factor = largest_prime_factor(600851475143); - println!("The largest prime factor of 600851475143 is {factor}"); + let factor = largest_prime_factor(600851475143); + println!("The largest prime factor of 600851475143 is {factor}"); } diff --git a/src/bin/4.rs b/src/bin/4.rs index bca51e7..c83aab6 100644 --- a/src/bin/4.rs +++ b/src/bin/4.rs @@ -6,29 +6,29 @@ Find the largest palindrome made from the product of two 3-digit numbers. */ fn largest_pallindromic_number(lower_bound: usize, upper_bound: usize) -> usize { - let mut products: Vec = vec![]; - - for i in lower_bound..(upper_bound + 1) { - for j in lower_bound..(upper_bound + 1) { - products.push(i * j); - } - } + let mut products: Vec = vec![]; - // Filter for pallindromic numbers - let mut pallindromic = products - .iter() - .filter(|x| x.to_string() == x.to_string().chars().rev().collect::()) - .collect::>(); + for i in lower_bound..(upper_bound + 1) { + for j in lower_bound..(upper_bound + 1) { + products.push(i * j); + } + } - // Return the largest value - pallindromic.sort(); - pallindromic.reverse(); + // Filter for pallindromic numbers + let mut pallindromic = products + .iter() + .filter(|x| x.to_string() == x.to_string().chars().rev().collect::()) + .collect::>(); - return *pallindromic[0]; + // Return the largest value + pallindromic.sort(); + pallindromic.reverse(); + + return *pallindromic[0]; } fn main() { - let number = largest_pallindromic_number(100, 999); - - println!("The largest pallindromic number made from the product of two three-digit numbers is {number}"); + let number = largest_pallindromic_number(100, 999); + + println!("The largest pallindromic number made from the product of two three-digit numbers is {number}"); } diff --git a/src/bin/5.rs b/src/bin/5.rs index ac24dd6..a4b8ae1 100644 --- a/src/bin/5.rs +++ b/src/bin/5.rs @@ -7,46 +7,46 @@ What is the smallest positive number that is evenly divisible by all of the nu // Euclidean algorithm for finding GCD fn gcd(a: usize, b: usize) -> usize { - let mut x = a; - let mut y = b; - let mut r: usize = 1; // temporary initial value + let mut x = a; + let mut y = b; + let mut r: usize = 1; // temporary initial value - while r != 0 { - if x < y { - let temp = x; - x = y; - y = temp; - } + while r != 0 { + if x < y { + let temp = x; + x = y; + y = temp; + } - r = x % y; + r = x % y; - if r == 0 { - break; - } else { - x = y; - y = r; - } - } + if r == 0 { + break; + } else { + x = y; + y = r; + } + } - return y; + return y; } -fn first_value_divisible_by(start: usize, end: usize) -> Option { - if start > end { - return None; - } +fn first_value_divisible_by(start: usize, end: usize) -> Option { + if start > end { + return None; + } - let mut result: usize = 1; + let mut result: usize = 1; - for i in start..(end + 1) { - result = (result * i) / gcd(result, i); - } + for i in start..(end + 1) { + result = (result * i) / gcd(result, i); + } - return Some(result); + return Some(result); } fn main() { - let number = first_value_divisible_by(1, 20).unwrap(); + let number = first_value_divisible_by(1, 20).unwrap(); - println!("The smallest number that is divisible by all integers between 1 and 20 is {number}"); + println!("The smallest number that is divisible by all integers between 1 and 20 is {number}"); } diff --git a/src/bin/6.rs b/src/bin/6.rs index df7bbf6..d8a7fed 100644 --- a/src/bin/6.rs +++ b/src/bin/6.rs @@ -13,31 +13,31 @@ const LOWER_BOUND: usize = 1; const UPPER_BOUND: usize = 100; fn sum_of_squares(lower_bound: usize, upper_bound: usize) -> Option { - if lower_bound > upper_bound { - return None; - } + if lower_bound > upper_bound { + return None; + } - let mut squares: Vec = vec![]; + let mut squares: Vec = vec![]; - for i in lower_bound..(upper_bound + 1) { - squares.push(i.pow(2)); - } + for i in lower_bound..(upper_bound + 1) { + squares.push(i.pow(2)); + } - return Some(squares.iter().sum()); + return Some(squares.iter().sum()); } fn square_of_sum(lower_bound: usize, upper_bound: usize) -> Option { - if lower_bound > upper_bound { - return None; - } + if lower_bound > upper_bound { + return None; + } - return Some(((lower_bound..(upper_bound + 1)).sum::()).pow(2)); + return Some(((lower_bound..(upper_bound + 1)).sum::()).pow(2)); } fn main() { - let squared_sum = square_of_sum(LOWER_BOUND, UPPER_BOUND).unwrap(); - let summed_squares = sum_of_squares(LOWER_BOUND, UPPER_BOUND).unwrap(); - let difference = squared_sum - summed_squares; + let squared_sum = square_of_sum(LOWER_BOUND, UPPER_BOUND).unwrap(); + let summed_squares = sum_of_squares(LOWER_BOUND, UPPER_BOUND).unwrap(); + let difference = squared_sum - summed_squares; - println!("For the numbers between {LOWER_BOUND} and {UPPER_BOUND}, the difference between the square of the sum and the sum of the squares is {difference}"); + println!("For the numbers between {LOWER_BOUND} and {UPPER_BOUND}, the difference between the square of the sum and the sum of the squares is {difference}"); } diff --git a/src/bin/7.rs b/src/bin/7.rs index fd72460..03decb9 100644 --- a/src/bin/7.rs +++ b/src/bin/7.rs @@ -10,52 +10,52 @@ use std::f64::consts::E; // Implementation of the Sieve of Eratosthenes // https://en.wikipedia.org/wiki/Sieve_of_Eratosthenes fn find_primes(upper_bound: usize) -> Vec { - let mut mask = vec![true; upper_bound]; - let mut primes: Vec = vec![]; + let mut mask = vec![true; upper_bound]; + let mut primes: Vec = vec![]; - mask[0] = false; - mask[1] = false; + mask[0] = false; + mask[1] = false; - for i in 2..upper_bound { - if mask[i] { - primes.push(i); + for i in 2..upper_bound { + if mask[i] { + primes.push(i); - let mut j = 2 * i; + let mut j = 2 * i; - while j < upper_bound { - mask[j] = false; - j += i; - } - } - } + while j < upper_bound { + mask[j] = false; + j += i; + } + } + } - return primes; + return primes; } // Bounds for nth prime: http://en.wikipedia.org/wiki/Prime_number_theorem // ln n + ln(ln n) - 1 < p_n / n < ln n + ln(ln n), n >= 6 fn upper_bound_for_nth_prime(n: usize) -> usize { - // The first 5 primes are under 13 (6th prime) - if n < 6 { - return 13; - } + // The first 5 primes are under 13 (6th prime) + if n < 6 { + return 13; + } - let ln_n = (n as f64).log(E); + let ln_n = (n as f64).log(E); - return n * (ln_n + ln_n.log(E)).ceil() as usize; + return n * (ln_n + ln_n.log(E)).ceil() as usize; } fn nth_prime(n: usize) -> Option { - if n < 1 { - return None; - } + if n < 1 { + return None; + } - let primes = find_primes(upper_bound_for_nth_prime(n)); - return Some(primes[n - 1]); + let primes = find_primes(upper_bound_for_nth_prime(n)); + return Some(primes[n - 1]); } fn main() { - let number = nth_prime(10001).unwrap(); + let number = nth_prime(10001).unwrap(); - println!("The 10,001st prime number is {number}"); + println!("The 10,001st prime number is {number}"); } diff --git a/src/bin/8.rs b/src/bin/8.rs index dddee22..775769a 100644 --- a/src/bin/8.rs +++ b/src/bin/8.rs @@ -30,49 +30,49 @@ const NUMBER: &str = "7316717653133062491922511967442657474235534919493496983520 const ADJACENT_DIGITS: usize = 13; fn largest_product(number: &str, adjacent_digits: usize) -> Option { - if adjacent_digits > number.len() { - return None; - } + if adjacent_digits > number.len() { + return None; + } - let mut cursor_index = 0; - let mut selections: Vec> = vec![]; - let characters = number.chars().collect::>(); + let mut cursor_index = 0; + let mut selections: Vec> = vec![]; + let characters = number.chars().collect::>(); - while cursor_index < number.len() { - let mut selection: Vec = vec![]; + while cursor_index < number.len() { + let mut selection: Vec = vec![]; - for i in 0..adjacent_digits { - if cursor_index + i >= number.len() - 1 { - break; - } + for i in 0..adjacent_digits { + if cursor_index + i >= number.len() - 1 { + break; + } - selection.push(characters[cursor_index + i].to_digit(10).unwrap()); - } + selection.push(characters[cursor_index + i].to_digit(10).unwrap()); + } - selections.push(selection); - cursor_index += 1; - } + selections.push(selection); + cursor_index += 1; + } - let mut products: Vec = vec![]; + let mut products: Vec = vec![]; - for i in 0..selections.len() { - let mut product: usize = 1; + for i in 0..selections.len() { + let mut product: usize = 1; - for value in &selections[i] { - product *= *value as usize; - } + for value in &selections[i] { + product *= *value as usize; + } - products.push(product); - } + products.push(product); + } - products.sort(); - products.reverse(); + products.sort(); + products.reverse(); - return Some(products[0]); + return Some(products[0]); } fn main() { - let value = largest_product(NUMBER, ADJACENT_DIGITS).unwrap(); - - println!("The thirteen adjacent digits in the number that have the greatest product have a product of {value}"); + let value = largest_product(NUMBER, ADJACENT_DIGITS).unwrap(); + + println!("The thirteen adjacent digits in the number that have the greatest product have a product of {value}"); } diff --git a/src/bin/9.rs b/src/bin/9.rs index 65d5489..c84d962 100644 --- a/src/bin/9.rs +++ b/src/bin/9.rs @@ -24,7 +24,7 @@ There exists exactly one Pythagorean triplet for which a + b + c = 1000. F fn triplet_with_sum(sum: isize) -> Option<(isize, isize, isize)> { for a in 1..(sum + 1) { let b: isize = ((2 * a * sum) - sum.pow(2)) / (2 * (a - sum)); - let c: isize = sum - a - b; + let c: isize = sum - a - b; if a.pow(2) + b.pow(2) == c.pow(2) { return Some((a, b, c)); @@ -36,6 +36,6 @@ fn triplet_with_sum(sum: isize) -> Option<(isize, isize, isize)> { fn main() { let (a, b, c) = triplet_with_sum(1000).unwrap(); - + println!("a = {a}, b = {b}, c = {c} // abc = {}", a * b * c); } diff --git a/src/main.rs b/src/main.rs index c7d516d..9b1eac2 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,15 +1,19 @@ use clap::{Parser, Subcommand}; use owo_colors::OwoColorize; -use std::{fs::{self, File, OpenOptions}, path::Path, io::{Write, BufRead}}; -use scraper::{Html, Selector}; use regex::Regex; -use std::io::{BufReader}; +use scraper::{Html, Selector}; +use std::io::BufReader; +use std::{ + fs::{self, File, OpenOptions}, + io::{BufRead, Write}, + path::Path, +}; #[derive(Parser)] #[clap(about, author, version)] struct Value { #[clap(subcommand)] - command: Commands + command: Commands, } #[derive(Subcommand)] @@ -55,13 +59,19 @@ async fn new() -> Result<(), Box> { Err("Please ensure that your input is valid!".to_owned()) } }) - .build() - ).unwrap().as_int().unwrap(); + .build(), + ) + .unwrap() + .as_int() + .unwrap(); // todo: thoughts documents (?) - + // Fetch the problem information - let body = reqwest::get(format!("https://projecteuler.net/problem={problem_number}")).await?.text().await?; + let body = reqwest::get(format!("https://projecteuler.net/problem={problem_number}")) + .await? + .text() + .await?; let document = Html::parse_document(body.as_str()); let title_selector = Selector::parse("h2")?; @@ -79,12 +89,12 @@ async fn new() -> Result<(), Box> { let mut problem = html_tag_regex .replace_all( document - .select(&content_selector) - .next() - .unwrap() - .inner_html() - .as_str(), - " " + .select(&content_selector) + .next() + .unwrap() + .inner_html() + .as_str(), + " ", ) .to_string() .replace("$$", " "); @@ -98,7 +108,7 @@ Problem {} - {} fn main() {{ println!(\"Hello World!\"); -}}", +}}", problem_number, html_escape::decode_html_entities(&mut title).to_string(), html_escape::decode_html_entities(&mut problem) @@ -117,17 +127,13 @@ fn main() {{ // Read the contents of the readme for editing let readme_path = base_dir.join("readme.md"); - let mut readme_file = OpenOptions::new() - .read(true) - .open(&readme_path) - .unwrap(); + let mut readme_file = OpenOptions::new().read(true).open(&readme_path).unwrap(); let mut readme_content = BufReader::new(&readme_file) .lines() .map(|s| s.unwrap()) .collect::>(); - drop(readme_file); // Mark the problem as done on the readme @@ -138,7 +144,10 @@ fn main() {{ if readme_regex.is_match(line) { let matched = readme_regex.captures(line).unwrap(); - readme_content[i] = format!("- [x] {problem_number} - [{}](src/bin/{problem_number}.rs)", &matched[1].trim()); + readme_content[i] = format!( + "- [x] {problem_number} - [{}](src/bin/{problem_number}.rs)", + &matched[1].trim() + ); } } @@ -147,26 +156,30 @@ fn main() {{ let completed_regex = Regex::new("([0-9]+)").unwrap(); - let new_completed = completed_regex - .captures(readme_string.as_str()) - .unwrap()[1] + let new_completed = completed_regex.captures(readme_string.as_str()).unwrap()[1] .parse::() - .unwrap() + 1; + .unwrap() + + 1; - readme_string = completed_regex.replace(readme_string.as_str(), format!("{new_completed}")).to_string(); + readme_string = completed_regex + .replace( + readme_string.as_str(), + format!("{new_completed}"), + ) + .to_string(); // Write the new content to the readme - readme_file = OpenOptions::new() - .write(true) - .open(&readme_path) - .unwrap(); + readme_file = OpenOptions::new().write(true).open(&readme_path).unwrap(); readme_file.write(readme_string.as_bytes()).unwrap(); drop(readme_file); // Announce completion! - println!("{}", "File successfully created! Good luck (:".green().bold()); + println!( + "{}", + "File successfully created! Good luck (:".green().bold() + ); Ok(()) } @@ -175,6 +188,6 @@ fn main() { let value = Value::parse(); match value.command { - Commands::New => new().unwrap() + Commands::New => new().unwrap(), } }