diff --git a/readme.md b/readme.md index c74e692..487b875 100644 --- a/readme.md +++ b/readme.md @@ -17,7 +17,7 @@ Here is a [link to my profile](https://projecteuler.net/progress=newtykins). ## Challenge Completion -### 23 out of 100 public challenges completed. +### 25 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) @@ -38,7 +38,7 @@ Here is a [link to my profile](https://projecteuler.net/progress=newtykins). - [x] 17 - [Number letter counts](src/bin/17.rs) - [x] 18 - [Maximum path sum I](src/bin/18.rs) - [x] 19 - Counting Sundays -- [ ] 20 - Factorial digit sum +- [x] 20 - Factorial digit sum - [ ] 21 - Amicable numbers - [x] 22 - [Names scores](src/bin/22.rs) - [ ] 23 - Non-abundant sums diff --git a/src/bin/16.rs b/src/bin/16.rs index e8b110b..6f8ea9d 100644 --- a/src/bin/16.rs +++ b/src/bin/16.rs @@ -5,11 +5,11 @@ Problem 16 - Power digit sum What is the sum of the digits of the number 2 1000 ? */ -fn power_digit_sum(base: usize) -> usize { - let mut digits = [0u8; POWER]; +fn power_digit_sum(base: usize, power: usize) -> usize { + let mut digits = vec![0u8; power]; digits[0] = 1; // 2^0 = 1 - for _ in 0..POWER { + for _ in 0..power { let mut carry = 0; for digit in digits.iter_mut() { @@ -23,7 +23,7 @@ fn power_digit_sum(base: usize) -> usize { } pub fn main() { - let sum = power_digit_sum::<1000>(2); + let sum = power_digit_sum(2, 1000); println!("The sum of the digits of the number 2^1000 is {}!", sum); } diff --git a/src/bin/20.rs b/src/bin/20.rs new file mode 100644 index 0000000..ae239fc --- /dev/null +++ b/src/bin/20.rs @@ -0,0 +1,34 @@ +/* +Problem 20 - Factorial Digit Sum + +$n!$ means $n \times (n - 1) \times \cdots \times 3 \times 2 \times 1$. +For example, $10! = 10 \times 9 \times \cdots \times 3 \times 2 \times 1 = 3628800$, and the sum of the digits in the number $10!$ is $3 + 6 + 2 + 8 + 8 + 0 + 0 = 27$. +Find the sum of the digits in the number $100!$. +*/ + +fn multiply(digits: &mut Vec, multiplier: usize) { + let mut carry = 0usize; + + for digit in digits.iter_mut() { + let product = *digit as usize * multiplier + carry; + *digit = (product % 10) as u8; + carry = product / 10; + } + + while carry > 0 { + digits.push((carry % 10) as u8); + carry /= 10; + } +} + +pub fn main() { + let mut digits = vec![1]; + + for num in 2..=100 { + multiply(&mut digits, num); + } + + let sum: usize = digits.iter().map(|&d| d as usize).sum(); + + print!("The sum of the digits in the number 100! is {}!", sum); +} diff --git a/src/commands/new.rs b/src/commands/new.rs index 8a36751..df28967 100644 --- a/src/commands/new.rs +++ b/src/commands/new.rs @@ -17,40 +17,42 @@ pub async fn execute(number: Option) -> Result<()> { file.write(problem.file_body().as_bytes())?; drop(file); - // open readme - let mut readme_file = OpenOptions::new().read(true).open(README.clone())?; + if problem.number <= 100 { + // open readme + let mut readme_file = OpenOptions::new().read(true).open(README.clone())?; - let readme_content = { - // read - let mut content = BufReader::new(&readme_file) - .lines() - .map(|s| s.unwrap()) - .collect::>() - .join("\n"); + let readme_content = { + // read + let mut content = BufReader::new(&readme_file) + .lines() + .map(|s| s.unwrap()) + .collect::>() + .join("\n"); + drop(readme_file); + + // mark problem as done on readme + content = content.replace( + &format!("\n- [ ] {}", problem.number), + &format!("\n- [x] {}", problem.number), + ); + + // update completed count + let completion_regex = Regex::new(r"(\d+) out of")?; + let problem_count = fs::read_dir(SOLUTIONS.clone())?.count(); + + content = completion_regex + .replace(&content, format!("{} out of", problem_count)) + .to_string(); + + content + }; + + // write the new content to the readme + readme_file = OpenOptions::new().write(true).open(README.clone())?; + readme_file.write(readme_content.as_bytes())?; drop(readme_file); - - // mark problem as done on readme - content = content.replace( - &format!("\n- [ ] {}", problem.number), - &format!("\n- [x] {}", problem.number), - ); - - // update completed count - let completion_regex = Regex::new(r"(\d+) out of")?; - let problem_count = fs::read_dir(SOLUTIONS.clone())?.count(); - - content = completion_regex - .replace(&content, format!("{} out of", problem_count)) - .to_string(); - - content - }; - - // write the new content to the readme - readme_file = OpenOptions::new().write(true).open(README.clone())?; - readme_file.write(readme_content.as_bytes())?; - drop(readme_file); + } // add the problem to the run command let mut run_file = OpenOptions::new() diff --git a/src/commands/run.rs b/src/commands/run.rs index faf8dc9..01876a6 100644 --- a/src/commands/run.rs +++ b/src/commands/run.rs @@ -42,6 +42,8 @@ mod thirteen; mod three; #[path = "../bin/12.rs"] mod twelve; +#[path = "../bin/20.rs"] +mod twenty; #[path = "../bin/27.rs"] mod twenty_seven; #[path = "../bin/22.rs"] @@ -87,6 +89,7 @@ pub async fn execute( 27 => twenty_seven::main(), 67 => sixty_seven::main(), 19 => nineteen::main(), + 20 => twenty::main(), _ => { exists = false; println!( diff --git a/src/problem.rs b/src/problem.rs index af10ee0..4640ee2 100644 --- a/src/problem.rs +++ b/src/problem.rs @@ -21,8 +21,6 @@ impl Problem { // ensure the number is in bound if n <= 0 { Err("Please enter a number greater than 0".to_string()) - } else if n > 100 { - Err("Please enter a number less than or equal to 100".to_string()) } // ensure that the problem has not already got a file associated with it else { @@ -64,7 +62,7 @@ impl Problem { let number = number .unwrap_or_else(|| Self::prompt_number("Please select a problem:", false).unwrap()); - let body = reqwest::get(format!("https://projecteuler.net/minimal={number}")) + let body = reqwest::get(format!("https://projecteuler.net/problem={number}")) .await? .text() .await?;