From 87d96c83e48e61720447e592f6f325bc702fda69 Mon Sep 17 00:00:00 2001 From: Xu Shaohua Date: Tue, 30 Jan 2024 08:55:48 +0800 Subject: [PATCH] Remove project euler --- Cargo.toml | 4 - project_euler/Cargo.toml | 9 - project_euler/README.md | 8 - project_euler/rust-toolchain.toml | 3 - project_euler/src/bin/euler_000.rs | 21 -- project_euler/src/bin/euler_001.rs | 108 ---------- project_euler/src/bin/euler_002.rs | 67 ------ project_euler/src/bin/euler_003.rs | 94 --------- project_euler/src/bin/euler_004.rs | 117 ----------- project_euler/src/bin/euler_005.rs | 49 ----- project_euler/src/bin/euler_006.rs | 56 ----- project_euler/src/bin/euler_007.rs | 51 ----- project_euler/src/bin/euler_008.rs | 98 --------- project_euler/src/bin/euler_009.rs | 37 ---- project_euler/src/bin/euler_010.rs | 26 --- project_euler/src/bin/euler_011.rs | 126 ----------- project_euler/src/bin/euler_012.rs | 90 -------- project_euler/src/bin/euler_013.rs | 315 ---------------------------- project_euler/src/bin/euler_014.rs | 104 --------- project_euler/src/bin/euler_016.rs | 41 ---- project_euler/src/bin/euler_017.rs | 243 --------------------- project_euler/src/bin/euler_018.rs | 52 ----- project_euler/src/bin/euler_019.rs | 89 -------- project_euler/src/bin/euler_020.rs | 41 ---- project_euler/src/bin/euler_021.rs | 50 ----- project_euler/src/bin/euler_022.rs | 63 ------ project_euler/src/bin/euler_023.rs | 72 ------- project_euler/src/bin/euler_024.rs | 33 --- project_euler/src/bin/euler_025.rs | 163 -------------- project_euler/src/bin/euler_026.rs | 70 ------- project_euler/src/bin/euler_027.rs | 104 --------- project_euler/src/bin/euler_028.rs | 45 ---- project_euler/src/bin/euler_029.rs | 51 ----- project_euler/src/bin/euler_030.rs | 129 ------------ project_euler/src/bin/euler_031.rs | 129 ------------ project_euler/src/bin/euler_032.rs | 88 -------- project_euler/src/bin/euler_033.rs | 59 ------ project_euler/src/bin/euler_034.rs | 68 ------ project_euler/src/bin/euler_035.rs | 83 -------- project_euler/src/bin/euler_036.rs | 125 ----------- project_euler/src/bin/euler_037.rs | 66 ------ project_euler/src/bin/euler_038.rs | 121 ----------- project_euler/src/bin/euler_039.rs | 55 ----- project_euler/src/bin/euler_040.rs | 81 ------- project_euler/src/bin/euler_041.rs | 50 ----- project_euler/src/bin/euler_042.rs | 72 ------- project_euler/src/bin/euler_043.rs | 69 ------ project_euler/src/bin/euler_044.rs | 55 ----- project_euler/src/bin/euler_045.rs | 61 ------ project_euler/src/bin/euler_046.rs | 75 ------- project_euler/src/bin/euler_047.rs | 112 ---------- project_euler/src/bin/euler_048.rs | 60 ------ project_euler/src/bin/euler_049.rs | 78 ------- project_euler/src/bin/euler_050.rs | 59 ------ project_euler/src/bin/euler_052.rs | 98 --------- project_euler/src/bin/euler_053.rs | 51 ----- project_euler/src/bin/euler_056.rs | 45 ---- project_euler/src/bin/euler_057.rs | 55 ----- project_euler/src/bin/euler_060.rs | 105 ---------- project_euler/src/bin/euler_063.rs | 42 ---- project_euler/src/bin/euler_092.rs | 87 -------- project_euler/src/bin/todo.md | 8 - project_euler/src/concate_number.rs | 38 ---- project_euler/src/digits.rs | 51 ----- project_euler/src/gcd.rs | 80 ------- project_euler/src/lib.rs | 9 - project_euler/src/permutation.rs | 112 ---------- project_euler/src/primes.rs | 181 ---------------- project_euler/todo.md | 4 - 69 files changed, 5161 deletions(-) delete mode 100644 project_euler/Cargo.toml delete mode 100644 project_euler/README.md delete mode 100644 project_euler/rust-toolchain.toml delete mode 100644 project_euler/src/bin/euler_000.rs delete mode 100644 project_euler/src/bin/euler_001.rs delete mode 100644 project_euler/src/bin/euler_002.rs delete mode 100644 project_euler/src/bin/euler_003.rs delete mode 100644 project_euler/src/bin/euler_004.rs delete mode 100644 project_euler/src/bin/euler_005.rs delete mode 100644 project_euler/src/bin/euler_006.rs delete mode 100644 project_euler/src/bin/euler_007.rs delete mode 100644 project_euler/src/bin/euler_008.rs delete mode 100644 project_euler/src/bin/euler_009.rs delete mode 100644 project_euler/src/bin/euler_010.rs delete mode 100644 project_euler/src/bin/euler_011.rs delete mode 100644 project_euler/src/bin/euler_012.rs delete mode 100644 project_euler/src/bin/euler_013.rs delete mode 100644 project_euler/src/bin/euler_014.rs delete mode 100644 project_euler/src/bin/euler_016.rs delete mode 100644 project_euler/src/bin/euler_017.rs delete mode 100644 project_euler/src/bin/euler_018.rs delete mode 100644 project_euler/src/bin/euler_019.rs delete mode 100644 project_euler/src/bin/euler_020.rs delete mode 100644 project_euler/src/bin/euler_021.rs delete mode 100644 project_euler/src/bin/euler_022.rs delete mode 100644 project_euler/src/bin/euler_023.rs delete mode 100644 project_euler/src/bin/euler_024.rs delete mode 100644 project_euler/src/bin/euler_025.rs delete mode 100644 project_euler/src/bin/euler_026.rs delete mode 100644 project_euler/src/bin/euler_027.rs delete mode 100644 project_euler/src/bin/euler_028.rs delete mode 100644 project_euler/src/bin/euler_029.rs delete mode 100644 project_euler/src/bin/euler_030.rs delete mode 100644 project_euler/src/bin/euler_031.rs delete mode 100644 project_euler/src/bin/euler_032.rs delete mode 100644 project_euler/src/bin/euler_033.rs delete mode 100644 project_euler/src/bin/euler_034.rs delete mode 100644 project_euler/src/bin/euler_035.rs delete mode 100644 project_euler/src/bin/euler_036.rs delete mode 100644 project_euler/src/bin/euler_037.rs delete mode 100644 project_euler/src/bin/euler_038.rs delete mode 100644 project_euler/src/bin/euler_039.rs delete mode 100644 project_euler/src/bin/euler_040.rs delete mode 100644 project_euler/src/bin/euler_041.rs delete mode 100644 project_euler/src/bin/euler_042.rs delete mode 100644 project_euler/src/bin/euler_043.rs delete mode 100644 project_euler/src/bin/euler_044.rs delete mode 100644 project_euler/src/bin/euler_045.rs delete mode 100644 project_euler/src/bin/euler_046.rs delete mode 100644 project_euler/src/bin/euler_047.rs delete mode 100644 project_euler/src/bin/euler_048.rs delete mode 100644 project_euler/src/bin/euler_049.rs delete mode 100644 project_euler/src/bin/euler_050.rs delete mode 100644 project_euler/src/bin/euler_052.rs delete mode 100644 project_euler/src/bin/euler_053.rs delete mode 100644 project_euler/src/bin/euler_056.rs delete mode 100644 project_euler/src/bin/euler_057.rs delete mode 100644 project_euler/src/bin/euler_060.rs delete mode 100644 project_euler/src/bin/euler_063.rs delete mode 100644 project_euler/src/bin/euler_092.rs delete mode 100644 project_euler/src/bin/todo.md delete mode 100644 project_euler/src/concate_number.rs delete mode 100644 project_euler/src/digits.rs delete mode 100644 project_euler/src/gcd.rs delete mode 100644 project_euler/src/lib.rs delete mode 100644 project_euler/src/permutation.rs delete mode 100644 project_euler/src/primes.rs delete mode 100644 project_euler/todo.md diff --git a/Cargo.toml b/Cargo.toml index 0a622e9d..0edc9c0f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -18,10 +18,6 @@ members = [ "graphs", ] -exclude = [ - "project_euler", -] - [profile.release] debug = true diff --git a/project_euler/Cargo.toml b/project_euler/Cargo.toml deleted file mode 100644 index 1d9b5679..00000000 --- a/project_euler/Cargo.toml +++ /dev/null @@ -1,9 +0,0 @@ -[package] -name = "euler" -version = "0.1.0" -edition = "2021" -publish = false - -[dependencies] -num-bigint = "0.4.4" -num-traits = "0.2.17" diff --git a/project_euler/README.md b/project_euler/README.md deleted file mode 100644 index 52dd88e3..00000000 --- a/project_euler/README.md +++ /dev/null @@ -1,8 +0,0 @@ - -# About -This crate is source code of solutions in [project euler][euler]. - -![Badge][badge] - -[euler]: https://projecteuler.org -[badge]: https://projecteuler.net/profile/xushaohua.png diff --git a/project_euler/rust-toolchain.toml b/project_euler/rust-toolchain.toml deleted file mode 100644 index e9743fb4..00000000 --- a/project_euler/rust-toolchain.toml +++ /dev/null @@ -1,3 +0,0 @@ - -[toolchain] -channel = "nightly" diff --git a/project_euler/src/bin/euler_000.rs b/project_euler/src/bin/euler_000.rs deleted file mode 100644 index 51dbebff..00000000 --- a/project_euler/src/bin/euler_000.rs +++ /dev/null @@ -1,21 +0,0 @@ -// Copyright (c) 2020 Xu Shaohua . All rights reserved. -// Use of this source is governed by General Public License that can be found -// in the LICENSE file. - -#![feature(test)] -extern crate test; - -/// Problem: - -fn method1() -> u64 { - 0 -} - -fn main() { - println!("method1: {}", method1()); -} - -#[bench] -fn bench_method1(b: &mut test::Bencher) { - b.iter(|| method1()); -} diff --git a/project_euler/src/bin/euler_001.rs b/project_euler/src/bin/euler_001.rs deleted file mode 100644 index 6d1ef96a..00000000 --- a/project_euler/src/bin/euler_001.rs +++ /dev/null @@ -1,108 +0,0 @@ -// Copyright (c) 2020 Xu Shaohua . All rights reserved. -// Use of this source is governed by General Public License that can be found -// in the LICENSE file. - -#![feature(test)] -extern crate test; - -/// Problem: -/// -/// If we list all the natural numbers below 10 that are multiples of 3 or 5, -/// we get 3, 5, 6 and 9. The sum of these multiples is 23. -/// -/// Find the sum of all the multiples of 3 or 5 below 1000. - -fn method1(max_num: usize) -> usize { - let mut arr = vec![false; max_num + 1]; - for i in 1..max_num { - let mul = i * 3; - if mul > max_num { - break; - } - arr[mul] = true; - } - - for i in 1..max_num { - let mul = i * 5; - if mul > max_num { - break; - } - arr[mul] = true; - } - - let mut sum = 0; - for i in 1..max_num { - if arr[i] { - sum += i; - } - } - sum -} - -fn method2(max_num: usize) -> usize { - let mut sum = 0; - for i in 1..max_num { - let mul = i * 3; - if mul >= max_num { - break; - } - sum += mul; - } - - let mut reminder = 0; - for i in 1..max_num { - let mul = i * 5; - if mul >= max_num { - break; - } - reminder += 1; - if reminder == 3 { - reminder = 0; - } else { - sum += mul; - } - } - sum -} - -fn method3(max_num: usize) -> usize { - let mut sum = 0; - let mut tmp = 0; - while tmp < max_num { - sum += tmp; - tmp += 3; - } - tmp = 0; - while tmp < max_num { - sum += tmp; - tmp += 5; - } - tmp = 0; - while tmp < max_num { - sum -= tmp; - tmp += 15; - } - sum -} - -fn main() { - let max_num = 1000; - println!("sum in method1: {}", method1(max_num)); - println!("sum in method2: {}", method2(max_num)); - println!("sum in method3: {}", method3(max_num)); -} - -#[bench] -fn bench_method1(b: &mut test::Bencher) { - b.iter(|| assert_eq!(method1(1000), 233_168)); -} - -#[bench] -fn bench_method2(b: &mut test::Bencher) { - b.iter(|| assert_eq!(method2(1000), 233_168)); -} - -#[bench] -fn bench_method3(b: &mut test::Bencher) { - b.iter(|| assert_eq!(method3(1000), 233_168)); -} diff --git a/project_euler/src/bin/euler_002.rs b/project_euler/src/bin/euler_002.rs deleted file mode 100644 index 3e90266f..00000000 --- a/project_euler/src/bin/euler_002.rs +++ /dev/null @@ -1,67 +0,0 @@ -// Copyright (c) 2020 Xu Shaohua . All rights reserved. -// Use of this source is governed by General Public License that can be found -// in the LICENSE file. - -#![feature(test)] -extern crate test; - -/// Problem: -/// -/// Each new term in the Fibonacci sequence is generated by adding the previous -/// two terms. By starting with 1 and 2, the first 10 terms will be: -/// 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, ... -/// By considering the terms in the Fibonacci sequence whose values do not -/// exceed four million, find the sum of the even-valued terms. - -fn method1(max_num: usize) -> usize { - let mut sum = 0; - let mut prev = 1; - let mut current = 2; - let mut tmp; - let mut odd_num_count = 0; - while current <= max_num { - tmp = prev + current; - prev = current; - current = tmp; - odd_num_count += 1; - if odd_num_count == 1 { - sum += prev; - } else if odd_num_count == 3 { - odd_num_count = 0; - } - } - - sum -} - -fn method2(max_num: usize) -> usize { - let mut sum = 0; - let mut prev = 1; - let mut current = 2; - - while current < max_num { - let new = prev + current; - prev = current; - current = new; - if prev % 2 == 0 { - sum += prev; - } - } - sum -} - -fn main() { - let max_num = 4_000_000; - println!("sum: {}", method1(max_num)); - println!("sum: {}", method2(max_num)); -} - -#[bench] -fn bench_method1(b: &mut test::Bencher) { - b.iter(|| assert_eq!(method1(4_000_000), 4_613_732)); -} - -#[bench] -fn bench_method2(b: &mut test::Bencher) { - b.iter(|| assert_eq!(method2(4_000_000), 4_613_732)); -} diff --git a/project_euler/src/bin/euler_003.rs b/project_euler/src/bin/euler_003.rs deleted file mode 100644 index d7d75e7f..00000000 --- a/project_euler/src/bin/euler_003.rs +++ /dev/null @@ -1,94 +0,0 @@ -// Copyright (c) 2020 Xu Shaohua . All rights reserved. -// Use of this source is governed by General Public License that can be found -// in the LICENSE file. - -#![feature(test)] -extern crate euler; -extern crate test; - -use euler::primes::get_prime_list; - -/// Problem: -/// -/// The prime factors of 13195 are 5, 7, 13 and 29. -/// What is the largest prime factor of the number 600851475143 ? - -const LARGEST_PRIME: u64 = 600851475143; - -fn method1(num: u64) -> u64 { - // Largest possible prime factor of an integer is its square root. - let sqrt: usize = (num as f64).sqrt().ceil() as usize; - - // Now get prime list smaller than square root. - let prime_list = get_prime_list(sqrt); - for prime in prime_list.into_iter().rev() { - if num % (prime as u64) == 0 { - return prime as u64; - } - } - - 0 -} - -fn method2(num: u64) -> u64 { - for i in 2..=num { - if num % i == 0 { - return if num == i { num } else { method2(num / i) }; - } - } - 0 -} - -fn method3(mut num: u64) -> u64 { - let mut i = 2; - while i < num { - if num % i == 0 { - num /= i; - } - i += 1; - } - i -} - -fn method4(mut num: u64) -> u64 { - let mut i = 2; - while i <= num { - if num % i == 0 { - num /= i; - } else { - if i == 2 { - i += 1; - } else { - i += 2; - } - } - } - i -} - -fn main() { - println!("method1: {}", method1(LARGEST_PRIME)); - println!("method2: {}", method2(LARGEST_PRIME)); - println!("method3: {}", method3(LARGEST_PRIME)); - println!("method4: {}", method4(LARGEST_PRIME)); -} - -#[bench] -fn bench_method1(b: &mut test::Bencher) { - b.iter(|| assert_eq!(method1(LARGEST_PRIME), 6857)); -} - -#[bench] -fn bench_method2(b: &mut test::Bencher) { - b.iter(|| assert_eq!(method2(LARGEST_PRIME), 6857)); -} - -#[bench] -fn bench_method3(b: &mut test::Bencher) { - b.iter(|| assert_eq!(method3(LARGEST_PRIME), 6857)); -} - -#[bench] -fn bench_method4(b: &mut test::Bencher) { - b.iter(|| assert_eq!(method4(LARGEST_PRIME), 6857)); -} diff --git a/project_euler/src/bin/euler_004.rs b/project_euler/src/bin/euler_004.rs deleted file mode 100644 index 1f8736fb..00000000 --- a/project_euler/src/bin/euler_004.rs +++ /dev/null @@ -1,117 +0,0 @@ -// Copyright (c) 2020 Xu Shaohua . All rights reserved. -// Use of this source is governed by General Public License that can be found -// in the LICENSE file. - -#![feature(test)] -extern crate test; - -/// Problem: -/// -/// A palindromic number reads the same both ways. The largest palindrome made -/// from the product of two 2-digit numbers is 9009 = 91 x 99. -/// -/// Find the largest palindrome made from the product of two 3-digit numbers. - -fn method1() -> u32 { - let mut largest_palindrome = 0; - for i in (1..999).rev() { - for j in (1..i).rev() { - let product = i * j; - if is_palindrome1(product) { - if product > largest_palindrome { - largest_palindrome = product; - } - break; - } else if product < largest_palindrome { - break; - } - } - } - largest_palindrome -} - -fn method2() -> u32 { - let mut largest_palindrome = 0; - for i in (1..999).rev() { - for j in (1..i).rev() { - let product = i * j; - if product < largest_palindrome { - break; - } else if is_palindrome2(product) { - if product > largest_palindrome { - largest_palindrome = product; - } - break; - } - } - } - largest_palindrome -} - -fn is_palindrome1(num: u32) -> bool { - let s = num.to_string(); - let rev_s: String = s.chars().rev().collect(); - rev_s == s -} - -fn is_palindrome2(num: u32) -> bool { - let mut mut_num = num; - let mut rev_num = 0; - while mut_num > 0 { - rev_num = rev_num * 10 + (mut_num % 10); - mut_num /= 10; - } - num == rev_num -} - -fn main() { - println!("method1: {}", method1()); - println!("method2: {}", method2()); -} - -#[bench] -fn bench_method1(b: &mut test::Bencher) { - b.iter(|| assert_eq!(method1(), 906609)); -} - -#[bench] -fn bench_method2(b: &mut test::Bencher) { - b.iter(|| assert_eq!(method2(), 906609)); -} - -#[bench] -fn bench_palindrome1(b: &mut test::Bencher) { - b.iter(|| { - for i in (1..999_999).step_by(10) { - is_palindrome1(i); - } - }); -} - -#[bench] -fn bench_palindrome2(b: &mut test::Bencher) { - b.iter(|| { - for i in (1..999_999).step_by(1) { - is_palindrome2(i); - } - }); -} - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn test_palindrome1() { - assert!(is_palindrome1(9009)); - assert!(is_palindrome1(906609)); - assert!(!is_palindrome1(98788)); - } - - #[test] - fn test_palindrome2() { - assert!(is_palindrome2(9009)); - assert!(is_palindrome2(906609)); - assert!(!is_palindrome2(98788)); - } -} diff --git a/project_euler/src/bin/euler_005.rs b/project_euler/src/bin/euler_005.rs deleted file mode 100644 index 5eaf1612..00000000 --- a/project_euler/src/bin/euler_005.rs +++ /dev/null @@ -1,49 +0,0 @@ -// Copyright (c) 2020 Xu Shaohua . All rights reserved. -// Use of this source is governed by General Public License that can be found -// in the LICENSE file. - -#![feature(test)] -extern crate test; - -use std::cmp::max; - -use euler::primes::{get_prime_factors, get_prime_list, PrimeFactor}; - -/// Problem: -/// -/// 2520 is the smallest number that can be divided by each of the numbers from -/// 1 to 10 without any remainder. What is the smallest positive number -/// that is evenly divisible by all of the numbers from 1 to 20? - -fn method1(max_num: usize) -> usize { - let ls = get_prime_list(max_num); - let mut minimum_factors = Vec::with_capacity(ls.len()); - for factor in &ls { - minimum_factors.push(PrimeFactor { - num: *factor, - count: 0, - }); - } - - for i in 2..=max_num { - let factors = get_prime_factors(i, &ls); - for factor in &factors { - for m in &mut minimum_factors { - if m.num == factor.num { - m.count = max(m.count, factor.count); - } - } - } - } - - minimum_factors.iter().fold(1, |p, f| p * f.num.pow(f.count as u32)) -} - -fn main() { - println!("method1 {}", method1(20)); -} - -#[bench] -fn bench_method1(b: &mut test::Bencher) { - b.iter(|| assert_eq!(method1(20), 232792560)); -} \ No newline at end of file diff --git a/project_euler/src/bin/euler_006.rs b/project_euler/src/bin/euler_006.rs deleted file mode 100644 index 5822aa5a..00000000 --- a/project_euler/src/bin/euler_006.rs +++ /dev/null @@ -1,56 +0,0 @@ -// Copyright (c) 2020 Xu Shaohua . All rights reserved. -// Use of this source is governed by General Public License that can be found -// in the LICENSE file. - -#![feature(test)] -extern crate test; - -/// Problem: -/// -/// The sum of the squares of the first ten natural numbers is, -/// -/// 1^2 + 2^2 + ... + 10^2 = 385 -/// -/// The square of the sum of the first ten natural numbers is, -/// (1 + 2 + ... + 10)^2 = 55^2 = 3025 -/// -/// Hence the difference between the sum of the squares of the first -/// ten natural numbers and the square of the sum is 3025−385=2640 . -/// -/// Find the difference between the sum of the squares of the first -/// one hundred natural numbers and the square of the sum. - -fn method1(max_num: i64) -> i64 { - let mut square_sum = 0; - for i in 1..=max_num { - square_sum += i * i; - } - - let mut sum = 0; - for i in 1..=max_num { - sum += i; - } - sum * sum - square_sum -} - -fn method2(max_num: i64) -> i64 { - let square_sum: i64 = (1..=max_num).map(|i| i * i).sum(); - let sum: i64 = (1..=max_num).sum(); - sum * sum - square_sum -} - -fn main() { - let max_num = 100; - println!("result: {}", method1(max_num)); - println!("result: {}", method2(max_num)); -} - -#[bench] -fn bench_method1(b: &mut test::Bencher) { - b.iter(|| assert_eq!(method1(100), 25164150)); -} - -#[bench] -fn bench_method2(b: &mut test::Bencher) { - b.iter(|| assert_eq!(method2(100), 25164150)); -} diff --git a/project_euler/src/bin/euler_007.rs b/project_euler/src/bin/euler_007.rs deleted file mode 100644 index a299253f..00000000 --- a/project_euler/src/bin/euler_007.rs +++ /dev/null @@ -1,51 +0,0 @@ -// Copyright (c) 2020 Xu Shaohua . All rights reserved. -// Use of this source is governed by General Public License that can be found -// in the LICENSE file. - -#![feature(test)] -extern crate test; - -use euler::primes::{get_prime_list, IsPrime}; - -/// Problem: -/// -/// By listing the first six prime numbers: 2, 3, 5, 7, 11, and 13, we can see -/// that the 6th prime is 13. -/// -/// What is the 10 001st prime number? - -fn method1(nth_prime: u32) -> usize { - let prime_list = get_prime_list(110_000); - prime_list[nth_prime as usize - 1] -} - -fn method2(nth_prime: u32) -> usize { - let mut primes = Vec::with_capacity(nth_prime as usize); - primes.push(2); - let mut num = 3; - while primes.len() < nth_prime as usize { - if num.is_prime() { - primes.push(num); - } - - num += 2; - } - - primes[primes.len() - 1] -} - -fn main() { - let nth_prime = 10001; - println!("#10001 prime is: {}", method1(nth_prime)); - println!("#10001 prime is: {}", method2(nth_prime)); -} - -#[bench] -fn bench_method1(b: &mut test::Bencher) { - b.iter(|| assert_eq!(method1(10001), 104743)); -} - -#[bench] -fn bench_method2(b: &mut test::Bencher) { - b.iter(|| assert_eq!(method2(10001), 104743)); -} diff --git a/project_euler/src/bin/euler_008.rs b/project_euler/src/bin/euler_008.rs deleted file mode 100644 index f272e93d..00000000 --- a/project_euler/src/bin/euler_008.rs +++ /dev/null @@ -1,98 +0,0 @@ -// Copyright (c) 2020 Xu Shaohua . All rights reserved. -// Use of this source is governed by General Public License that can be found -// in the LICENSE file. - -#![feature(test)] -extern crate test; - -/// Problem: -/// -/// The four adjacent digits in the 1000-digit number that have -/// the greatest product are 9 × 9 × 8 × 9 = 5832. -/// -/// 73167176531330624919225119674426574742355349194934 -/// 96983520312774506326239578318016984801869478851843 -/// 85861560789112949495459501737958331952853208805511 -/// 12540698747158523863050715693290963295227443043557 -/// 66896648950445244523161731856403098711121722383113 -/// 62229893423380308135336276614282806444486645238749 -/// 30358907296290491560440772390713810515859307960866 -/// 70172427121883998797908792274921901699720888093776 -/// 65727333001053367881220235421809751254540594752243 -/// 52584907711670556013604839586446706324415722155397 -/// 53697817977846174064955149290862569321978468622482 -/// 83972241375657056057490261407972968652414535100474 -/// 82166370484403199890008895243450658541227588666881 -/// 16427171479924442928230863465674813919123162824586 -/// 17866458359124566529476545682848912883142607690042 -/// 24219022671055626321111109370544217506941658960408 -/// 07198403850962455444362981230987879927244284909188 -/// 84580156166097919133875499200524063689912560717606 -/// 05886116467109405077541002256983155200055935729725 -/// 71636269561882670428252483600823257530420752963450 -/// -/// Find the thirteen adjacent digits in the 1000-digit number -/// that have the greatest product. What is the value of this product? - -const NUMS: &str = " -73167176531330624919225119674426574742355349194934 -96983520312774506326239578318016984801869478851843 -85861560789112949495459501737958331952853208805511 -12540698747158523863050715693290963295227443043557 -66896648950445244523161731856403098711121722383113 -62229893423380308135336276614282806444486645238749 -30358907296290491560440772390713810515859307960866 -70172427121883998797908792274921901699720888093776 -65727333001053367881220235421809751254540594752243 -52584907711670556013604839586446706324415722155397 -53697817977846174064955149290862569321978468622482 -83972241375657056057490261407972968652414535100474 -82166370484403199890008895243450658541227588666881 -16427171479924442928230863465674813919123162824586 -17866458359124566529476545682848912883142607690042 -24219022671055626321111109370544217506941658960408 -07198403850962455444362981230987879927244284909188 -84580156166097919133875499200524063689912560717606 -05886116467109405077541002256983155200055935729725 -71636269561882670428252483600823257530420752963450 -"; - -fn method1(nums: &[u8; 1000]) -> u64 { - let mut product: u64; - let last_pos: usize = 1000 - 13; - let mut largest_product: u64 = 1; - for i in 0..last_pos { - product = 1; - for num in nums.iter().skip(i).take(13) { - product *= *num as u64; - if product > largest_product { - largest_product = product; - } - } - } - largest_product -} - -fn get_nums() -> [u8; 1000] { - let mut nums = [0_u8; 1000]; - let mut i = 0; - for c in NUMS.bytes() { - if c >= b'0' && c <= b'9' { - let num: u8 = c - b'0'; - nums[i] = num; - i += 1; - } - } - nums -} - -fn main() { - let nums = get_nums(); - println!("method1: {}", method1(&nums)); -} - -#[bench] -fn bench_method1(b: &mut test::Bencher) { - let nums = get_nums(); - b.iter(|| assert_eq!(method1(&nums), 23514624000)); -} diff --git a/project_euler/src/bin/euler_009.rs b/project_euler/src/bin/euler_009.rs deleted file mode 100644 index e1dbad76..00000000 --- a/project_euler/src/bin/euler_009.rs +++ /dev/null @@ -1,37 +0,0 @@ -// Copyright (c) 2020 Xu Shaohua . All rights reserved. -// Use of this source is governed by General Public License that can be found -// in the LICENSE file. - -#![feature(test)] -extern crate test; - -/// Problem: -/// -/// A Pythagorean triplet is a set of three natural numbers, a < b < c, for which, -/// a^2 + b^2 = c^2 -/// -/// For example, 3^2 + 4^2 = 9 + 16 = 2^5 = 52. -/// There exists exactly one Pythagorean triplet for which a + b + c = 1000. -/// Find the product abc. - -fn method1() -> u64 { - for c in 333..1000 { - for a in 1..c { - let b = 1000 - a - c; - if a * a + b * b == c * c { - println!(">: {}, {}, {}", a, b, c); - return a * b * c; - } - } - } - 0 -} - -fn main() { - println!("method1: {}", method1()); -} - -#[bench] -fn bench_method1(b: &mut test::Bencher) { - b.iter(|| assert_eq!(method1(), 31875000)); -} diff --git a/project_euler/src/bin/euler_010.rs b/project_euler/src/bin/euler_010.rs deleted file mode 100644 index d76525de..00000000 --- a/project_euler/src/bin/euler_010.rs +++ /dev/null @@ -1,26 +0,0 @@ -// Copyright (c) 2020 Xu Shaohua . All rights reserved. -// Use of this source is governed by General Public License that can be found -// in the LICENSE file. - -#![feature(test)] -extern crate euler; -extern crate test; - -/// Problem: -/// -/// The sum of the primes below 10 is 2 + 3 + 5 + 7 = 17. -/// Find the sum of all the primes below two million. - -fn method1() -> usize { - let primes = euler::primes::get_prime_list(2_000_000); - primes.iter().sum() -} - -fn main() { - println!("method1: {}", method1()); -} - -#[bench] -fn bench_method1(b: &mut test::Bencher) { - b.iter(|| assert_eq!(method1(), 142913828922)); -} diff --git a/project_euler/src/bin/euler_011.rs b/project_euler/src/bin/euler_011.rs deleted file mode 100644 index f861be53..00000000 --- a/project_euler/src/bin/euler_011.rs +++ /dev/null @@ -1,126 +0,0 @@ -// Copyright (c) 2020 Xu Shaohua . All rights reserved. -// Use of this source is governed by General Public License that can be found -// in the LICENSE file. - -#![feature(test)] -extern crate test; - -/// Problem: -/// -/// In the 20×20 grid below, four numbers along a diagonal line -/// have been marked in red. -/// -/// 08 02 22 97 38 15 00 40 00 75 04 05 07 78 52 12 50 77 91 08 -/// 49 49 99 40 17 81 18 57 60 87 17 40 98 43 69 48 04 56 62 00 -/// 81 49 31 73 55 79 14 29 93 71 40 67 53 88 30 03 49 13 36 65 -/// 52 70 95 23 04 60 11 42 69 24 68 56 01 32 56 71 37 02 36 91 -/// 22 31 16 71 51 67 63 89 41 92 36 54 22 40 40 28 66 33 13 80 -/// 24 47 32 60 99 03 45 02 44 75 33 53 78 36 84 20 35 17 12 50 -/// 32 98 81 28 64 23 67 10 26 38 40 67 59 54 70 66 18 38 64 70 -/// 67 26 20 68 02 62 12 20 95 63 94 39 63 08 40 91 66 49 94 21 -/// 24 55 58 05 66 73 99 26 97 17 78 78 96 83 14 88 34 89 63 72 -/// 21 36 23 09 75 00 76 44 20 45 35 14 00 61 33 97 34 31 33 95 -/// 78 17 53 28 22 75 31 67 15 94 03 80 04 62 16 14 09 53 56 92 -/// 16 39 05 42 96 35 31 47 55 58 88 24 00 17 54 24 36 29 85 57 -/// 86 56 00 48 35 71 89 07 05 44 44 37 44 60 21 58 51 54 17 58 -/// 19 80 81 68 05 94 47 69 28 73 92 13 86 52 17 77 04 89 55 40 -/// 04 52 08 83 97 35 99 16 07 97 57 32 16 26 26 79 33 27 98 66 -/// 88 36 68 87 57 62 20 72 03 46 33 67 46 55 12 32 63 93 53 69 -/// 04 42 16 73 38 25 39 11 24 94 72 18 08 46 29 32 40 62 76 36 -/// 20 69 36 41 72 30 23 88 34 62 99 69 82 67 59 85 74 04 36 16 -/// 20 73 35 29 78 31 90 01 74 31 49 71 48 86 81 16 23 57 05 54 -/// 01 70 54 71 83 51 54 69 16 92 33 48 61 43 52 01 89 19 67 48 -/// -/// The product of these numbers is 26 × 63 × 78 × 14 = 1788696. -/// -/// What is the greatest product of four adjacent numbers -/// in the same direction (up, down, left, right, or diagonally) -/// in the 20×20 grid? - -const MAX: usize = 400; -const NUMS: [u8; MAX] = [ - 8, 2, 22, 97, 38, 15, 0, 40, 0, 75, 4, 5, 7, 78, 52, 12, 50, 77, 91, 8, 49, 49, 99, 40, - 17, 81, 18, 57, 60, 87, 17, 40, 98, 43, 69, 48, 4, 56, 62, 0, 81, 49, 31, 73, 55, 79, 14, 29, - 93, 71, 40, 67, 53, 88, 30, 3, 49, 13, 36, 65, 52, 70, 95, 23, 4, 60, 11, 42, 69, 24, 68, 56, - 1, 32, 56, 71, 37, 2, 36, 91, 22, 31, 16, 71, 51, 67, 63, 89, 41, 92, 36, 54, 22, 40, 40, 28, - 66, 33, 13, 80, 24, 47, 32, 60, 99, 3, 45, 2, 44, 75, 33, 53, 78, 36, 84, 20, 35, 17, 12, 50, - 32, 98, 81, 28, 64, 23, 67, 10, 26, 38, 40, 67, 59, 54, 70, 66, 18, 38, 64, 70, 67, 26, 20, 68, - 2, 62, 12, 20, 95, 63, 94, 39, 63, 8, 40, 91, 66, 49, 94, 21, 24, 55, 58, 5, 66, 73, 99, 26, - 97, 17, 78, 78, 96, 83, 14, 88, 34, 89, 63, 72, 21, 36, 23, 9, 75, 0, 76, 44, 20, 45, 35, 14, - 0, 61, 33, 97, 34, 31, 33, 95, 78, 17, 53, 28, 22, 75, 31, 67, 15, 94, 3, 80, 4, 62, 16, 14, - 9, 53, 56, 92, 16, 39, 5, 42, 96, 35, 31, 47, 55, 58, 88, 24, 0, 17, 54, 24, 36, 29, 85, 57, - 86, 56, 0, 48, 35, 71, 89, 7, 5, 44, 44, 37, 44, 60, 21, 58, 51, 54, 17, 58, 19, 80, 81, 68, - 5, 94, 47, 69, 28, 73, 92, 13, 86, 52, 17, 77, 4, 89, 55, 40, 4, 52, 8, 83, 97, 35, 99, 16, - 7, 97, 57, 32, 16, 26, 26, 79, 33, 27, 98, 66, 88, 36, 68, 87, 57, 62, 20, 72, 3, 46, 33, 67, - 46, 55, 12, 32, 63, 93, 53, 69, 4, 42, 16, 73, 38, 25, 39, 11, 24, 94, 72, 18, 8, 46, 29, 32, - 40, 62, 76, 36, 20, 69, 36, 41, 72, 30, 23, 88, 34, 62, 99, 69, 82, 67, 59, 85, 74, 4, 36, 16, - 20, 73, 35, 29, 78, 31, 90, 1, 74, 31, 49, 71, 48, 86, 81, 16, 23, 57, 5, 54, 1, 70, 54, 71, - 83, 51, 54, 69, 16, 92, 33, 48, 61, 43, 52, 1, 89, 19, 67, 48, -]; - -fn method1() -> u64 { - let get_right_value = |n: usize| -> u64 { - let n1 = n + 1; - let n2 = n1 + 1; - let n3 = n2 + 1; - if n3 < MAX { - (NUMS[n] as u64) * (NUMS[n1] as u64) * (NUMS[n2] as u64) * (NUMS[n3] as u64) - } else { - 1 - } - }; - - let get_bottom_value = |n: usize| -> u64 { - let n1 = n + 20; - let n2 = n1 + 20; - let n3 = n2 + 20; - if n3 < MAX { - (NUMS[n] as u64) * (NUMS[n1] as u64) * (NUMS[n2] as u64) * (NUMS[n3] as u64) - } else { - 1 - } - }; - - let get_bottom_left = |n: usize| -> u64 { - let n1 = n + 19; - let n2 = n1 + 19; - let n3 = n2 + 19; - if n1 < MAX && n2 < MAX && n3 < MAX { - (NUMS[n] as u64) * (NUMS[n1] as u64) * (NUMS[n2] as u64) * (NUMS[n3] as u64) - } else { - 1 - } - }; - let get_bottom_right = |n: usize| -> u64 { - let n1 = n + 21; - let n2 = n1 + 21; - let n3 = n2 + 21; - if n1 < MAX && n2 < MAX && n3 < MAX { - (NUMS[n] as u64) * (NUMS[n1] as u64) * (NUMS[n2] as u64) * (NUMS[n3] as u64) - } else { - 1 - } - }; - - let mut largest_product: u64 = 1; - let mut product: u64; - for i in 0..MAX { - product = std::cmp::max(get_right_value(i), get_bottom_value(i)); - product = std::cmp::max(product, get_bottom_right(i)); - product = std::cmp::max(product, get_bottom_left(i)); - if product > largest_product { - println!("> {}", product); - largest_product = product; - } - } - largest_product -} - -fn main() { - println!("method1: {}", method1()); -} - -#[bench] -fn bench_method1(b: &mut test::Bencher) { - b.iter(|| assert_eq!(method1(), 70600674)); -} diff --git a/project_euler/src/bin/euler_012.rs b/project_euler/src/bin/euler_012.rs deleted file mode 100644 index 1d958412..00000000 --- a/project_euler/src/bin/euler_012.rs +++ /dev/null @@ -1,90 +0,0 @@ -// Copyright (c) 2020 Xu Shaohua . All rights reserved. -// Use of this source is governed by General Public License that can be found -// in the LICENSE file. - -#![feature(test)] -extern crate test; - -/// Problem: -/// -/// The sequence of triangle numbers is generated by adding the natural numbers. -/// So the 7th triangle number would be 1 + 2 + 3 + 4 + 5 + 6 + 7 = 28. -/// The first ten terms would be: -/// 1, 3, 6, 10, 15, 21, 28, 36, 45, 55, ... -/// Let us list the factors of the first seven triangle numbers: -/// 1: 1 -/// 3: 1,3 -/// 6: 1,2,3,6 -/// 10: 1,2,5,10 -/// 15: 1,3,5,15 -/// 21: 1,3,7,21 -/// 28: 1,2,4,7,14,28 -/// We can see that 28 is the first triangle number to have over five divisors. -/// What is the value of the first triangle number to have over -/// five hundred divisors? - -fn get_num_factors(n: usize, primes: &[usize]) -> u16 { - let prime_factors = euler::primes::get_prime_factors(n, primes); - let mut num_factors = 1; - for factor in &prime_factors { - num_factors *= factor.count + 1; - } - - num_factors -} - -/// Ref: -/// * https://www.allmathtricks.com/factors-number/ -fn method1() -> usize { - //let f(n) = n * (n + 1) / 2; - let mut s = 0; - let primes = euler::primes::get_prime_list(100_000); - for i in 1.. { - s += i; - let num_factors = get_num_factors(s, &primes); - if num_factors > 500 { - return s; - } - } - 0 -} - -fn factor(num: u32) -> u32 { - let mut buffer = 0; - - let mut i = 1; - while i * i < num { - if num % i == 0 { - buffer += 1; - } - i += 1; - } - buffer * 2 -} - -fn method2() -> u32 { - let mut trinum = 0; - for i in 1.. { - trinum += i; - if factor(trinum) >= 500 { - break; - } - } - - trinum -} - -fn main() { - println!("method1: {}", method1()); - println!("method2: {}", method2()); -} - -#[bench] -fn bench_method1(b: &mut test::Bencher) { - b.iter(|| assert_eq!(method1(), 76576500)); -} - -#[bench] -fn bench_method2(b: &mut test::Bencher) { - b.iter(|| assert_eq!(method2(), 76576500)); -} diff --git a/project_euler/src/bin/euler_013.rs b/project_euler/src/bin/euler_013.rs deleted file mode 100644 index 4bad5f60..00000000 --- a/project_euler/src/bin/euler_013.rs +++ /dev/null @@ -1,315 +0,0 @@ -// Copyright (c) 2020 Xu Shaohua . All rights reserved. -// Use of this source is governed by General Public License that can be found -// in the LICENSE file. - -#![feature(test)] -extern crate test; - -/// Problem: -/// -/// Work out the first ten digits of the sum of the following one-hundred -/// 50-digit numbers. -/// -/// 37107287533902102798797998220837590246510135740250 -/// 46376937677490009712648124896970078050417018260538 -/// 74324986199524741059474233309513058123726617309629 -/// 91942213363574161572522430563301811072406154908250 -/// 23067588207539346171171980310421047513778063246676 -/// 89261670696623633820136378418383684178734361726757 -/// 28112879812849979408065481931592621691275889832738 -/// 44274228917432520321923589422876796487670272189318 -/// 47451445736001306439091167216856844588711603153276 -/// 70386486105843025439939619828917593665686757934951 -/// 62176457141856560629502157223196586755079324193331 -/// 64906352462741904929101432445813822663347944758178 -/// 92575867718337217661963751590579239728245598838407 -/// 58203565325359399008402633568948830189458628227828 -/// 80181199384826282014278194139940567587151170094390 -/// 35398664372827112653829987240784473053190104293586 -/// 86515506006295864861532075273371959191420517255829 -/// 71693888707715466499115593487603532921714970056938 -/// 54370070576826684624621495650076471787294438377604 -/// 53282654108756828443191190634694037855217779295145 -/// 36123272525000296071075082563815656710885258350721 -/// 45876576172410976447339110607218265236877223636045 -/// 17423706905851860660448207621209813287860733969412 -/// 81142660418086830619328460811191061556940512689692 -/// 51934325451728388641918047049293215058642563049483 -/// 62467221648435076201727918039944693004732956340691 -/// 15732444386908125794514089057706229429197107928209 -/// 55037687525678773091862540744969844508330393682126 -/// 18336384825330154686196124348767681297534375946515 -/// 80386287592878490201521685554828717201219257766954 -/// 78182833757993103614740356856449095527097864797581 -/// 16726320100436897842553539920931837441497806860984 -/// 48403098129077791799088218795327364475675590848030 -/// 87086987551392711854517078544161852424320693150332 -/// 59959406895756536782107074926966537676326235447210 -/// 69793950679652694742597709739166693763042633987085 -/// 41052684708299085211399427365734116182760315001271 -/// 65378607361501080857009149939512557028198746004375 -/// 35829035317434717326932123578154982629742552737307 -/// 94953759765105305946966067683156574377167401875275 -/// 88902802571733229619176668713819931811048770190271 -/// 25267680276078003013678680992525463401061632866526 -/// 36270218540497705585629946580636237993140746255962 -/// 24074486908231174977792365466257246923322810917141 -/// 91430288197103288597806669760892938638285025333403 -/// 34413065578016127815921815005561868836468420090470 -/// 23053081172816430487623791969842487255036638784583 -/// 11487696932154902810424020138335124462181441773470 -/// 63783299490636259666498587618221225225512486764533 -/// 67720186971698544312419572409913959008952310058822 -/// 95548255300263520781532296796249481641953868218774 -/// 76085327132285723110424803456124867697064507995236 -/// 37774242535411291684276865538926205024910326572967 -/// 23701913275725675285653248258265463092207058596522 -/// 29798860272258331913126375147341994889534765745501 -/// 18495701454879288984856827726077713721403798879715 -/// 38298203783031473527721580348144513491373226651381 -/// 34829543829199918180278916522431027392251122869539 -/// 40957953066405232632538044100059654939159879593635 -/// 29746152185502371307642255121183693803580388584903 -/// 41698116222072977186158236678424689157993532961922 -/// 62467957194401269043877107275048102390895523597457 -/// 23189706772547915061505504953922979530901129967519 -/// 86188088225875314529584099251203829009407770775672 -/// 11306739708304724483816533873502340845647058077308 -/// 82959174767140363198008187129011875491310547126581 -/// 97623331044818386269515456334926366572897563400500 -/// 42846280183517070527831839425882145521227251250327 -/// 55121603546981200581762165212827652751691296897789 -/// 32238195734329339946437501907836945765883352399886 -/// 75506164965184775180738168837861091527357929701337 -/// 62177842752192623401942399639168044983993173312731 -/// 32924185707147349566916674687634660915035914677504 -/// 99518671430235219628894890102423325116913619626622 -/// 73267460800591547471830798392868535206946944540724 -/// 76841822524674417161514036427982273348055556214818 -/// 97142617910342598647204516893989422179826088076852 -/// 87783646182799346313767754307809363333018982642090 -/// 10848802521674670883215120185883543223812876952786 -/// 71329612474782464538636993009049310363619763878039 -/// 62184073572399794223406235393808339651327408011116 -/// 66627891981488087797941876876144230030984490851411 -/// 60661826293682836764744779239180335110989069790714 -/// 85786944089552990653640447425576083659976645795096 -/// 66024396409905389607120198219976047599490197230297 -/// 64913982680032973156037120041377903785566085089252 -/// 16730939319872750275468906903707539413042652315011 -/// 94809377245048795150954100921645863754710598436791 -/// 78639167021187492431995700641917969777599028300699 -/// 15368713711936614952811305876380278410754449733078 -/// 40789923115535562561142322423255033685442488917353 -/// 44889911501440648020369068063960672322193204149535 -/// 41503128880339536053299340368006977710650566631954 -/// 81234880673210146739058568557934581403627822703280 -/// 82616570773948327592232845941706525094512325230608 -/// 22918802058777319719839450180888072429661980811197 -/// 77158542502016545090413245809786882778948721859617 -/// 72107838435069186155435662884062257473692284509516 -/// 20849603980134001723930671666823555245252804609722 -/// 53503534226472524250874054075591789781264330331690 - -const NUMS: [&str; 100] = [ - "37107287533902102798797998220837590246510135740250", - "46376937677490009712648124896970078050417018260538", - "74324986199524741059474233309513058123726617309629", - "91942213363574161572522430563301811072406154908250", - "23067588207539346171171980310421047513778063246676", - "89261670696623633820136378418383684178734361726757", - "28112879812849979408065481931592621691275889832738", - "44274228917432520321923589422876796487670272189318", - "47451445736001306439091167216856844588711603153276", - "70386486105843025439939619828917593665686757934951", - "62176457141856560629502157223196586755079324193331", - "64906352462741904929101432445813822663347944758178", - "92575867718337217661963751590579239728245598838407", - "58203565325359399008402633568948830189458628227828", - "80181199384826282014278194139940567587151170094390", - "35398664372827112653829987240784473053190104293586", - "86515506006295864861532075273371959191420517255829", - "71693888707715466499115593487603532921714970056938", - "54370070576826684624621495650076471787294438377604", - "53282654108756828443191190634694037855217779295145", - "36123272525000296071075082563815656710885258350721", - "45876576172410976447339110607218265236877223636045", - "17423706905851860660448207621209813287860733969412", - "81142660418086830619328460811191061556940512689692", - "51934325451728388641918047049293215058642563049483", - "62467221648435076201727918039944693004732956340691", - "15732444386908125794514089057706229429197107928209", - "55037687525678773091862540744969844508330393682126", - "18336384825330154686196124348767681297534375946515", - "80386287592878490201521685554828717201219257766954", - "78182833757993103614740356856449095527097864797581", - "16726320100436897842553539920931837441497806860984", - "48403098129077791799088218795327364475675590848030", - "87086987551392711854517078544161852424320693150332", - "59959406895756536782107074926966537676326235447210", - "69793950679652694742597709739166693763042633987085", - "41052684708299085211399427365734116182760315001271", - "65378607361501080857009149939512557028198746004375", - "35829035317434717326932123578154982629742552737307", - "94953759765105305946966067683156574377167401875275", - "88902802571733229619176668713819931811048770190271", - "25267680276078003013678680992525463401061632866526", - "36270218540497705585629946580636237993140746255962", - "24074486908231174977792365466257246923322810917141", - "91430288197103288597806669760892938638285025333403", - "34413065578016127815921815005561868836468420090470", - "23053081172816430487623791969842487255036638784583", - "11487696932154902810424020138335124462181441773470", - "63783299490636259666498587618221225225512486764533", - "67720186971698544312419572409913959008952310058822", - "95548255300263520781532296796249481641953868218774", - "76085327132285723110424803456124867697064507995236", - "37774242535411291684276865538926205024910326572967", - "23701913275725675285653248258265463092207058596522", - "29798860272258331913126375147341994889534765745501", - "18495701454879288984856827726077713721403798879715", - "38298203783031473527721580348144513491373226651381", - "34829543829199918180278916522431027392251122869539", - "40957953066405232632538044100059654939159879593635", - "29746152185502371307642255121183693803580388584903", - "41698116222072977186158236678424689157993532961922", - "62467957194401269043877107275048102390895523597457", - "23189706772547915061505504953922979530901129967519", - "86188088225875314529584099251203829009407770775672", - "11306739708304724483816533873502340845647058077308", - "82959174767140363198008187129011875491310547126581", - "97623331044818386269515456334926366572897563400500", - "42846280183517070527831839425882145521227251250327", - "55121603546981200581762165212827652751691296897789", - "32238195734329339946437501907836945765883352399886", - "75506164965184775180738168837861091527357929701337", - "62177842752192623401942399639168044983993173312731", - "32924185707147349566916674687634660915035914677504", - "99518671430235219628894890102423325116913619626622", - "73267460800591547471830798392868535206946944540724", - "76841822524674417161514036427982273348055556214818", - "97142617910342598647204516893989422179826088076852", - "87783646182799346313767754307809363333018982642090", - "10848802521674670883215120185883543223812876952786", - "71329612474782464538636993009049310363619763878039", - "62184073572399794223406235393808339651327408011116", - "66627891981488087797941876876144230030984490851411", - "60661826293682836764744779239180335110989069790714", - "85786944089552990653640447425576083659976645795096", - "66024396409905389607120198219976047599490197230297", - "64913982680032973156037120041377903785566085089252", - "16730939319872750275468906903707539413042652315011", - "94809377245048795150954100921645863754710598436791", - "78639167021187492431995700641917969777599028300699", - "15368713711936614952811305876380278410754449733078", - "40789923115535562561142322423255033685442488917353", - "44889911501440648020369068063960672322193204149535", - "41503128880339536053299340368006977710650566631954", - "81234880673210146739058568557934581403627822703280", - "82616570773948327592232845941706525094512325230608", - "22918802058777319719839450180888072429661980811197", - "77158542502016545090413245809786882778948721859617", - "72107838435069186155435662884062257473692284509516", - "20849603980134001723930671666823555245252804609722", - "53503534226472524250874054075591789781264330331690", -]; - -fn method1(nums: &[&str]) -> u64 { - let mut digits = Vec::new(); - let mut sum = 0; - for i in (0..50).rev() { - for num in nums { - if let Some(digit) = num.chars().nth(i) { - if let Some(digit) = digit.to_digit(10) { - sum += digit; - } - } - } - let remainder = sum % 10; - digits.push(remainder); - sum /= 10; - } - while sum > 0 { - let remainder = sum % 10; - digits.push(remainder); - sum /= 10; - } - - digits - .into_iter() - .rev() - .take(10) - .fold(0, |sum: u64, digit: u32| { - sum * 10 + digit as u64 - }) -} - -fn method2(nums: &[&str]) -> u64 { - let mut last_part: u128 = 0; - for num in nums { - let x: u128 = (&num[25..]).parse().expect("Failed to parse digits"); - last_part += x; - } - let mut first_part: u128 = 0; - for num in nums { - let x: u128 = (&num[..25]).parse().expect("Failed to parse digits"); - first_part += x; - } - let separator = 10_u128.pow(25); - first_part += last_part / (separator); - last_part %= separator; - (first_part.to_string() + &last_part.to_string())[..10].parse::().unwrap() -} - -fn method3(nums: &[&str]) -> u64 { - let mut digits = Vec::with_capacity(60); - let mut sum = 0; - for i in (0..50).rev() { - for num in nums { - let digit: u32 = num[i..i + 1].parse().expect("Failed to read digit"); - sum += digit; - } - let remainder = sum % 10; - digits.push(remainder); - sum /= 10; - } - while sum > 0 { - let remainder = sum % 10; - digits.push(remainder); - sum /= 10; - } - - digits - .into_iter() - .rev() - .take(10) - .fold(0, |sum: u64, digit: u32| { - sum * 10 + digit as u64 - }) -} - -fn main() { - println!("method1: {}", method1(&NUMS)); - println!("method2 = {}", method2(&NUMS)); - println!("method3 = {}", method3(&NUMS)); -} - -#[bench] -fn bench_method1(b: &mut test::Bencher) { - b.iter(|| assert_eq!(method1(&NUMS), 5537376230)); -} - -#[bench] -fn bench_method3(b: &mut test::Bencher) { - b.iter(|| assert_eq!(method3(&NUMS), 5537376230)); -} - -#[bench] -fn bench_method2(b: &mut test::Bencher) { - b.iter(|| assert_eq!(method2(&NUMS), 5537376230)); -} - -#[test] -fn test_method_eq() { - assert_eq!(method1(&NUMS), method2(&NUMS)); -} diff --git a/project_euler/src/bin/euler_014.rs b/project_euler/src/bin/euler_014.rs deleted file mode 100644 index c0ffe541..00000000 --- a/project_euler/src/bin/euler_014.rs +++ /dev/null @@ -1,104 +0,0 @@ -// Copyright (c) 2020 Xu Shaohua . All rights reserved. -// Use of this source is governed by General Public License that can be found -// in the LICENSE file. - -#![feature(test)] -extern crate test; - -/// Problem: -/// -/// The following iterative sequence is defined for the set of positive -/// integers: -/// -/// n → n/2 (n is even) -/// n → 3n + 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. - -fn method1() -> u32 { - let get_collatz_sequence = |n: u32| -> u32 { - let mut n: u64 = n as u64; - let mut seq = 0; - while n != 1 { - if n % 2 == 0 { - n /= 2; - } else { - n = 3 * n + 1; - } - seq += 1; - } - seq - }; - - let mut largest_sequence = 0; - let mut largest_sequence_num = 0; - for i in 1..=1_000_000 { - let seq = get_collatz_sequence(i); - if seq > largest_sequence { - largest_sequence_num = i; - largest_sequence = seq; - } - } - - largest_sequence_num -} - -fn method2() -> usize { - const MAX: usize = 1_000_000; - let cache: [u32; MAX + 1] = [0; MAX + 1]; - let get_collatz_sequence = |num: usize| -> u32 { - let mut n = num; - let mut seq = 0; - while n != 1 { - if n < num && cache[n] != 0 { - seq += cache[n]; - break; - } - if n % 2 == 0 { - n /= 2; - } else { - n = 3 * n + 1; - } - seq += 1; - } - seq - }; - - let mut largest_sequence = 0; - let mut largest_sequence_num = 0; - for i in 1..=MAX { - let seq = get_collatz_sequence(i); - if seq > largest_sequence { - largest_sequence_num = i; - largest_sequence = seq; - } - } - - largest_sequence_num -} - -fn main() { - println!("method1: {}", method1()); - println!("method2: {}", method2()); -} - -#[bench] -fn bench_method1(b: &mut test::Bencher) { - b.iter(|| assert_eq!(method1(), 837799)); -} - -#[bench] -fn bench_method2(_b: &mut test::Bencher) { - // FIXME(Shaohua): Stackoverflow - //b.iter(|| method2()); -} diff --git a/project_euler/src/bin/euler_016.rs b/project_euler/src/bin/euler_016.rs deleted file mode 100644 index f63cbe2d..00000000 --- a/project_euler/src/bin/euler_016.rs +++ /dev/null @@ -1,41 +0,0 @@ -// Copyright (c) 2020 Xu Shaohua . All rights reserved. -// Use of this source is governed by General Public License that can be found -// in the LICENSE file. - -#![feature(test)] -extern crate test; - -/// Problem: -/// -/// 2^15 = 32768 and the sum of its digits is 3 + 2 + 7 + 6 + 8 = 26. -/// What is the sum of the digits of the number 2^1000? - -fn method1() -> u32 { - const MAX: usize = 1000; - let mut digits: [u8; MAX] = [0; MAX]; - digits[0] = 1; - for _ in 0..MAX { - let mut quotient = 0; - for digit in digits.iter_mut().take(MAX) { - quotient += *digit * 2; - if quotient >= 10 { - *digit = quotient - 10; - quotient = 1; - } else { - *digit = quotient; - quotient = 0; - } - } - } - - digits.iter().map(|n| *n as u32).sum() -} - -fn main() { - println!("method1: {}", method1()); -} - -#[bench] -fn bench_method1(b: &mut test::Bencher) { - b.iter(|| assert_eq!(method1(), 1366)); -} diff --git a/project_euler/src/bin/euler_017.rs b/project_euler/src/bin/euler_017.rs deleted file mode 100644 index 54ccbf1c..00000000 --- a/project_euler/src/bin/euler_017.rs +++ /dev/null @@ -1,243 +0,0 @@ -// Copyright (c) 2020 Xu Shaohua . All rights reserved. -// Use of this source is governed by General Public License that can be found -// in the LICENSE file. - -#![feature(test)] -extern crate test; - -use std::collections::HashMap; - -/// Problem: -/// -/// If the numbers 1 to 5 are written out in words: one, two, three, four, -/// five, then there are 3 + 3 + 5 + 4 + 4 = 19 letters used in total. -/// If all the numbers from 1 to 1000 (one thousand) inclusive were -/// written out in words, how many letters would be used? -/// -/// NOTE: Do not count spaces or hyphens. For example, 342 -/// (three hundred and forty-two) contains 23 letters and -/// 115 (one hundred and fifteen) contains 20 letters. The use of "and" -/// when writing out numbers is in compliance with British usage. - -const LETTERS: [(u32, &str); 27] = [ - (1, "one"), - (2, "two"), - (3, "three"), - (4, "four"), - (5, "five"), - (6, "six"), - (7, "seven"), - (8, "eight"), - (9, "nine"), - (10, "ten"), - (11, "eleven"), - (12, "twelve"), - (13, "thirteen"), - (14, "fourteen"), - (15, "fifteen"), - (16, "sixteen"), - (17, "seventeen"), - (18, "eighteen"), - (19, "nineteen"), - (20, "twenty"), - (30, "thirty"), - (40, "forty"), - (50, "fifty"), - (60, "sixty"), - (70, "seventy"), - (80, "eighty"), - (90, "ninety"), -]; - -fn method1() -> usize { - let mut letters = HashMap::new(); - for letter in &LETTERS { - letters.insert(letter.0, letter.1.to_string()); - } - - let get_letters = |num: u32| -> usize { - let mut sum = Vec::new(); - let mut n = num; - if n >= 1000 { - let quotient = n / 1000; - n %= 1000; - if let Some(l) = letters.get("ient) { - sum.push(l.clone()); - } else { - panic!("letters not contain: {}", quotient); - } - sum.push("thousand".to_string()); - } - if n >= 100 { - let quotient = n / 100; - n %= 100; - - if let Some(l) = letters.get("ient) { - sum.push(l.clone()); - } else { - panic!("letters not contain: {}", quotient); - } - sum.push("hundred".to_string()); - if n > 0 { - sum.push("and".to_string()); - } - } - if n >= 20 { - let quotient = n / 10 * 10; - if let Some(l) = letters.get("ient) { - sum.push(l.clone()); - } else { - panic!("letters not contain: {}", quotient); - } - n %= 10; - } else if n >= 10 { - if let Some(l) = letters.get(&n) { - sum.push(l.clone()); - } else { - panic!("letters not contain: {}", n); - } - } - - if n > 0 && n < 10 { - if let Some(l) = letters.get(&n) { - sum.push(l.clone()); - } else { - panic!("letters not contain: {}", n); - } - } - - sum.iter().map(|word| word.len()).sum() - }; - - (1..=1000).map(get_letters).sum() -} - -fn method2() -> usize { - let mut letters = HashMap::new(); - for letter in &LETTERS { - letters.insert(letter.0, letter.1.len()); - } - - let get_letters = |num: u32| -> usize { - let mut sum = 0; - let mut n = num; - if n >= 1000 { - let quotient = n / 1000; - n %= 1000; - if let Some(l) = letters.get("ient) { - sum += l; - } else { - panic!("letters not contain: {}", quotient); - } - sum += "thousand".len(); - } - if n >= 100 { - let quotient = n / 100; - n %= 100; - - if let Some(l) = letters.get("ient) { - sum += l; - } else { - panic!("letters not contain: {}", quotient); - } - sum += "hundred".len(); - if n > 0 { - sum += "and".len(); - } - } - if n >= 20 { - let quotient = n / 10 * 10; - if let Some(l) = letters.get("ient) { - sum += l; - } else { - panic!("letters not contain: {}", quotient); - } - n %= 10; - } else if n >= 10 { - if let Some(l) = letters.get(&n) { - sum += l; - } else { - panic!("letters not contain: {}", n); - } - } - - if n > 0 && n < 10 { - if let Some(l) = letters.get(&n) { - sum += l; - } else { - panic!("letters not contain: {}", n); - } - } - sum - }; - - (1..=1000).map(get_letters).sum() -} - -fn method3() -> usize { - let mut letters = HashMap::new(); - for letter in &LETTERS { - letters.insert(letter.0, letter.1.len()); - } - - let get_letters = |num: u32| -> usize { - let mut sum = 0; - let mut n = num; - let mut quotient; - if n >= 1000 { - quotient = n / 1000; - sum += letters["ient]; - sum += "thousand".len(); - n %= 1000; - } - if n >= 100 { - quotient = n / 100; - sum += letters["ient]; - sum += "hundred".len(); - - n %= 100; - if n > 0 { - sum += "and".len(); - } - } - if n >= 20 { - quotient = n / 10 * 10; - sum += letters["ient]; - n %= 10; - } else if n >= 10 { - sum += letters[&n]; - } - - if n > 0 && n < 10 { - sum += letters[&n]; - } - sum - }; - - let mut sum = 0; - for i in 1..=1000 { - sum += get_letters(i); - } - sum -} - -fn main() { - println!("method1: {}", method1()); - println!("method2: {}", method2()); - println!("method3: {}", method3()); -} - -#[bench] -fn bench_method1(b: &mut test::Bencher) { - b.iter(|| assert_eq!(method1(), 21124)); -} - -#[bench] -fn bench_method2(b: &mut test::Bencher) { - b.iter(|| assert_eq!(method2(), 21124)); -} - -#[bench] -fn bench_method3(b: &mut test::Bencher) { - b.iter(|| assert_eq!(method3(), 21124)); -} diff --git a/project_euler/src/bin/euler_018.rs b/project_euler/src/bin/euler_018.rs deleted file mode 100644 index 229dbd64..00000000 --- a/project_euler/src/bin/euler_018.rs +++ /dev/null @@ -1,52 +0,0 @@ -// Copyright (c) 2020 Xu Shaohua . All rights reserved. -// Use of this source is governed by General Public License that can be found -// in the LICENSE file. - -#![feature(test)] -extern crate test; - -/// Problem: -/// -/// By starting at the top of the triangle below and moving to adjacent -/// numbers on the row below, the maximum total from top to bottom is 23. -/// 3 -/// 7 4 -/// 2 4 6 -/// 8 5 9 3 -/// -/// That is, 3 + 7 + 4 + 9 = 23. -/// Find the maximum total from top to bottom of the triangle below: -/// -/// 75 -/// 95 64 -/// 17 47 82 -/// 18 35 87 10 -/// 20 04 82 47 65 -/// 19 01 23 75 03 34 -/// 88 02 77 73 07 63 67 -/// 99 65 04 28 06 16 70 92 -/// 41 41 26 56 83 40 80 70 33 -/// 41 48 72 33 47 32 37 16 94 29 -/// 53 71 44 65 25 43 91 52 97 51 14 -/// 70 11 33 28 77 73 17 78 39 68 17 57 -/// 91 71 52 38 17 14 91 43 58 50 27 29 48 -/// 63 66 04 68 89 53 67 30 73 16 69 87 40 31 -/// 04 62 98 27 23 09 70 98 73 93 38 53 60 04 23 -/// -/// NOTE: As there are only 16384 routes, it is possible to solve this problem -/// by trying every route. However, Problem 67, is the same challenge with -/// a triangle containing one-hundred rows; it cannot be solved by brute force, -/// and requires a clever method! ;o) - -fn method1() -> u64 { - 0 -} - -fn main() { - println!("method1: {}", method1()); -} - -#[bench] -fn bench_method1(b: &mut test::Bencher) { - b.iter(|| method1()); -} diff --git a/project_euler/src/bin/euler_019.rs b/project_euler/src/bin/euler_019.rs deleted file mode 100644 index 1a561256..00000000 --- a/project_euler/src/bin/euler_019.rs +++ /dev/null @@ -1,89 +0,0 @@ -// Copyright (c) 2020 Xu Shaohua . All rights reserved. -// Use of this source is governed by General Public License that can be found -// in the LICENSE file. - -#![feature(test)] -extern crate test; - -/// Problem: -/// -/// You are given the following information, but you may prefer to do -/// some research for yourself. -/// -/// * 1 Jan 1900 was a Monday. -/// * Thirty days has September, -/// April, June and November. -/// All the rest have thirty-one, -/// Saving February alone, -/// Which has twenty-eight, rain or shine. -/// And on leap years, twenty-nine. -/// * A leap year occurs on any year evenly divisible by 4, but not on -/// a century unless it is divisible by 400. -/// -/// How many Sundays fell on the first of the month during the twentieth -/// century (1 Jan 1901 to 31 Dec 2000)? - -type Year = u32; -type Month = u8; -type Day = u8; - -fn method1() -> u64 { - const MONTH_DAYS: [Month; 12] = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]; - - let check_leap_year = |year: Year| year % 400 == 0 || (year % 4 == 0 && year % 100 != 0); - - let mut year: Year = 1900; - let mut month: Month = 0; // January - let mut day: Day = 1; // zero-day - let mut weekday: u8 = 1; // Monday - let mut is_leap_year = check_leap_year(year); - let mut month_days = MONTH_DAYS[month as usize]; - - let mut count = 0; - - loop { - if weekday == 7 && day == 1 && year > 1900 { - count += 1; - } - - day += 1; - weekday %= 7; - weekday += 1; - - if month_days < day { - // goto next month. - day = 1; - month += 1; - } - - if month == 12 { - day = 1; - month = 0; - year += 1; - is_leap_year = check_leap_year(year); - } - - if day == 1 { - month_days = MONTH_DAYS[month as usize]; - // Handle leap years. - if month == 1 && is_leap_year { - month_days += 1; - } - } - - if year == 2001 { - break; - } - } - - count -} - -fn main() { - println!("method1: {}", method1()); -} - -#[bench] -fn bench_method1(b: &mut test::Bencher) { - b.iter(|| assert_eq!(method1(), 171)); -} diff --git a/project_euler/src/bin/euler_020.rs b/project_euler/src/bin/euler_020.rs deleted file mode 100644 index 094346ed..00000000 --- a/project_euler/src/bin/euler_020.rs +++ /dev/null @@ -1,41 +0,0 @@ -// Copyright (c) 2020 Xu Shaohua . All rights reserved. -// Use of this source is governed by General Public License that can be found -// in the LICENSE file. - -#![feature(test)] -extern crate test; - -/// Problem: -/// -/// n! means n × (n − 1) × ... × 3 × 2 × 1 -/// -/// For example, 10! = 10 × 9 × ... × 3 × 2 × 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 method1() -> u16 { - const MAX: usize = 1024; - let mut digits: [u16; MAX] = [0; MAX]; - digits[0] = 1; - for i in 1..=100 { - let mut quotient = 0; - for j in 0..MAX { - quotient += digits[j] * i; - digits[j] = quotient % 10; - quotient /= 10; - } - } - - digits.iter().sum() -} - -fn main() { - println!("method1: {}", method1()); -} - -#[bench] -fn bench_method1(b: &mut test::Bencher) { - b.iter(|| assert_eq!(method1(), 648)); -} diff --git a/project_euler/src/bin/euler_021.rs b/project_euler/src/bin/euler_021.rs deleted file mode 100644 index 13df0435..00000000 --- a/project_euler/src/bin/euler_021.rs +++ /dev/null @@ -1,50 +0,0 @@ -// Copyright (c) 2020 Xu Shaohua . All rights reserved. -// Use of this source is governed by General Public License that can be found -// in the LICENSE file. - -#![feature(test)] -extern crate test; - -use euler::primes::GetFactors; - -/// Problem: -/// -/// Let d(n) be defined as the sum of proper divisors of n (numbers less than -/// n which divide evenly into n). -/// If d(a) = b and d(b) = a, where a ≠ b, then a and b are an amicable pair -/// and each of a and b are called amicable numbers. -/// -/// For example, the proper divisors of 220 are 1, 2, 4, 5, 10, 11, 20, 22, -/// 44, 55 and 110; therefore d(220) = 284. The proper divisors of 284 -/// are 1, 2, 4, 71 and 142; so d(284) = 220. -/// -/// Evaluate the sum of all the amicable numbers under 10000. - -fn method1() -> usize { - const MAX: usize = 10_000; - - let mut divisors: [usize; MAX + 1] = [0; MAX + 1]; - - for i in 2..=MAX { - let divisor = i.get_factors().iter().sum(); - divisors[i] = divisor; - } - - let mut sum = 0; - for (index, divisor) in divisors.iter().enumerate() { - if index != *divisor && divisor <= &MAX && divisors[*divisor] == index { - sum += index; - } - } - - sum -} - -fn main() { - println!("method1: {}", method1()); -} - -#[bench] -fn bench_method1(b: &mut test::Bencher) { - b.iter(|| assert_eq!(method1(), 31626)); -} diff --git a/project_euler/src/bin/euler_022.rs b/project_euler/src/bin/euler_022.rs deleted file mode 100644 index d0f74c41..00000000 --- a/project_euler/src/bin/euler_022.rs +++ /dev/null @@ -1,63 +0,0 @@ -// Copyright (c) 2020 Xu Shaohua . All rights reserved. -// Use of this source is governed by General Public License that can be found -// in the LICENSE file. - -#![feature(test)] -extern crate test; - -use std::fs::File; -use std::io::{BufReader, Read}; - -/// Problem: -/// -/// Using names.txt (right click and 'Save Link/Target As...'), a 46K -/// text file containing over five-thousand first names, begin by sorting it -/// into alphabetical order. Then working out the alphabetical value for -/// each name, multiply this value by its alphabetical position in the list -/// to obtain a name score. -/// -/// For example, when the list is sorted into alphabetical order, COLIN, -/// which is worth 3 + 15 + 12 + 9 + 14 = 53, is the 938th name in the list. -/// So, COLIN would obtain a score of 938 × 53 = 49714. -/// -/// What is the total of all the name scores in the file? - -fn method1(words: &[String]) -> u64 { - let mut scores = 0; - for (index, word) in words.iter().enumerate() { - let word_score: u64 = word - .bytes() - .filter(|c| c != &b'"') - .map(|c| (c - b'A' + 1) as u64) - .sum(); - - scores += (index as u64 + 1) * word_score; - } - scores -} - -fn read_file() -> Option> { - if let Some(file_path) = std::env::args_os().nth(1) { - let file = File::open(file_path).unwrap(); - let mut buffer = BufReader::new(file); - let mut content = String::new(); - buffer.read_to_string(&mut content).unwrap(); - let mut words: Vec = content.split(',').map(|s| s.to_string()).collect(); - words.sort(); - Some(words) - } else { - eprintln!("Usage: {} file_path", std::env::args().next().unwrap()); - None - } -} - -fn main() { - let words = read_file().unwrap(); - println!("method1: {}", method1(words.as_ref())); -} - -#[bench] -fn bench_method1(_b: &mut test::Bencher) { - // let words = read_file().unwrap(); - // b.iter(|| method1(words.as_ref())); -} diff --git a/project_euler/src/bin/euler_023.rs b/project_euler/src/bin/euler_023.rs deleted file mode 100644 index bbc93c54..00000000 --- a/project_euler/src/bin/euler_023.rs +++ /dev/null @@ -1,72 +0,0 @@ -// Copyright (c) 2020 Xu Shaohua . All rights reserved. -// Use of this source is governed by General Public License that can be found -// in the LICENSE file. - -#![feature(test)] -extern crate test; - -use euler::primes::GetFactors; - -/// Problem: -/// -/// A perfect number is a number for which the sum of its proper divisors -/// is exactly equal to the number. For example, the sum of the proper divisors -/// of 28 would be 1 + 2 + 4 + 7 + 14 = 28, which means that 28 is a perfect -/// number. -/// -/// A number n is called deficient if the sum of its proper divisors is -/// less than n and it is called abundant if this sum exceeds n. -/// -/// As 12 is the smallest abundant number, 1 + 2 + 3 + 4 + 6 = 16, the smallest -/// number that can be written as the sum of two abundant numbers is 24. -/// By mathematical analysis, it can be shown that all integers greater than -/// 28123 can be written as the sum of two abundant numbers. However, -/// this upper limit cannot be reduced any further by analysis even though -/// it is known that the greatest number that cannot be expressed as the sum -/// of two abundant numbers is less than this limit. -/// -/// Find the sum of all the positive integers which cannot be written as -/// the sum of two abundant numbers. - -fn method1() -> u32 { - // TODO(Shaohua): Tuning method1 - let max = 28123; - let mut buf = Vec::new(); - let abundant_nums: Vec = (2_u32..max) - .filter(|i| { - i.get_factors_cache(&mut buf); - let sum: u32 = buf.iter().sum(); - &sum > i - }) - .collect(); - - let mut sum = 0; - for i in 1..=max { - let half = i / 2 + 1; - let mut exists = false; - for j in &abundant_nums { - if j > &half { - break; - } - let d = i - j; - if abundant_nums.binary_search(&d).is_ok() { - exists = true; - break; - } - } - if !exists { - sum += i; - } - } - - sum -} - -fn main() { - println!("method1: {}", method1()); -} - -#[bench] -fn bench_method1(b: &mut test::Bencher) { - b.iter(|| assert_eq!(method1(), 4179871)); -} diff --git a/project_euler/src/bin/euler_024.rs b/project_euler/src/bin/euler_024.rs deleted file mode 100644 index 8a990a8c..00000000 --- a/project_euler/src/bin/euler_024.rs +++ /dev/null @@ -1,33 +0,0 @@ -// Copyright (c) 2020 Xu Shaohua . All rights reserved. -// Use of this source is governed by General Public License that can be found -// in the LICENSE file. - -#![feature(test)] -extern crate test; - -/// Problem: -/// -/// A permutation is an ordered arrangement of objects. For example, -/// 3124 is one possible permutation of the digits 1, 2, 3 and 4. -/// If all of the permutations are listed numerically or alphabetically, -/// we call it lexicographic order. The lexicographic permutations of -/// 0, 1 and 2 are: -/// -/// 012 021 102 120 201 210 -/// -/// What is the millionth lexicographic permutation of the digits -/// 0, 1, 2, 3, 4, 5, 6, 7, 8 and 9? - -fn method1() -> u64 { - // FIXME(Shaohua): Move example code to here - 2783915460 -} - -fn main() { - println!("method1: {}", method1()); -} - -#[bench] -fn bench_method1(b: &mut test::Bencher) { - b.iter(|| assert_eq!(method1(), 2783915460)); -} diff --git a/project_euler/src/bin/euler_025.rs b/project_euler/src/bin/euler_025.rs deleted file mode 100644 index 2fbdab29..00000000 --- a/project_euler/src/bin/euler_025.rs +++ /dev/null @@ -1,163 +0,0 @@ -// Copyright (c) 2020 Xu Shaohua . All rights reserved. -// Use of this source is governed by General Public License that can be found -// in the LICENSE file. - -#![feature(test)] -extern crate test; - -/// Problem: -/// -/// The Fibonacci sequence is defined by the recurrence relation: -/// Fn = F_(n−1) + F_(n−2), where F1 = 1 and F2 = 1. -/// Hence the first 12 terms will be: -/// F1 = 1 -/// F2 = 1 -/// F3 = 2 -/// F4 = 3 -/// F5 = 5 -/// F6 = 8 -/// F7 = 13 -/// F8 = 21 -/// F9 = 34 -/// F10 = 55 -/// F11 = 89 -/// F12 = 144 -/// The 12th term, F12, is the first term to contain three digits. -/// What is the index of the first term in the Fibonacci sequence to -/// contain 1000 digits? - -fn method1() -> u32 { - const MAX_NUM: usize = 1000; - let mut a: Vec = Vec::with_capacity(MAX_NUM); - let mut b: Vec = Vec::with_capacity(MAX_NUM); - let mut digits = 1; - a.push(1); - b.push(1); - let mut index = 2; - loop { - index += 1; - let mut sum = 0; - let mut add_digit = false; - for digit in 0..digits { - sum += a[digit] + b[digit]; - a[digit] = b[digit]; - if sum > 9 { - b[digit] = sum - 10; - sum = 1; - add_digit = true; - } else { - b[digit] = sum; - sum = 0; - add_digit = false; - } - } - if add_digit { - b.push(1); - a.push(0); - digits += 1; - } - if (digits + 1) > MAX_NUM { - break; - } - } - index -} - -fn method2() -> u32 { - const MAX_NUM: usize = 1000; - let mut a: Vec = Vec::with_capacity(MAX_NUM + 1); - let mut b: Vec = Vec::with_capacity(MAX_NUM + 1); - for _i in 0..MAX_NUM { - a.push(0); - b.push(0); - } - let mut digits = 1; - a[0] = 1; - b[0] = 1; - let mut index = 2; - loop { - index += 1; - let mut sum = 0; - let mut add_digit = false; - for digit in 0..digits { - sum += a[digit] + b[digit]; - a[digit] = b[digit]; - if sum > 9 { - b[digit] = sum - 10; - sum = 1; - add_digit = true; - } else { - b[digit] = sum; - sum = 0; - add_digit = false; - } - } - if add_digit { - b[digits] = 1; - digits += 1; - } - if (digits + 1) > MAX_NUM { - break; - } - } - index -} - -fn method3() -> u32 { - const MAX_NUM: usize = 1000; - let mut a: [u8; MAX_NUM] = [0; MAX_NUM]; - let mut b: [u8; MAX_NUM] = [0; MAX_NUM]; - let mut digits = 1; - a[0] = 1; - b[0] = 1; - - let mut index = 2; - let mut sum; - loop { - index += 1; - sum = 0; - let mut add_digit = false; - for digit in 0..digits { - sum += a[digit] + b[digit]; - a[digit] = b[digit]; - if sum > 9 { - b[digit] = sum - 10; - sum = 1; - add_digit = true; - } else { - b[digit] = sum; - sum = 0; - add_digit = false; - } - } - if add_digit { - b[digits] = 1; - digits += 1; - } - if (digits + 1) > MAX_NUM { - break; - } - } - index -} - -fn main() { - println!("method1: {}", method1()); - println!("method2: {}", method2()); - println!("method3: {}", method3()); -} - -#[bench] -fn bench_method1(b: &mut test::Bencher) { - b.iter(|| assert_eq!(method1(), 4782)); -} - -#[bench] -fn bench_method2(b: &mut test::Bencher) { - b.iter(|| assert_eq!(method2(), 4782)); -} - -#[bench] -fn bench_method3(b: &mut test::Bencher) { - b.iter(|| assert_eq!(method3(), 4782)); -} diff --git a/project_euler/src/bin/euler_026.rs b/project_euler/src/bin/euler_026.rs deleted file mode 100644 index d1783e68..00000000 --- a/project_euler/src/bin/euler_026.rs +++ /dev/null @@ -1,70 +0,0 @@ -// Copyright (c) 2020 Xu Shaohua . All rights reserved. -// Use of this source is governed by General Public License that can be found -// in the LICENSE file. - -#![feature(test)] -extern crate test; - -/// Problem: -/// -/// A unit fraction contains 1 in the numerator. The decimal -/// representation of the unit fractions with denominators 2 to 10 -/// are given: -/// -/// 1/2 = 0.5 -/// 1/3 = 0.(3) -/// 1/4 = 0.25 -/// 1/5 = 0.2 -/// 1/6 = 0.1(6) -/// 1/7 = 0.(142857) -/// 1/8 = 0.125 -/// 1/9 = 0.(1) -/// 1/10 = 0.1 -/// -/// Where 0.1(6) means 0.166666..., and has a 1-digit recurring cycle. -/// It can be seen that 1/7 has a 6-digit recurring cycle. -/// -/// Find the value of d < 1000 for which 1/d contains the longest -/// recurring cycle in its decimal fraction part. - -fn method1() -> u32 { - let mut longest_cycle = 1; - let mut longest_cycle_num = 0; - - let mut buf = vec![]; - let mut get_cycle = |i: u32| -> usize { - buf.clear(); - let mut num = 1; - loop { - let r = (num % i) * 10; - if r == 0 { - return 0; - } - if let Some(index) = buf.iter().position(|n| n == &r) { - return buf.len() - index; - } - buf.push(r); - num = r; - } - }; - - for i in 2..1000 { - let cycle = get_cycle(i); - if cycle > longest_cycle { - //println!("> {} => {}, longest: {}", i, cycle, longest_cycle); - longest_cycle = cycle; - longest_cycle_num = i; - } - } - - longest_cycle_num -} - -fn main() { - println!("method1: {}", method1()); -} - -#[bench] -fn bench_method1(b: &mut test::Bencher) { - b.iter(|| assert_eq!(method1(), 983)); -} diff --git a/project_euler/src/bin/euler_027.rs b/project_euler/src/bin/euler_027.rs deleted file mode 100644 index b5a9c9ae..00000000 --- a/project_euler/src/bin/euler_027.rs +++ /dev/null @@ -1,104 +0,0 @@ -// Copyright (c) 2020 Xu Shaohua . All rights reserved. -// Use of this source is governed by General Public License that can be found -// in the LICENSE file. - -#![feature(test)] -extern crate test; - -use euler::primes::get_prime_list; - -/// Problem: -/// Euler discovered the remarkable quadratic formula: -/// n^2 + n + 41 -/// -/// It turns out that the formula will produce 40 primes for the consecutive -/// integer values 0 ≤ n ≤ 39. However, when n = 40, -/// 40^2 + 40 + 41 = 40(40 + 1) + 41 is divisible by 41, and certainly -/// when n = 41,41^2 + 41 + 41 is clearly divisible by 41. -/// -/// The incredible formula n^2 − 79^n + 1601 was discovered, which produces -/// 80 primes for the consecutive values 0 ≤ n ≤ 79. The product of -/// the coefficients, −79 and 1601, is −126479. -/// -/// Considering quadratics of the form: -/// -/// n^2 + an + b, where |a| < 1000 and |b| ≤ 1000 -/// where |n| is the modulus/absolute value of n -/// e.g. |11| = 11 and |−4| = 4 -/// -/// Find the product of the coefficients, a and b, for the quadratic expression -/// that produces the maximum number of primes for consecutive values of n, -/// starting with n = 0. - -fn method1() -> i32 { - let prime_list = get_prime_list(2_300_000); - let mut coefficients = 0; - let mut max_num_primes = 0; - - let is_product = |n: i32| prime_list.binary_search(&(n as usize)).is_ok(); - let b_primes = get_prime_list(1000); - - for a in -999..1000_i32 { - for b in &b_primes { - let mut num_primes = 0; - let b = *b as i32; - for i in 0.. { - let product = i * i + a * i + b; - if is_product(product) { - num_primes += 1; - } else { - break; - } - } - - if num_primes > max_num_primes { - max_num_primes = num_primes; - coefficients = a * b; - } - } - } - coefficients -} - -fn method2() -> i32 { - let prime_list = get_prime_list(2_300_000); - let mut coefficients = 0; - let mut max_num_primes = 0; - - let is_product = |n: i32| prime_list.binary_search(&(n as usize)).is_ok(); - - for a in -999..1000_i32 { - for b in 2..1000 { - let mut num_primes = 0; - for i in 0.. { - let product = i * i + a * i + b; - if is_product(product) { - num_primes += 1; - } else { - break; - } - } - - if num_primes > max_num_primes { - max_num_primes = num_primes; - coefficients = a * b; - } - } - } - coefficients -} - -fn main() { - println!("method1: {}", method1()); - println!("method2: {}", method2()); -} - -#[bench] -fn bench_method1(b: &mut test::Bencher) { - b.iter(|| assert_eq!(method1(), -59231)); -} - -#[bench] -fn bench_method2(b: &mut test::Bencher) { - b.iter(|| assert_eq!(method2(), -59231)); -} diff --git a/project_euler/src/bin/euler_028.rs b/project_euler/src/bin/euler_028.rs deleted file mode 100644 index 56ee33f2..00000000 --- a/project_euler/src/bin/euler_028.rs +++ /dev/null @@ -1,45 +0,0 @@ -// Copyright (c) 2020 Xu Shaohua . All rights reserved. -// Use of this source is governed by General Public License that can be found -// in the LICENSE file. - -#![feature(test)] -extern crate test; - -/// Problem: -/// -/// Starting with the number 1 and moving to the right in a clockwise direction -/// a 5 by 5 spiral is formed as follows: -/// -/// 21 22 23 24 25 -/// 20 7 8 9 10 -/// 19 6 1 2 11 -/// 18 5 4 3 12 -/// 17 16 15 14 13 -/// -/// It can be verified that the sum of the numbers on the diagonals is 101. -/// -/// What is the sum of the numbers on the diagonals in a 1001 by 1001 -/// spiral formed in the same way? - -fn method1() -> u32 { - let mut sum = 1; - for i in 1.. { - let side = 2 * i + 1; - if side > 1001 { - break; - } - let s = side * side * 4 - i * 12; - //println!("side: {}, s: {}", side, s); - sum += s; - } - sum -} - -fn main() { - println!("method1: {}", method1()); -} - -#[bench] -fn bench_method1(b: &mut test::Bencher) { - b.iter(|| assert_eq!(method1(), 669171001)); -} diff --git a/project_euler/src/bin/euler_029.rs b/project_euler/src/bin/euler_029.rs deleted file mode 100644 index 03bd6e41..00000000 --- a/project_euler/src/bin/euler_029.rs +++ /dev/null @@ -1,51 +0,0 @@ -// Copyright (c) 2020 Xu Shaohua . All rights reserved. -// Use of this source is governed by General Public License that can be found -// in the LICENSE file. - -#![feature(test)] -extern crate num_bigint; -extern crate test; - -use num_bigint::BigUint; -use std::collections::HashSet; - -/// Problem: -/// -/// Consider all integer combinations of ab for 2 ≤ a ≤ 5 and 2 ≤ b ≤ 5: -/// -/// 2^2=4, 2^3=8, 2^4=16, 2^5=32 -/// 3^2=9, 3^3=27, 3^4=81, 3^5=243 -/// 4^2=16, 4^3=64, 4^4=256, 4^5=1024 -/// 5^2=25, 5^3=125, 5^4=625, 5^5=3125 -/// -/// If they are then placed in numerical order, with any repeats removed, -/// we get the following sequence of 15 distinct terms: -/// -/// 4, 8, 9, 16, 25, 27, 32, 64, 81, 125, 243, 256, 625, 1024, 3125 -/// -/// How many distinct terms are in the sequence generated by ab for -/// 2 ≤ a ≤ 100 and 2 ≤ b ≤ 100? - -fn method1() -> usize { - let mut set = HashSet::::new(); - - let mut big_num: BigUint; - for i in 2_u16..=100 { - big_num = BigUint::from(i); - for _j in 2_u16..=100 { - big_num *= i; - set.insert(big_num.to_string()); - } - } - - set.len() -} - -fn main() { - println!("method1: {}", method1()); -} - -#[bench] -fn bench_method1(b: &mut test::Bencher) { - b.iter(|| assert_eq!(method1(), 9183)); -} diff --git a/project_euler/src/bin/euler_030.rs b/project_euler/src/bin/euler_030.rs deleted file mode 100644 index 2b4303e8..00000000 --- a/project_euler/src/bin/euler_030.rs +++ /dev/null @@ -1,129 +0,0 @@ -// Copyright (c) 2020 Xu Shaohua . All rights reserved. -// Use of this source is governed by General Public License that can be found -// in the LICENSE file. - -#![feature(test)] -extern crate test; - -/// Problem: -/// -/// Surprisingly there are only three numbers that can be written as -/// the sum of fourth powers of their digits: -/// -/// 1634 = 14 + 64 + 34 + 44 -/// 8208 = 84 + 24 + 04 + 84 -/// 9474 = 94 + 44 + 74 + 44 -/// -/// As 1 = 14 is not a sum it is not included. -/// -/// The sum of these numbers is 1634 + 8208 + 9474 = 19316. -/// -/// Find the sum of all the numbers that can be written as -/// the sum of fifth powers of their digits. - -const FIFTH_POW: [u64; 10] = [ - 0, - 1, - 2 * 2 * 2 * 2 * 2, - 3 * 3 * 3 * 3 * 3, - 4 * 4 * 4 * 4 * 4, - 5 * 5 * 5 * 5 * 5, - 6 * 6 * 6 * 6 * 6, - 7 * 7 * 7 * 7 * 7, - 8 * 8 * 8 * 8 * 8, - 9 * 9 * 9 * 9 * 9, -]; - -/// For n * 9 ^ 5 > 10^n - 1, max value of n is 5. -fn method1() -> u64 { - const MAX: usize = 10; - let mut digits: [u8; MAX] = [0; MAX]; - let mut fifth_power_nums = vec![]; - // Skip 1 - digits[0] = 1; - for i in 2..1_000_000_u64 { - let mut sum = 1; - for j in 0..MAX { - sum += digits[j]; - if sum > 9 { - digits[j] = 0; - sum = 1; - } else { - digits[j] = sum; - break; - } - } - - let sum: u64 = digits.iter().map(|digit| (*digit as u64).pow(5)).sum(); - if sum == i { - fifth_power_nums.push(i); - } - } - fifth_power_nums.into_iter().sum() -} - -fn method2() -> u64 { - let mut fifth_power_nums = vec![]; - let mut s; - for i in 2..1_000_000_u64 { - s = i.to_string(); - let sum: u64 = s - .bytes() - .map(|b| { - let digit: u64 = (b - b'0') as u64; - digit.pow(5) - }) - .sum(); - if sum == i { - fifth_power_nums.push(i); - } - } - fifth_power_nums.into_iter().sum() -} - -fn method3() -> u64 { - const MAX: usize = 10; - let mut digits: [u8; MAX] = [0; MAX]; - let mut fifth_power_nums = vec![]; - digits[0] = 1; - for i in 2..1_000_000_u64 { - let mut sum = 1; - for j in 0..MAX { - sum += digits[j]; - if sum > 9 { - digits[j] = 0; - sum = 1; - } else { - digits[j] = sum; - break; - } - } - - let sum: u64 = digits.iter().map(|digit| FIFTH_POW[*digit as usize]).sum(); - if sum == i { - fifth_power_nums.push(i); - } - } - fifth_power_nums.into_iter().sum() -} - -fn main() { - println!("method1: {}", method1()); - println!("method2: {}", method2()); - println!("method3: {}", method3()); -} - -#[bench] -fn bench_method1(b: &mut test::Bencher) { - b.iter(|| assert_eq!(method1(), 443839)); -} - -#[bench] -fn bench_method2(b: &mut test::Bencher) { - b.iter(|| assert_eq!(method2(), 443839)); -} - -#[bench] -fn bench_method3(b: &mut test::Bencher) { - b.iter(|| assert_eq!(method3(), 443839)); -} diff --git a/project_euler/src/bin/euler_031.rs b/project_euler/src/bin/euler_031.rs deleted file mode 100644 index 03499c5e..00000000 --- a/project_euler/src/bin/euler_031.rs +++ /dev/null @@ -1,129 +0,0 @@ -// Copyright (c) 2020 Xu Shaohua . All rights reserved. -// Use of this source is governed by General Public License that can be found -// in the LICENSE file. - -#![feature(test)] -extern crate test; - -/// Problem: -/// -/// In the United Kingdom the currency is made up of pound (£) and pence (p). -/// There are eight coins in general circulation: -/// 1p, 2p, 5p, 10p, 20p, 50p, £1 (100p), and £2 (200p). -/// It is possible to make £2 in the following way: -/// 1×£1 + 1×50p + 2×20p + 1×5p + 1×2p + 3×1p -/// How many different ways can £2 be made using any number of coins? - -fn method1(max_num: usize) -> usize { - let mut count = 0; - for i200 in 0..=max_num { - let s200 = i200 * 200; - if s200 == max_num { - count += 1; - break; - } - if s200 > max_num { - break; - } - for i100 in 0..=max_num { - let s100 = s200 + i100 * 100; - if s100 == max_num { - count += 1; - break; - } - if s100 > max_num { - break; - } - for i50 in 0..=max_num { - let s50 = s100 + i50 * 50; - if s50 == max_num { - count += 1; - break; - } - if s50 > max_num { - break; - } - - for i20 in 0..=max_num { - let s20 = s50 + i20 * 20; - if s20 == max_num { - count += 1; - break; - } - if s20 > max_num { - break; - } - - for i10 in 0..=max_num { - let s10 = s20 + i10 * 10; - if s10 == max_num { - count += 1; - break; - } - if s10 > max_num { - break; - } - for i5 in 0..=max_num { - let s5 = s10 + i5 * 5; - if s5 == max_num { - count += 1; - break; - } - if s5 > max_num { - break; - } - for i2 in 0..=max_num { - let s2 = s5 + i2 * 2; - if s2 == max_num { - count += 1; - break; - } - if s2 < max_num { - //println!("s2: {}, i100:{}, i50: {}, i20: {}, i10: {}, i5: {}, i2: {}",s2, i100, i50, i20, i10, i5, i2); - count += 1; - } else if s2 == max_num { - //println!("s2: {}, i100:{}, i50: {}, i20: {}, i10: {}, i5: {}, i2: {}", s2, i100, i50, i20, i10, i5, i2); - count += 1; - break; - } else { - break; - } - } - } - } - } - } - } - } - - count -} - -fn method2(max_num: usize) -> usize { - let coins = vec![1, 2, 5, 10, 20, 50, 100, 200]; - let mut ways = vec![0; max_num + 1]; - ways[0] = 1; - for coin in coins { - for j in coin..=max_num { - ways[j] += ways[j - coin]; - } - } - - ways[max_num] -} - -fn main() { - let max_num = 200; - println!("ways: {}", method1(max_num)); - println!("ways: {}", method2(max_num)); -} - -#[bench] -fn bench_method1(b: &mut test::Bencher) { - b.iter(|| assert_eq!(method1(200), 73682)); -} - -#[bench] -fn bench_method2(b: &mut test::Bencher) { - b.iter(|| assert_eq!(method2(200), 73682)); -} diff --git a/project_euler/src/bin/euler_032.rs b/project_euler/src/bin/euler_032.rs deleted file mode 100644 index c0f0cd9e..00000000 --- a/project_euler/src/bin/euler_032.rs +++ /dev/null @@ -1,88 +0,0 @@ -// Copyright (c) 2020 Xu Shaohua . All rights reserved. -// Use of this source is governed by General Public License that can be found -// in the LICENSE file. - -#![feature(test)] -extern crate test; - -use std::collections::HashSet; - -/// Problem: -/// -/// We shall say that an n-digit number is pandigital if it makes use of -/// all the digits 1 to n exactly once; for example, the 5-digit number, 15234, -/// is 1 through 5 pandigital. -/// -/// The product 7254 is unusual, as the identity, 39 × 186 = 7254, -/// containing multiplicand, multiplier, and product is 1 through 9 pandigital. -/// -/// Find the sum of all products whose multiplicand/multiplier/product identity -/// can be written as a 1 through 9 pandigital. -/// HINT: Some products can be obtained in more than one way so be sure -/// to only include it once in your sum. - -fn method1() -> u32 { - let mut products: HashSet = HashSet::new(); - let mut digits: [usize; 10] = [0; 10]; - let mut is_pandigitals = |mut i: u32, mut j: u32, mut p: u32| -> bool { - if p > 9999 || p < 1000 { - return false; - } - - for i in 0..digits.len() { - digits[i] = 0; - } - - let mut r: usize; - let mut count = 0; - while i > 0 { - r = (i % 10) as usize; - if r == 0 || digits[r] != 0 { - return false; - } - digits[r] = r; - count += 1; - i /= 10; - } - while j > 0 { - r = (j % 10) as usize; - if r == 0 || digits[r] != 0 { - return false; - } - digits[r] = r; - count += 1; - j /= 10; - } - while p > 0 { - r = (p % 10) as usize; - if r == 0 || digits[r] != 0 { - return false; - } - digits[r] = r; - count += 1; - p /= 10; - } - - count == 9 - }; - - for i in 1..999 { - for j in i..9999 { - let p = i * j; - if is_pandigitals(i, j, p) { - products.insert(p); - } - } - } - - products.into_iter().sum() -} - -fn main() { - println!("method1: {}", method1()); -} - -#[bench] -fn bench_method1(b: &mut test::Bencher) { - b.iter(|| assert_eq!(method1(), 45228)); -} diff --git a/project_euler/src/bin/euler_033.rs b/project_euler/src/bin/euler_033.rs deleted file mode 100644 index 2e4a2815..00000000 --- a/project_euler/src/bin/euler_033.rs +++ /dev/null @@ -1,59 +0,0 @@ -// Copyright (c) 2020 Xu Shaohua . All rights reserved. -// Use of this source is governed by General Public License that can be found -// in the LICENSE file. - -#![feature(test)] -extern crate test; - -use euler::gcd::Gcd; - -/// Problem: -/// -/// The fraction 49/98 is a curious fraction, as an inexperienced mathematician -/// in attempting to simplify it may incorrectly believe that 49/98 = 4/8, -/// which is correct, is obtained by cancelling the 9s. -/// -/// We shall consider fractions like, 30/50 = 3/5, to be trivial examples. -/// -/// There are exactly four non-trivial examples of this type of fraction, -/// less than one in value, and containing two digits in the numerator and -/// denominator. -/// -/// If the product of these four fractions is given in its lowest common terms, -/// find the value of the denominator. - -fn method1() -> u32 { - let is_canceling_fraction = |numerator: u32, denominator: u32| -> bool { - let n1 = numerator / 10; - let n2 = numerator % 10; - let d1 = denominator / 10; - let d2 = denominator % 10; - (n2 == d1) && (n1 * denominator == d2 * numerator) - }; - - let mut denominators = 1; - let mut numerators = 1; - for i in 10..99_u32 { - for j in (i + 1)..=99 { - if is_canceling_fraction(i, j) { - println!("> {} / {}", i, j); - numerators *= i; - denominators *= j; - let common = u32::gcd(numerators, denominators); - numerators /= common; - denominators /= common; - } - } - } - - denominators -} - -fn main() { - println!("method1: {}", method1()); -} - -#[bench] -fn bench_method1(b: &mut test::Bencher) { - b.iter(|| assert_eq!(method1(), 100)); -} diff --git a/project_euler/src/bin/euler_034.rs b/project_euler/src/bin/euler_034.rs deleted file mode 100644 index d20d8056..00000000 --- a/project_euler/src/bin/euler_034.rs +++ /dev/null @@ -1,68 +0,0 @@ -// Copyright (c) 2020 Xu Shaohua . All rights reserved. -// Use of this source is governed by General Public License that can be found -// in the LICENSE file. - -#![feature(test)] -extern crate test; - -use euler::digits::GetDigits; - -/// Problem: -/// -/// The Fibonacci sequence is defined by the recurrence relation: -/// Fn = F_(n−1) + F_(n−2), where F1 = 1 and F2 = 1. -/// Hence the first 12 terms will be: -/// F1 = 1 -/// F2 = 1 -/// F3 = 2 -/// F4 = 3 -/// F5 = 5 -/// F6 = 8 -/// F7 = 13 -/// F8 = 21 -/// F9 = 34 -/// F10 = 55 -/// F11 = 89 -/// F12 = 144 -/// The 12th term, F12, is the first term to contain three digits. -/// What is the index of the first term in the Fibonacci sequence to -/// contain 1000 digits? - -/// f1(n) = 9! * n; -/// f2(n) = 10^n - 1; -/// 9_999_999 is upper bound. -const UPPER_BOND: usize = 7; - -fn method1() -> u64 { - let mut product = 1; - let mut factorials: [u64; 10] = [1; 10]; - for i in 1..=9 { - product *= i; - factorials[i] = product as u64; - } - - let mut curious_nums = vec![]; - let mut digits = Vec::with_capacity(UPPER_BOND); - - for i in 1_u64..(UPPER_BOND as u64 * factorials[9]) { - digits.clear(); - let _num_digits = i.get_digits(&mut digits); - let sum: u64 = digits.iter().map(|&digit| factorials[digit as usize]).sum(); - if i == sum { - println!(">> {}", i); - curious_nums.push(i); - } - } - - let s: u64 = curious_nums.into_iter().sum(); - s - 1 - 2 -} - -fn main() { - println!("method1: {}", method1()); -} - -#[bench] -fn bench_method1(b: &mut test::Bencher) { - b.iter(|| assert_eq!(method1(), 40730)); -} diff --git a/project_euler/src/bin/euler_035.rs b/project_euler/src/bin/euler_035.rs deleted file mode 100644 index 4da49120..00000000 --- a/project_euler/src/bin/euler_035.rs +++ /dev/null @@ -1,83 +0,0 @@ -// Copyright (c) 2020 Xu Shaohua . All rights reserved. -// Use of this source is governed by General Public License that can be found -// in the LICENSE file. - -#![feature(test)] -extern crate euler; -extern crate test; - -use std::collections::HashSet; -use std::iter::FromIterator; - -/// Problem: -/// -/// The number, 197, is called a circular prime because all rotations of -/// the digits: 197, 971, and 719, are themselves prime. -/// There are thirteen such primes below 100: -/// 2, 3, 5, 7, 11, 13, 17, 31, 37, 71, 73, 79, and 97. -/// How many circular primes are there below one million? - -fn method1() -> u32 { - const MAX: usize = 1_000_000; - let mut circular_count = 0; - let prime_list = euler::primes::get_prime_list(MAX); - let primes: HashSet = HashSet::from_iter(prime_list.into_iter()); - let is_circurlar_prime = |prime: usize| -> bool { - let rotate_digits = if prime > 100_000 { - 5 - } else if prime > 10_000 { - 4 - } else if prime > 1_000 { - 3 - } else if prime > 100 { - 2 - } else if prime > 10 { - 1 - } else { - 0 - }; - - let mut result = true; - let mut p = prime; - let rotate = 10_usize.pow(rotate_digits); - for _i in 0..rotate_digits { - let quotient = p / rotate; - // Skip prime numbers which contain even digits - if quotient == 0 - || quotient == 2 - || quotient == 4 - || quotient == 5 - || quotient == 6 - || quotient == 8 - { - result = false; - break; - } - // rotate left - p = p % rotate * 10 + quotient; - if !primes.contains(&p) { - result = false; - break; - } - } - result - }; - - for prime in &primes { - if is_circurlar_prime(*prime) { - //println!("> prime: {}", prime); - circular_count += 1; - } - } - - circular_count -} - -fn main() { - println!("method1: {}", method1()); -} - -#[bench] -fn bench_method1(b: &mut test::Bencher) { - b.iter(|| assert_eq!(method1(), 55)); -} diff --git a/project_euler/src/bin/euler_036.rs b/project_euler/src/bin/euler_036.rs deleted file mode 100644 index b7df2c9a..00000000 --- a/project_euler/src/bin/euler_036.rs +++ /dev/null @@ -1,125 +0,0 @@ -// Copyright (c) 2020 Xu Shaohua . All rights reserved. -// Use of this source is governed by General Public License that can be found -// in the LICENSE file. - -#![feature(test)] -extern crate test; - -/// Problem: -/// -/// The decimal number, 585 = 10010010012 (binary), is palindromic -/// in both bases. -/// -/// Find the sum of all numbers, less than one million, which are palindromic -/// in base 10 and base 2. -/// -/// (Please note that the palindromic number, in either base, may not -/// include leading zeros.) - -fn is_palindrome(n: u32, base: u8) -> bool { - let s: String = if base == 10 { - n.to_string() - } else { - format!("{:b}", n) - }; - let rev_s: String = s.chars().rev().collect(); - s == rev_s -} - -fn method1() -> u32 { - let mut palindromes: Vec = Vec::new(); - - for i in 1..1_000_000 { - if is_palindrome(i, 10) && is_palindrome(i, 2) { - palindromes.push(i); - } - } - - palindromes.iter().sum() -} - -fn is_palindrome2(num: u32, base: u32) -> bool { - let mut n = num; - let mut digits = vec![]; - while n >= base { - digits.push(n % base); - n /= base; - } - digits.push(n); - - let len = digits.len(); - for i in 0..len { - if digits[i] != digits[len - i - 1] { - return false; - } - } - - true -} - -fn method2() -> u32 { - let mut palindromes: Vec = Vec::new(); - - for i in 1..1_000_000 { - if is_palindrome2(i, 10) && is_palindrome2(i, 2) { - palindromes.push(i); - } - } - - palindromes.iter().sum() -} - -fn method3() -> u32 { - // 1_000_000 consumes 20 bits in binary format. - let mut digits = Vec::with_capacity(20); - let mut is_palindrome3 = |num: u32, base: u32| -> bool { - let mut n = num; - digits.clear(); - - while n >= base { - digits.push(n % base); - n /= base; - } - digits.push(n); - - let len = digits.len(); - for i in 0..len { - if digits[i] != digits[len - i - 1] { - return false; - } - } - - true - }; - - let mut palindromes: Vec = Vec::new(); - - for i in 1..1_000_000 { - if is_palindrome3(i, 10) && is_palindrome3(i, 2) { - palindromes.push(i); - } - } - - palindromes.iter().sum() -} - -fn main() { - println!("method1: {}", method1()); - println!("method2: {}", method2()); - println!("method3: {}", method3()); -} - -#[bench] -fn bench_method1(b: &mut test::Bencher) { - b.iter(|| assert_eq!(method1(), 872187)); -} - -#[bench] -fn bench_method2(b: &mut test::Bencher) { - b.iter(|| assert_eq!(method2(), 872187)); -} - -#[bench] -fn bench_method3(b: &mut test::Bencher) { - b.iter(|| assert_eq!(method3(), 872187)); -} diff --git a/project_euler/src/bin/euler_037.rs b/project_euler/src/bin/euler_037.rs deleted file mode 100644 index f08961a2..00000000 --- a/project_euler/src/bin/euler_037.rs +++ /dev/null @@ -1,66 +0,0 @@ -// Copyright (c) 2020 Xu Shaohua . All rights reserved. -// Use of this source is governed by General Public License that can be found -// in the LICENSE file. - -#![feature(test)] -extern crate euler; -extern crate test; - -/// Problem: -/// -/// The number 3797 has an interesting property. Being prime itself, -/// it is possible to continuously remove digits from left to right, -/// and remain prime at each stage: 3797, 797, 97, and 7. -/// Similarly we can work from right to left: 3797, 379, 37, and 3. -/// -/// Find the sum of the only eleven primes that are both truncatable from -/// left to right and right to left. -/// -/// NOTE: 2, 3, 5, and 7 are not considered to be truncatable primes. - -fn method1() -> usize { - let primes = euler::primes::get_prime_list(1_000_000); - let mut truncatable_primes: Vec = Vec::with_capacity(11); - - let is_truncatable_prime = |prime: usize| -> bool { - let mut p = prime; - while p >= 10 { - p /= 10; - if primes.binary_search(&p).is_err() { - return false; - } - } - if primes.binary_search(&p).is_err() { - return false; - } - - let mut base = 10; - let mut p; - while prime >= base { - p = prime % base; - base *= 10; - if primes.binary_search(&p).is_err() { - return false; - } - } - - true - }; - - for prime in &primes { - if prime > &10 && is_truncatable_prime(*prime) { - println!("> #{}, {}", truncatable_primes.len() + 1, prime); - truncatable_primes.push(*prime); - } - } - truncatable_primes.iter().sum() -} - -fn main() { - println!("method1: {}", method1()); -} - -#[bench] -fn bench_method1(b: &mut test::Bencher) { - b.iter(|| assert_eq!(method1(), 748317)); -} diff --git a/project_euler/src/bin/euler_038.rs b/project_euler/src/bin/euler_038.rs deleted file mode 100644 index b7bb26e5..00000000 --- a/project_euler/src/bin/euler_038.rs +++ /dev/null @@ -1,121 +0,0 @@ -// Copyright (c) 2020 Xu Shaohua . All rights reserved. -// Use of this source is governed by General Public License that can be found -// in the LICENSE file. - -#![feature(test)] -extern crate test; - -/// Problem: -/// -/// Take the number 192 and multiply it by each of 1, 2, and 3: -/// -/// 192 × 1 = 192 -/// 192 × 2 = 384 -/// 192 × 3 = 576 -/// -/// By concatenating each product we get the 1 to 9 pandigital, 192384576. -/// We will call 192384576 the concatenated product of 192 and (1,2,3) -/// -/// The same can be achieved by starting with 9 and multiplying by 1, 2, 3, 4, -/// and 5, giving the pandigital, 918273645, which is the concatenated product -/// of 9 and (1,2,3,4,5). -/// -/// What is the largest 1 to 9 pandigital 9-digit number that can be formed -/// as the concatenated product of an integer with (1,2, ... , n) where n > 1? - -pub struct Pandigits { - digits: [bool; Self::MAX], - num: u64, -} - -impl Pandigits { - const MAX: usize = 10; - - pub fn new() -> Pandigits { - Pandigits { - digits: [false; Self::MAX], - num: 0, - } - } - - pub fn reset(&mut self) { - for i in 0..Self::MAX { - self.digits[i] = false; - } - self.num = 0; - } - - pub fn append(&mut self, orig_n: u64) -> bool { - let mut r: usize; - let mut n = orig_n; - let mut count = 0; - while n > 0 { - r = (n % 10) as usize; - n /= 10; - if r == 0 || self.digits[r] { - return false; - } - self.digits[r] = true; - count += 1; - } - self.num = self.num * 10_u64.pow(count) + orig_n; - true - } - - pub fn is_pandigitals(&self) -> bool { - for i in 1..Self::MAX { - if !self.digits[i] { - return false; - } - } - true - } - - pub fn get_num(&self) -> u64 { - self.num - } -} - -fn method1() -> u64 { - let mut pandigits = Pandigits::new(); - let mut max_pandigitals = 0; - let ranges = vec![ - (2, 1000, 9999), - (3, 1000, 9999), - (4, 100, 999), - (5, 1, 99), - (6, 1, 9), - ]; - - for (n, start, end) in ranges.into_iter() { - - 'i_range: - for i in start..end { - pandigits.reset(); - for j in 1..=n { - if !pandigits.append(i * j) { - continue 'i_range; - } - } - - if pandigits.is_pandigitals() { - let p = pandigits.get_num(); - println!("> i: {}, p: {}, max: {}", i, p, max_pandigitals); - if p > max_pandigitals { - max_pandigitals = p; - } - } - } - } - - max_pandigitals -} - -fn main() { - println!("method1: {}", method1()); -} - -#[bench] -fn bench_method1(b: &mut test::Bencher) { - b.iter(|| assert_eq!(method1(), 932718654)); -} diff --git a/project_euler/src/bin/euler_039.rs b/project_euler/src/bin/euler_039.rs deleted file mode 100644 index 91a77e16..00000000 --- a/project_euler/src/bin/euler_039.rs +++ /dev/null @@ -1,55 +0,0 @@ -// Copyright (c) 2020 Xu Shaohua . All rights reserved. -// Use of this source is governed by General Public License that can be found -// in the LICENSE file. - -#![feature(test)] -extern crate test; - -/// Problem: -/// -/// If p is the perimeter of a right angle triangle with integral length sides, -/// {a,b,c}, there are exactly three solutions for p = 120. -/// -/// {20,48,52}, {24,45,51}, {30,40,50} -/// -/// For which value of p ≤ 1000, is the number of solutions maximised? - -fn method1() -> u32 { - let parse_triangle = |num: u32| { - let one_third = num / 3; - let half = num / 2; - let mut count = 0; - - for a in 1..one_third { - for b in a..half { - let c = num - a - b; - if a * a + b * b == c * c { - count += 1; - } - } - } - - count - }; - - let mut max_count = 0; - let mut max_num = 0; - for i in 120..=1000 { - let count = parse_triangle(i); - if count > max_count { - max_count = count; - max_num = i; - } - } - - max_num -} - -fn main() { - println!("method1: {}", method1()); -} - -#[bench] -fn bench_method1(b: &mut test::Bencher) { - b.iter(|| assert_eq!(method1(), 840)); -} diff --git a/project_euler/src/bin/euler_040.rs b/project_euler/src/bin/euler_040.rs deleted file mode 100644 index 340dfd54..00000000 --- a/project_euler/src/bin/euler_040.rs +++ /dev/null @@ -1,81 +0,0 @@ -// Copyright (c) 2020 Xu Shaohua . All rights reserved. -// Use of this source is governed by General Public License that can be found -// in the LICENSE file. - -#![feature(test)] -extern crate test; - -/// Problem: -/// -/// An irrational decimal fraction is created by -/// concatenating the positive integers: -/// -/// 0.123456789101112131415161718192021... -/// -/// It can be seen that the 12th digit of the fractional part is 1. -/// -/// If dn represents the nth digit of the fractional part, -/// find the value of the following expression. -/// -/// d1 × d10 × d100 × d1000 × d10000 × d100000 × d1000000 - -fn method1() -> u64 { - let mut result = String::with_capacity(1_000_000); - for i in 1..200_000 { - let s = i.to_string(); - result += &s; - } - - let mut product = 1; - for i in 0..6 { - let pos = 10_usize.pow(i) - 1; - product *= &result[pos..pos + 1].parse().unwrap(); - } - product -} - -fn method2() -> u64 { - const DIGITS: [u32; 6] = [9, 90 * 2, 900 * 3, 9000 * 4, 90_000 * 5, 900_000 * 6]; - - let get_digits = |num: u32| { - let mut n = num; - let mut i = 0; - let mut base = 1; - let mut num_digits = 1; - while n > DIGITS[i] { - n -= DIGITS[i]; - i += 1; - base *= 10; - num_digits += 1; - } - - let num_order = (n - 1) / num_digits + 1; - let digit_order = (n - 1) % num_digits; - let number = base + num_order - 1; - let s: String = number.to_string(); - (s.bytes().nth(digit_order as usize).unwrap() - b'0') as u64 - }; - - get_digits(1) - * get_digits(10) - * get_digits(100) - * get_digits(1000) - * get_digits(10_000) - * get_digits(100_000) - * get_digits(1_000_000) -} - -fn main() { - println!("method1: {}", method1()); - println!("method2: {}", method2()); -} - -#[bench] -fn bench_method1(b: &mut test::Bencher) { - b.iter(|| assert_eq!(method1(), 210)); -} - -#[bench] -fn bench_method2(b: &mut test::Bencher) { - b.iter(|| assert_eq!(method2(), 210)); -} diff --git a/project_euler/src/bin/euler_041.rs b/project_euler/src/bin/euler_041.rs deleted file mode 100644 index 53fd00cf..00000000 --- a/project_euler/src/bin/euler_041.rs +++ /dev/null @@ -1,50 +0,0 @@ -// Copyright (c) 2020 Xu Shaohua . All rights reserved. -// Use of this source is governed by General Public License that can be found -// in the LICENSE file. - -#![feature(test)] -extern crate test; - -use euler::permutation::Permutation; -use euler::primes::IsPrime; - -/// Problem: -/// -/// We shall say that an n-digit number is pandigital if it makes use of -/// all the digits 1 to n exactly once. For example, 2143 is a 4-digit -/// pandigital and is also prime. -/// -/// What is the largest n-digit pandigital prime that exists? - -fn method1() -> usize { - let mut largest_pandigital_prime = 0; - - for i in 2..=7 { - let mut digits: Vec = vec![]; - for j in 1..=i { - digits.push(j); - } - let p = Permutation::new(digits); - for d in p.into_iter() { - let mut num: usize = 0; - for digit in d { - num = num * 10 + digit as usize; - } - if num > largest_pandigital_prime && num.is_prime() { - println!("> {}, {}", num, largest_pandigital_prime); - largest_pandigital_prime = num; - } - } - } - - largest_pandigital_prime -} - -fn main() { - println!("method1: {}", method1()); -} - -#[bench] -fn bench_method1(b: &mut test::Bencher) { - b.iter(|| assert_eq!(method1(), 7652413)); -} diff --git a/project_euler/src/bin/euler_042.rs b/project_euler/src/bin/euler_042.rs deleted file mode 100644 index c1b64b87..00000000 --- a/project_euler/src/bin/euler_042.rs +++ /dev/null @@ -1,72 +0,0 @@ -// Copyright (c) 2020 Xu Shaohua . All rights reserved. -// Use of this source is governed by General Public License that can be found -// in the LICENSE file. - -#![feature(test)] -extern crate test; - -use std::fs::File; -use std::io::{BufRead, BufReader, Result}; - -/// Problem: -/// - -/// The nth term of the sequence of triangle numbers is given by, t_n = ½n(n+1); -/// so the first ten triangle numbers are: -/// -/// 1, 3, 6, 10, 15, 21, 28, 36, 45, 55, ... -/// -/// By converting each letter in a word to a number corresponding to -/// its alphabetical position and adding these values we form a word value. -/// For example, the word value for SKY is 19 + 11 + 25 = 55 = t10. -/// If the word value is a triangle number then we shall call the word -/// a triangle word. -/// -/// Using words.txt (right click and 'Save Link/Target As...'), a 16K -/// text file containing nearly two-thousand common English words, -/// how many are triangle words? - -fn method1(words: &Vec>) -> usize { - let get_word_sum = |v: &Vec| -> u16 { - v.iter() - .map(|c| { - if c < &b'A' || c > &b'Z' { - 0 - } else { - (c - b'A' + 1) as u16 - } - }) - .sum() - }; - - let triangle_nums: Vec = (1..100).map(|i| i * (i + 1) / 2).collect(); - let is_triangle_num = |n: u16| -> bool { triangle_nums.binary_search(&n).is_ok() }; - - words - .iter() - .map(|word| get_word_sum(word)) - .filter(|n| is_triangle_num(*n)) - .count() -} - -fn read_words(filepath: &str) -> Result>> { - let fd = File::open(filepath)?; - let buf = BufReader::new(fd); - Ok(buf.split(b',').map(|l| l.unwrap()).collect()) -} - -fn main() { - let filepath = if let Some(filepath) = std::env::args().nth(1) { - filepath - } else { - panic!("Usage: euler_042 words.txt"); - }; - let words = read_words(&filepath).unwrap(); - println!("method1: {}", method1(&words)); -} - -#[bench] -fn bench_method1(b: &mut test::Bencher) { - let words = read_words("/etc/issue").unwrap(); - b.iter(|| method1(&words)); -} diff --git a/project_euler/src/bin/euler_043.rs b/project_euler/src/bin/euler_043.rs deleted file mode 100644 index 0068cf33..00000000 --- a/project_euler/src/bin/euler_043.rs +++ /dev/null @@ -1,69 +0,0 @@ -// Copyright (c) 2020 Xu Shaohua . All rights reserved. -// Use of this source is governed by General Public License that can be found -// in the LICENSE file. - -#![feature(test)] -extern crate test; - -use euler::permutation::Permutation; - -/// Problem: -/// -/// The number, 1406357289, is a 0 to 9 pandigital number because it is -/// made up of each of the digits 0 to 9 in some order, but it also -/// has a rather interesting sub-string divisibility property. -/// -/// Let d1 be the 1st digit, d2 be the 2nd digit, and so on. In this way, -/// we note the following: -/// -/// d2d3d4=406 is divisible by 2 -/// d3d4d5=063 is divisible by 3 -/// d4d5d6=635 is divisible by 5 -/// d5d6d7=357 is divisible by 7 -/// d6d7d8=572 is divisible by 11 -/// d7d8d9=728 is divisible by 13 -/// d8d9d10=289 is divisible by 17 -/// -/// Find the sum of all 0 to 9 pandigital numbers with this property. - -fn method1() -> u64 { - let mut sum = vec![]; - let pairs = [ - (1_usize, 2), - (2, 3), - (3, 5), - (4, 7), - (5, 11), - (6, 13), - (7, 17), - ]; - - let digits = vec![0, 1, 2, 3, 4, 5, 6, 7, 8, 9]; - let p = Permutation::new(digits); - 'iterator: for item in p.into_iter() { - for (i, prime) in &pairs { - let num = (item[*i] as u64) * 100 + (item[i + 1] as u64) * 10 + item[i + 2] as u64; - if num % prime != 0 { - continue 'iterator; - } - } - - let mut num: u64 = 0; - for i in item { - num = (num * 10) + (i as u64); - } - println!("> {}", num); - sum.push(num); - } - - sum.into_iter().sum() -} - -fn main() { - println!("method1: {}", method1()); -} - -#[bench] -fn bench_method1(b: &mut test::Bencher) { - b.iter(|| assert_eq!(method1(), 16695334890)); -} diff --git a/project_euler/src/bin/euler_044.rs b/project_euler/src/bin/euler_044.rs deleted file mode 100644 index 1ad0097e..00000000 --- a/project_euler/src/bin/euler_044.rs +++ /dev/null @@ -1,55 +0,0 @@ -// Copyright (c) 2020 Xu Shaohua . All rights reserved. -// Use of this source is governed by General Public License that can be found -// in the LICENSE file. - -#![feature(test)] -extern crate test; - -/// Problem: -/// -/// Pentagonal numbers are generated by the formula, Pn=n(3n−1)/2. -/// The first ten pentagonal numbers are: -/// -/// 1, 5, 12, 22, 35, 51, 70, 92, 117, 145, ... -/// -/// It can be seen that P4 + P7 = 22 + 70 = 92 = P8. However, their difference, -/// 70 − 22 = 48, is not pentagonal. -/// -/// Find the pair of pentagonal numbers, Pj and Pk, for which their sum and -/// difference are pentagonal and D = |Pk − Pj| is minimised; -/// what is the value of D? - -fn method1() -> usize { - const MAX: usize = 2500; - let mut pentagons: [usize; MAX] = [0; MAX]; - for i in 1..MAX { - let pentagon = i * (3 * i - 1) / 2; - pentagons[i] = pentagon; - } - - let mut min_pentagon = pentagons[MAX - 1]; - for i in 1..(MAX - 1) { - for j in (i + 1)..MAX { - let sum = pentagons[i] + pentagons[j]; - let sub = pentagons[j] - pentagons[i]; - if pentagons.binary_search(&sum).is_ok() && pentagons.binary_search(&sub).is_ok() { - println!("> i: {}, j: {}, sub: {}", i, j, sub); - if min_pentagon > sub { - min_pentagon = sub; - } - } - } - } - - min_pentagon -} - - -fn main() { - println!("method1: {}", method1()); -} - -#[bench] -fn bench_method1(b: &mut test::Bencher) { - b.iter(|| assert_eq!(method1(), 5482660)); -} diff --git a/project_euler/src/bin/euler_045.rs b/project_euler/src/bin/euler_045.rs deleted file mode 100644 index 4344bf95..00000000 --- a/project_euler/src/bin/euler_045.rs +++ /dev/null @@ -1,61 +0,0 @@ -// Copyright (c) 2020 Xu Shaohua . All rights reserved. -// Use of this source is governed by General Public License that can be found -// in the LICENSE file. - -#![feature(test)] -extern crate test; - -/// Problem: -/// -/// Triangle, pentagonal, and hexagonal numbers are generated by the following -/// formulae: -/// -/// Triangle Tn=n(n+1)/2 1, 3, 6, 10, 15, ... -/// Pentagonal Pn=n(3n−1)/2 1, 5, 12, 22, 35, ... -/// Hexagonal Hn=n(2n−1) 1, 6, 15, 28, 45, ... -/// -/// It can be verified that T285 = P165 = H143 = 40755. -/// -/// Find the next triangle number that is also pentagonal and hexagonal. - -fn method1() -> u64 { - let mut i = 286; - let mut j = 166; - let mut k = 144; - loop { - let triangle = i * (i + 1) / 2; - let pentagonal = j * (3 * j - 1) / 2; - if triangle == pentagonal { - println!("> i: {}, j: {}, triangle: {}", i, j, triangle); - loop { - let hexagonal = k * (2 * k - 1); - if triangle == hexagonal { - println!("> i: {}, j: {}, k: {}", i, j, k); - println!( - ">> triangle: {}, pentagonal: {}, hexagonal: {}", - triangle, pentagonal, hexagonal - ); - return triangle; - } else if triangle > hexagonal { - k += 1; - } else { - break; - } - } - i += 1; - } else if triangle > pentagonal { - j += 1; - } else if triangle < pentagonal { - i += 1; - } - } -} - -fn main() { - println!("method1: {}", method1()); -} - -#[bench] -fn bench_method1(b: &mut test::Bencher) { - b.iter(|| assert_eq!(method1(), 1533776805)); -} diff --git a/project_euler/src/bin/euler_046.rs b/project_euler/src/bin/euler_046.rs deleted file mode 100644 index 0b2426d8..00000000 --- a/project_euler/src/bin/euler_046.rs +++ /dev/null @@ -1,75 +0,0 @@ -// Copyright (c) 2020 Xu Shaohua . All rights reserved. -// Use of this source is governed by General Public License that can be found -// in the LICENSE file. - -#![feature(test)] -extern crate test; - -use euler::primes::get_prime_list; - -/// 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×1^2 -/// 15 = 7 + 2×2^2 -/// 21 = 3 + 2×3^2 -/// 25 = 7 + 2×3^2 -/// 27 = 19 + 2×2^2 -/// 33 = 31 + 2×1^2 -///kip -/// 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? - -fn method1() -> usize { - let primes = get_prime_list(100_000); - for num in (9..).step_by(2) { - if primes.binary_search(&num).is_ok() { - continue; - } - - let mut ok = true; - for prime in &primes { - if prime > &num { - ok = false; - break; - } - - ok = true; - let remainder = num - prime; - for i in 1.. { - let s = 2 * i * i; - if s > remainder { - ok = false; - break; - } else if s == remainder { - ok = true; - break; - } - } - - if ok { - //println!("num: {}, prime: {}", num, prime); - break; - } - } - - if !ok { - return num; - } - } - - 0 -} - -fn main() { - println!("method1: {}", method1()); -} - -#[bench] -fn bench_method1(b: &mut test::Bencher) { - b.iter(|| assert_eq!(method1(), 5777)); -} diff --git a/project_euler/src/bin/euler_047.rs b/project_euler/src/bin/euler_047.rs deleted file mode 100644 index b316a172..00000000 --- a/project_euler/src/bin/euler_047.rs +++ /dev/null @@ -1,112 +0,0 @@ -// Copyright (c) 2020 Xu Shaohua . All rights reserved. -// Use of this source is governed by General Public License that can be found -// in the LICENSE file. - -#![feature(test)] -extern crate euler; -extern crate test; - -/// Problem: -/// -/// The first two consecutive numbers to have two distinct prime factors are: -/// -/// 14 = 2 × 7 -/// 15 = 3 × 5 -/// -/// The first three consecutive numbers to have three distinct prime factors are: -/// -/// 644 = 2² × 7 × 23 -/// 645 = 3 × 5 × 43 -/// 646 = 2 × 17 × 19. -/// -/// Find the first four consecutive integers to have four distinct -/// prime factors each. What is the first of these numbers? - -fn method1() -> usize { - let primes = euler::primes::get_prime_list(100_000); - let mut count = 0; - for i in 2.. { - let factors = euler::primes::get_prime_factors(i, &primes); - if factors.len() != 4 { - count = 0; - } else { - count += 1; - if count == 4 { - return i - 3; - } - } - } - - 0 -} - -fn method2() -> usize { - let primes = euler::primes::get_prime_list(100_000); - let mut count = 0; - for i in 2.. { - let factors = euler::primes::get_prime_factor_num(i, &primes); - if factors != 4 { - count = 0; - } else { - count += 1; - if count == 4 { - return i - 3; - } - } - } - - 0 -} - -fn method3() -> usize { - let primes = euler::primes::get_prime_list(100_000); - let mut i = 2; - loop { - let factors = euler::primes::get_prime_factor_num(i, &primes); - if factors != 4 { - i += 1; - continue; - } - - let factors = euler::primes::get_prime_factor_num(i + 3, &primes); - if factors != 4 { - i += 4; - continue; - } - - let factors = euler::primes::get_prime_factor_num(i + 2, &primes); - if factors != 4 { - i += 3; - continue; - } - - let factors = euler::primes::get_prime_factor_num(i + 1, &primes); - if factors != 4 { - i += 2; - continue; - } else { - return i; - } - } -} - -fn main() { - println!("method1: {}", method1()); - println!("method2: {}", method2()); - println!("method3: {}", method3()); -} - -#[bench] -fn bench_method1(b: &mut test::Bencher) { - b.iter(|| assert_eq!(method1(), 134043)); -} - -#[bench] -fn bench_method2(b: &mut test::Bencher) { - b.iter(|| assert_eq!(method2(), 134043)); -} - -#[bench] -fn bench_method3(b: &mut test::Bencher) { - b.iter(|| assert_eq!(method3(), 134043)); -} diff --git a/project_euler/src/bin/euler_048.rs b/project_euler/src/bin/euler_048.rs deleted file mode 100644 index 7093f4c5..00000000 --- a/project_euler/src/bin/euler_048.rs +++ /dev/null @@ -1,60 +0,0 @@ -// Copyright (c) 2020 Xu Shaohua . All rights reserved. -// Use of this source is governed by General Public License that can be found -// in the LICENSE file. - -#![feature(test)] -extern crate num_bigint; -extern crate test; - -use num_bigint::BigUint; -use num_traits::pow::Pow; - -/// Problem: -/// -/// The series, 1^1 + 2^2 + 3^3 + ... + 10^10 = 10405071317. -/// -/// Find the last ten digits of the series, 1^1 + 2^2 + 3^3 + ... + 1000^1000. - -fn method1() -> String { - const MODULE: u64 = 10_000_000_000; - let mut sum: u64 = 0; - for i in 1..=1000 { - let mut product = 1; - for _j in 0..i { - product *= i; - product %= MODULE; - if product == 0 { - break; - } - } - sum += product; - } - - let mut s = sum.to_string(); - s.split_off(s.len() - 10) -} - -fn method2() -> String { - let mut sum = BigUint::default(); - for i in 1_u32..=1000 { - let num = BigUint::from(i).pow(i); - sum += num; - } - let mut s = sum.to_string(); - s.split_off(s.len() - 10) -} - -fn main() { - println!("last 10 digits: {}", method1()); - println!("last 10 digits: {}", method2()); -} - -#[bench] -fn bench_method1(b: &mut test::Bencher) { - b.iter(|| assert_eq!(method1(), "9110846700")); -} - -#[bench] -fn bench_method2(b: &mut test::Bencher) { - b.iter(|| assert_eq!(method2(), "9110846700")); -} diff --git a/project_euler/src/bin/euler_049.rs b/project_euler/src/bin/euler_049.rs deleted file mode 100644 index 2474756a..00000000 --- a/project_euler/src/bin/euler_049.rs +++ /dev/null @@ -1,78 +0,0 @@ -// Copyright (c) 2020 Xu Shaohua . All rights reserved. -// Use of this source is governed by General Public License that can be found -// in the LICENSE file. - -#![feature(test)] -extern crate test; - -use euler::permutation::Permutation; -use euler::primes::get_prime_list; - -/// Problem: -/// -/// The arithmetic sequence, 1487, 4817, 8147, in which each of the terms -/// increases by 3330, is unusual in two ways: (i) each of the three terms -/// are prime, and, (ii) each of the 4-digit numbers are permutations of -/// one another. -/// -/// There are no arithmetic sequences made up of three 1-, 2-, or -/// 3-digit primes, exhibiting this property, but there is one other 4-digit -/// increasing sequence. -/// -/// What 12-digit number do you form by concatenating the three terms in -/// this sequence? - -fn method1() -> Option<(usize, usize, usize)> { - let primes = get_prime_list(10000); - let get_digits = |mut num: usize| -> Vec { - let mut v = vec![]; - while num > 0 { - v.push(num % 10); - num /= 10; - } - v - }; - - for prime in &primes { - if prime < &1000 { - continue; - } - - let mut nums = vec![*prime]; - let p = Permutation::new(get_digits(*prime)); - for digits in p.into_iter() { - let n = digits.iter().fold(0, |prod, i| prod * 10 + i); - if n > 1000 && &n > prime && primes.binary_search(&n).is_ok() { - nums.push(n); - } - } - nums.sort(); - nums.dedup(); - if nums.len() < 3 { - continue; - } - - // combinations - let len = nums.len(); - for i in 0..len - 2 { - for j in i + 1..len - 1 { - for k in j + 1..len { - if nums[j] - nums[i] == nums[k] - nums[j] && nums[i] != 1487 { - return Some((nums[i], nums[j], nums[k])); - } - } - } - } - } - - None -} - -fn main() { - println!("method1: {:?}", method1()); -} - -#[bench] -fn bench_method1(b: &mut test::Bencher) { - b.iter(|| assert_eq!(method1(), Some((2969, 6299, 9629)))); -} diff --git a/project_euler/src/bin/euler_050.rs b/project_euler/src/bin/euler_050.rs deleted file mode 100644 index e930f2f2..00000000 --- a/project_euler/src/bin/euler_050.rs +++ /dev/null @@ -1,59 +0,0 @@ -// Copyright (c) 2020 Xu Shaohua . All rights reserved. -// Use of this source is governed by General Public License that can be found -// in the LICENSE file. - -#![feature(test)] -extern crate test; - -/// Problem: -/// -/// The prime 41, can be written as the sum of six consecutive primes: -/// 41 = 2 + 3 + 5 + 7 + 11 + 13 -/// -/// This is the longest sum of consecutive primes that adds to a prime -/// below one-hundred. -/// -/// The longest sum of consecutive primes below one-thousand that adds to -/// a prime, contains 21 terms, and is equal to 953. -/// -/// Which prime, below one-million, can be written as the sum -/// of the most consecutive primes? - -fn method1() -> usize { - const MAX: usize = 1_000_000; - let primes = euler::primes::get_prime_list(MAX); - let len = primes.len(); - let mut max_consecutive_prime = 0; - let mut max_consecutive_count = 0; - for i in 0..len { - let prime = primes[i]; - for j in 0..i { - let mut count = 0; - let mut sum = 0; - while sum < prime && j + count < i { - sum += primes[j + count]; - count += 1; - } - if count <= max_consecutive_count { - break; - } - if sum == prime { - if count > max_consecutive_count { - max_consecutive_prime = prime; - max_consecutive_count = count; - } - break; - } - } - } - max_consecutive_prime -} - -fn main() { - println!("method1: {}", method1()); -} - -#[bench] -fn bench_method1(b: &mut test::Bencher) { - b.iter(|| assert_eq!(method1(), 997651)); -} diff --git a/project_euler/src/bin/euler_052.rs b/project_euler/src/bin/euler_052.rs deleted file mode 100644 index f89def06..00000000 --- a/project_euler/src/bin/euler_052.rs +++ /dev/null @@ -1,98 +0,0 @@ -// Copyright (c) 2020 Xu Shaohua . All rights reserved. -// Use of this source is governed by General Public License that can be found -// in the LICENSE file. - -#![feature(test)] -extern crate test; - -/// Problem: -/// -/// It can be seen that the number, 125874, and its double, 251748, -/// contain exactly the same digits, but in a different order. -/// -/// Find the smallest positive integer, x, such that 2x, 3x, 4x, 5x, and 6x, -/// contain the same digits. - -fn method1() -> u32 { - let get_digits = |num: u32| { - let mut n = num; - let mut digits: [u8; 8] = [0; 8]; - let mut i = 0; - while n > 9 { - digits[i] = (n % 10) as u8; - i += 1; - n /= 10; - } - digits[i] = n as u8; - digits.sort(); - digits - }; - - for i in 100.. { - let digits = get_digits(i); - if digits == get_digits(i * 2) - && digits == get_digits(i * 3) - && digits == get_digits(i * 4) - && digits == get_digits(i * 5) - && digits == get_digits(i * 6) - { - return i; - } - } - 0 -} - -fn method2() -> u32 { - let get_digits = |num: u32| { - let mut n = num; - let mut digits: [u8; 8] = [0; 8]; - let mut i = 0; - while n > 9 { - digits[i] = (n % 10) as u8; - i += 1; - n /= 10; - } - digits[i] = n as u8; - digits.sort(); - digits - }; - - let get_base = |num: u32| { - let mut n = num; - let mut base = 1; - while n > 9 { - n /= 10; - base += 1; - } - base - }; - - for i in 100.. { - let num = i + 10_u32.pow(get_base(i)); - let digits = get_digits(num); - if digits == get_digits(num * 2) - && digits == get_digits(num * 3) - && digits == get_digits(num * 4) - && digits == get_digits(num * 5) - && digits == get_digits(num * 6) - { - return num; - } - } - 0 -} - -fn main() { - println!("method1: {}", method1()); - println!("method2: {}", method2()); -} - -#[bench] -fn bench_method1(b: &mut test::Bencher) { - b.iter(|| assert_eq!(method1(), 142857)); -} - -#[bench] -fn bench_method2(b: &mut test::Bencher) { - b.iter(|| assert_eq!(method2(), 142857)); -} diff --git a/project_euler/src/bin/euler_053.rs b/project_euler/src/bin/euler_053.rs deleted file mode 100644 index 6075379b..00000000 --- a/project_euler/src/bin/euler_053.rs +++ /dev/null @@ -1,51 +0,0 @@ -// Copyright (c) 2020 Xu Shaohua . All rights reserved. -// Use of this source is governed by General Public License that can be found -// in the LICENSE file. - -#![feature(test)] -extern crate test; - -use num_bigint::BigUint; -use std::ops::Div; - -/// Problem: -/// -/// There are exactly ten ways of selecting three from five, 12345: -/// 123, 124, 125, 134, 135, 145, 234, 235, 245, and 345 -/// -/// In combinatorics, we use the notation, (5/3)=10. -/// -/// In general, (n/r)=n!/ (r!(n−r)!) , where r≤n, n!=n×(n−1)×...×3×2×1, and 0!=1 . -/// -/// It is not until n=23, that a value exceeds one-million: (23/10)=1144066. -/// -/// How many, not necessarily distinct, values of (n/r) for 1≤n≤100, -/// are greater than one-million? - -fn combination(n: u32, r: u32) -> BigUint { - let p1 = ((r + 1)..=n).fold(BigUint::from(1_u32), |prod, i| prod * i); - let p2 = (1..=(n - r)).fold(BigUint::from(1_u32), |prod, i| prod * i); - p1.div(p2) -} - -fn method1() -> u32 { - let mut count = 0; - let threshold = BigUint::from(1_000_000_u32); - for i in 1..=100 { - for j in 1..=i { - if combination(i, j) > threshold { - count += 1; - } - } - } - count -} - -fn main() { - println!("method1: {}", method1()); -} - -#[bench] -fn bench_method1(b: &mut test::Bencher) { - b.iter(|| assert_eq!(method1(), 4075)); -} diff --git a/project_euler/src/bin/euler_056.rs b/project_euler/src/bin/euler_056.rs deleted file mode 100644 index 4781ca52..00000000 --- a/project_euler/src/bin/euler_056.rs +++ /dev/null @@ -1,45 +0,0 @@ -// Copyright (c) 2020 Xu Shaohua . All rights reserved. -// Use of this source is governed by General Public License that can be found -// in the LICENSE file. - -#![feature(test)] -extern crate test; - -use num_bigint::BigUint; -use num_traits::pow::Pow; - -/// Problem: -/// -/// A googol (10100) is a massive number: one followed by one-hundred zeros; -/// 100100 is almost unimaginably large: one followed by two-hundred zeros. -/// Despite their size, the sum of the digits in each number is only 1. -/// -/// Considering natural numbers of the form, ab, where a, b < 100, -/// what is the maximum digital sum? - -fn method1() -> u32 { - let mut largest_sum = 0; - for i in 2..100_u16 { - for j in 2..100_u16 { - let p: BigUint = BigUint::from(i).pow(j); - let len = p - .to_radix_le(10) - .iter() - .map(|num: &u8| -> u32 { *num as u32 }) - .sum(); - if len > largest_sum { - largest_sum = len; - } - } - } - largest_sum -} - -fn main() { - println!("method1: {}", method1()); -} - -#[bench] -fn bench_method1(b: &mut test::Bencher) { - b.iter(|| assert_eq!(method1(), 972)); -} diff --git a/project_euler/src/bin/euler_057.rs b/project_euler/src/bin/euler_057.rs deleted file mode 100644 index 7f824b1b..00000000 --- a/project_euler/src/bin/euler_057.rs +++ /dev/null @@ -1,55 +0,0 @@ -// Copyright (c) 2020 Xu Shaohua . All rights reserved. -// Use of this source is governed by General Public License that can be found -// in the LICENSE file. - -#![feature(test)] -extern crate test; - -use num_bigint::BigUint; - -/// Problem: -/// -/// It is possible to show that the square root of two can be expressed as -/// an infinite continued fraction. -/// -/// √2 = 1 + 1/(2+1/(2+1/2+…)) -/// -/// By expanding this for the first four iterations, we get: -/// -/// 1+1/2 = 3/2 = 1.5 -/// 1+1/(2+1/2) = 7/5 = 1.4 -/// 1+1/(2+1/(2+1/2)) = 17/12 = 1.41666… -/// 1+1/(2+1/(2+1(2+1/2))) = 41/29 = 1.41379… -/// -/// -/// The next three expansions are 99/70, 239/169, and 577/408, but the eighth -/// expansion, 1393/985, is the first example where the number of digits -/// in the numerator exceeds the number of digits in the denominator. -/// -/// In the first one-thousand expansions, how many fractions contain -/// a numerator with more digits than the denominator? - -fn method1() -> u32 { - let mut count = 0; - let mut numerator = BigUint::from(3_u32); - let mut denominator = BigUint::from(2_u32); - let mut tmp; - for _i in 1..1000 { - if numerator.to_string().len() > denominator.to_string().len() { - count += 1; - } - tmp = denominator.clone(); - denominator += &numerator; - numerator += tmp * 2_u32; - } - count -} - -fn main() { - println!("method1: {}", method1()); -} - -#[bench] -fn bench_method1(b: &mut test::Bencher) { - b.iter(|| assert_eq!(method1(), 153)); -} diff --git a/project_euler/src/bin/euler_060.rs b/project_euler/src/bin/euler_060.rs deleted file mode 100644 index 35490831..00000000 --- a/project_euler/src/bin/euler_060.rs +++ /dev/null @@ -1,105 +0,0 @@ -// Copyright (c) 2020 Xu Shaohua . All rights reserved. -// Use of this source is governed by General Public License that can be found -// in the LICENSE file. - -#![feature(test)] -extern crate test; - -use euler::concate_number::ConcateNumber; -use euler::primes::{get_prime_list, IsPrime}; -use std::collections::BTreeMap; - -/// Problem: -/// -/// The primes 3, 7, 109, and 673, are quite remarkable. By taking any -/// two primes and concatenating them in any order the result will always -/// be prime. For example, taking 7 and 109, both 7109 and 1097 are prime. -/// The sum of these four primes, 792, represents the lowest sum for a set -/// of four primes with this property. -/// -/// Find the lowest sum for a set of five primes for which any two primes -/// concatenate to produce another prime. - -fn method1() -> usize { - const MAX: usize = 10_000; - let primes = get_prime_list(MAX); - - let is_prime = |num: usize| -> bool { primes.binary_search(&num).is_ok() }; - - type PrimePair = Vec; - let mut prime_maps: BTreeMap = BTreeMap::new(); - - for p1 in &primes { - let mut prime_pair = PrimePair::new(); - for p2 in &primes { - if p1 < p2 { - let c1 = p1.concate(*p2); - let c2 = p2.concate(*p1); - if c1 > MAX || c2 > MAX { - if c1.is_prime() && c2.is_prime() { - prime_pair.push(*p2); - } - } else { - if is_prime(c1) && is_prime(c2) { - prime_pair.push(*p2); - } - } - } - } - - if prime_pair.len() > 3 { - prime_maps.insert(*p1, prime_pair); - } - } - - // TODO(Shaohua): Replace with combination - for (p0, pair0) in prime_maps.iter() { - for p1 in pair0 { - if let Some(pair1) = prime_maps.get(&p1) { - for p2 in pair1 { - if !pair0.contains(p2) { - continue; - } - if let Some(pair2) = prime_maps.get(&p2) { - for p3 in pair2 { - if !pair0.contains(p3) { - continue; - } - if !pair1.contains(p3) { - continue; - } - println!("{}, {}, {}, {}", p0, p1, p2, p3); - - if let Some(pair3) = prime_maps.get(&p3) { - for p4 in pair3 { - if !pair0.contains(p4) { - continue; - } - if !pair1.contains(p4) { - continue; - } - if !pair2.contains(p4) { - continue; - } - println!("{}, {}, {}, {}, {}", p0, p1, p2, p3, p4); - return p0 + p1 + p2 + p3 + p4; - } - } - } - } - } - } - } - } - - 0 -} - -fn main() { - println!("method1: {}", method1()); -} - -#[bench] -fn bench_method1(b: &mut test::Bencher) { - b.iter(|| assert_eq!(method1(), 26033)); -} diff --git a/project_euler/src/bin/euler_063.rs b/project_euler/src/bin/euler_063.rs deleted file mode 100644 index e186caf8..00000000 --- a/project_euler/src/bin/euler_063.rs +++ /dev/null @@ -1,42 +0,0 @@ -// Copyright (c) 2020 Xu Shaohua . All rights reserved. -// Use of this source is governed by General Public License that can be found -// in the LICENSE file. - -#![feature(test)] -extern crate test; - -use euler::digits::CountDigits; - -/// Problem: -/// -/// The 5-digit number, 16807=7^5, is also a fifth power. Similarly, -/// the 9-digit number, 134217728=8^9, is a ninth power. -/// -/// How many n-digit positive integers exist which are also an nth power? - -fn method1() -> u32 { - let mut count = 0; - // Obveriously root number cannot be larger than 10 - for i in 1..10_u128 { - for j in 1_u32.. { - let p = i.pow(j); - let n_digits = p.count_digits() as u32; - if j == n_digits { - println!("{} = {}^{}", p, i, j); - count += 1; - } else if j > n_digits { - break; - } - } - } - count -} - -fn main() { - println!("method1: {}", method1()); -} - -#[bench] -fn bench_method1(b: &mut test::Bencher) { - b.iter(|| assert_eq!(method1(), 49)); -} diff --git a/project_euler/src/bin/euler_092.rs b/project_euler/src/bin/euler_092.rs deleted file mode 100644 index 4471d4fb..00000000 --- a/project_euler/src/bin/euler_092.rs +++ /dev/null @@ -1,87 +0,0 @@ -// Copyright (c) 2020 Xu Shaohua . All rights reserved. -// Use of this source is governed by General Public License that can be found -// in the LICENSE file. - -#![feature(test)] -extern crate test; - -/// Problem: -/// -/// A number chain is created by continuously adding the square of the digits -/// in a number to form a new number until it has been seen before. -/// -/// For example, -/// -/// 44 → 32 → 13 → 10 → 1 → 1 -/// 85 → 89 → 145 → 42 → 20 → 4 → 16 → 37 → 58 → 89 -/// -/// Therefore any chain that arrives at 1 or 89 will become stuck in an -/// endless loop. What is most amazing is that EVERY starting number will -/// eventually arrive at 1 or 89. -/// -/// How many starting numbers below ten million will arrive at 89? - -fn method1() -> u64 { - let mut count = 0; - for i in 1..10_000_000_u32 { - let mut s = get_square_digit(i); - while s != 89 && s != 1 { - s = get_square_digit(s); - } - if s == 89 { - count += 1; - } - } - - count -} - -fn get_square_digit(mut num: u32) -> u32 { - let mut r; - let mut sum = 0; - while num >= 10 { - r = num % 10; - num /= 10; - sum += r * r; - } - sum + num * num -} - -fn method2() -> u64 { - let mut cache: [bool; 1000] = [false; 1000]; - - let mut count = 0; - for i in 1..10_000_000_u32 { - let mut s = get_square_digit(i); - while s != 89 && s != 1 { - if cache[s as usize] { - s = 89; - break; - } - s = get_square_digit(s); - } - if s == 89 { - count += 1; - if i < 1000 { - cache[i as usize] = true; - } - } - } - - count -} - -fn main() { - println!("method1: {}", method1()); - println!("method2: {}", method2()); -} - -#[bench] -fn bench_method1(b: &mut test::Bencher) { - b.iter(|| assert_eq!(method1(), 8581146)); -} - -#[bench] -fn bench_method2(b: &mut test::Bencher) { - b.iter(|| assert_eq!(method2(), 8581146)); -} diff --git a/project_euler/src/bin/todo.md b/project_euler/src/bin/todo.md deleted file mode 100644 index 9b9749b9..00000000 --- a/project_euler/src/bin/todo.md +++ /dev/null @@ -1,8 +0,0 @@ - -## graph -- [ ] 015 -- [ ] 018 -- [ ] 067 - -## permutation -- [ ] 24 diff --git a/project_euler/src/concate_number.rs b/project_euler/src/concate_number.rs deleted file mode 100644 index 9f80cfc9..00000000 --- a/project_euler/src/concate_number.rs +++ /dev/null @@ -1,38 +0,0 @@ -// Copyright (c) 2020 Xu Shaohua . All rights reserved. -// Use of this source is governed by General Public License that can be found -// in the LICENSE file. - -pub trait ConcateNumber { - fn concate(&self, other: Self) -> Self; -} - -macro_rules! concate_number_impl { - ( $( $t:ident )* ) => { - $( - impl ConcateNumber for $t { - fn concate(&self, other: Self) -> Self { - let mut shift = 1; - let mut q = other; - while q >= 10 { - q /= 10; - shift += 1; - } - self * (10 as $t).pow(shift) + other - } - } - )* - }; -} - -concate_number_impl!(u8 u16 u32 usize u64 u128); - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn test_concate_number() { - assert_eq!(12_u32.concate(42), 1242); - assert_eq!(42_u64.concate(10), 4210); - } -} diff --git a/project_euler/src/digits.rs b/project_euler/src/digits.rs deleted file mode 100644 index a1ddf4d5..00000000 --- a/project_euler/src/digits.rs +++ /dev/null @@ -1,51 +0,0 @@ -// Copyright (c) 2020 Xu Shaohua . All rights reserved. -// Use of this source is governed by General Public License that can be found -// in the LICENSE file. - -pub trait CountDigits { - fn count_digits(&self) -> u16; -} - -macro_rules! count_digits_impl { - ( $( $t:ident )* ) => { - $( - impl CountDigits for $t { - fn count_digits(&self) -> u16 { - let mut count = 1; - let mut n = *self; - while n >= 10 { - count += 1; - n /= 10; - } - count - } - } - )* - }; -} - -count_digits_impl!(u8 u16 u32 u64 u128); - -pub trait GetDigits { - fn get_digits(&self, buf: &mut Vec) -> usize; -} - -macro_rules! get_digits_impl { - ( $( $t:ident )* ) => { - $( - impl GetDigits for $t { - fn get_digits(&self, buf: &mut Vec) -> usize { - let mut n = *self; - let old_len = buf.len(); - while n > 0 { - buf.push((n % 10) as u8); - n /= 10; - } - buf.len() - old_len - } - } - )* - }; -} - -get_digits_impl!(u8 u16 u32 u64 u128); diff --git a/project_euler/src/gcd.rs b/project_euler/src/gcd.rs deleted file mode 100644 index a0d7791a..00000000 --- a/project_euler/src/gcd.rs +++ /dev/null @@ -1,80 +0,0 @@ -// Copyright (c) 2020 Xu Shaohua . All rights reserved. -// Use of this source is governed by General Public License that can be found -// in the LICENSE file. - -pub trait Gcd { - type Output; - fn gcd(self, denominator: Denominator) -> Self::Output; -} - -macro_rules! gcd_impl { - ( $( $t:ident )* ) => { - $( - impl Gcd for $t { - type Output = $t; - - /// Implemented based on the Euclidean Algorithm - fn gcd(self, denominator: $t) -> $t { - assert!(self > 0); - assert!(denominator > 0); - let (mut n, mut d) = if self > denominator { - (self, denominator) - } else { - (denominator, self) - }; - - while d != 0 { - let r = n % d; - n = d; - d = r; - } - - n - } - } - )* - }; -} - -gcd_impl!(u8 i8 u16 i16 u32 i32 usize isize u64 i64 u128 i128); - -pub trait Lcm { - type Output; - fn lcm(self, denominator: Denominator) -> Self::Output; -} - -macro_rules! lcm_impl { - ( $( $t:ident )* ) => { - $( - impl Lcm for $t { - type Output = $t; - - /// Based on the theorem: `a * b = gcd(a, b) * lcm(a, b)` - fn lcm(self, denominator: $t) -> $t { - let gcd = self.gcd(denominator); - self / gcd * denominator - } - } - )* - }; -} - -lcm_impl!(u8 i8 u16 i16 u32 i32 usize isize u64 i64 u128 i128); - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn test_gcd() { - assert_eq!(i8::gcd(8, 16), 8); - assert_eq!(u64::gcd(42, 21), 21); - } - - #[test] - fn test_lcm() { - assert_eq!(i8::lcm(8, 16), 16); - assert_eq!(u64::lcm(42, 21), 42); - assert_eq!(u64::lcm(42, 21), 42); - } -} diff --git a/project_euler/src/lib.rs b/project_euler/src/lib.rs deleted file mode 100644 index 012efe2c..00000000 --- a/project_euler/src/lib.rs +++ /dev/null @@ -1,9 +0,0 @@ -// Copyright (c) 2020 Xu Shaohua . All rights reserved. -// Use of this source is governed by General Public License that can be found -// in the LICENSE file. - -pub mod concate_number; -pub mod digits; -pub mod gcd; -pub mod permutation; -pub mod primes; diff --git a/project_euler/src/permutation.rs b/project_euler/src/permutation.rs deleted file mode 100644 index e0ca8d3f..00000000 --- a/project_euler/src/permutation.rs +++ /dev/null @@ -1,112 +0,0 @@ -// Copyright (c) 2020 Xu Shaohua . All rights reserved. -// Use of this source is governed by General Public License that can be found -// in the LICENSE file. - -//! Heap's algorithms to generate all possible permutations of n objects. -//! See: https://en.wikipedia.org/wiki/Heap%27s_algorithm - -#[derive(Clone, Debug)] -pub struct Permutation { - data: Vec, - swaps: Vec, - index: usize, -} - -impl Permutation { - pub fn new(data: Vec) -> Permutation { - let len = data.len(); - Permutation { - data, - swaps: vec![0; len], - index: 0, - } - } -} - -// TODO(Shaohua): Returns references only. -impl Iterator for Permutation { - type Item = Vec; - - fn next(&mut self) -> Option { - if self.index > 0 { - loop { - if self.index >= self.swaps.len() { - return None; - } - if self.swaps[self.index] < self.index { - break; - } - self.swaps[self.index] = 0; - self.index += 1; - } - - let pos = (self.index & 1) * self.swaps[self.index]; - self.data.swap(self.index, pos); - self.swaps[self.index] += 1; - } - self.index = 1; - Some(self.data.clone()) - } -} - -#[derive(Debug)] -pub struct Combination { - chunk_len: u32, - min: u32, - mask: u32, - data: Vec, -} - -impl Combination { - pub fn new(chunk_len: u32, data: Vec) -> Self { - let len = data.len() as u32; - let min = 2_u32.pow(chunk_len) - 1; - // FIXME(Shaohua): multiply overflow for large vectors. - let max = 2_u32.pow(len) - 2_u32.pow(len - chunk_len); - - Combination { - chunk_len, - min: min as u32, - mask: max as u32, - data, - } - } - - fn get_chunk(&self) -> Vec { - let b = format!("{:01$b}", self.mask, self.data.len()); - b.chars() - .enumerate() - .filter(|&(_, e)| e == '1') - .map(|(i, _)| self.data[i].clone()) - .collect() - } -} - -// TODO(Shaohua): Returns reference. -impl Iterator for Combination { - type Item = Vec; - - fn next(&mut self) -> Option { - while self.mask >= self.min { - if self.mask.count_ones() == self.chunk_len { - let res = self.get_chunk(); - self.mask -= 1; - return Some(res); - } - self.mask -= 1; - } - None - } -} - -#[cfg(test)] -mod tests { - use super::Permutation; - - #[test] - fn test_permutation() { - let arr = vec![1, 2, 3, 5, 8]; - let p = Permutation::new(arr); - assert_eq!(p.into_iter().count(), 120); - } -} diff --git a/project_euler/src/primes.rs b/project_euler/src/primes.rs deleted file mode 100644 index e68f11a9..00000000 --- a/project_euler/src/primes.rs +++ /dev/null @@ -1,181 +0,0 @@ -pub fn get_prime_list(max_num: usize) -> Vec { - let mut list = vec![true; max_num + 1]; - let sqrt = (max_num as f64).sqrt() as usize; - let mut mul; - for i in 2..(sqrt + 2) { - for j in 2..max_num { - mul = i * j; - if mul > max_num { - break; - } - list[mul] = false; - } - } - - let mut result = vec![]; - for i in 2..max_num { - if list[i] { - result.push(i); - } - } - - result -} - -pub trait IsPrime { - fn is_prime(&self) -> bool; -} - -macro_rules! is_prime_impl { - ( $( $t:ident )* ) => { - $( - impl IsPrime for $t { - fn is_prime(&self) -> bool { - if self <= &0 { - return false; - } - if self % 2 == 0 { - return false; - } - - let mut d = 3; - while &(d * d) <= self { - if self % d == 0 { - return false; - } - d += 2; - } - return true; - } - } - )* - }; -} - -is_prime_impl!(u8 i8 u16 i16 u32 i32 usize isize u64 i64 u128 i128); - -#[derive(Debug, Clone, Copy)] -pub struct PrimeFactor { - pub num: usize, - pub count: u16, -} - -pub fn get_prime_factors(num: usize, primes: &[usize]) -> Vec { - let mut result = Vec::::new(); - let mut rem = num; - let root = (num as f64).sqrt().ceil() as usize; - for p in primes { - if rem == 1 { - break; - } - if p > &root { - if rem > 1 { - result.push(PrimeFactor { num: rem, count: 1 }); - } - break; - } - let mut prime_factor = PrimeFactor { num: *p, count: 0 }; - while rem != 1 { - if rem % *p == 0 { - prime_factor.count += 1; - rem /= *p; - } else { - break; - } - } - if prime_factor.count > 0 { - result.push(prime_factor); - } - } - - result -} - -pub trait GetFactors { - type Output; - fn get_factors(self) -> Self::Output; - fn get_factors_cache(self, v: &mut Self::Output); -} - -macro_rules! get_factors_impl { - ( $( $t:ident )* ) => { - $( - impl GetFactors for $t { - type Output = Vec<$t>; - fn get_factors(self) -> Self::Output { - let mut factors = Vec::new(); - if self <= 0 { - return factors; - } - for i in 1..self { - if self % i == 0 { - factors.push(i); - } - } - return factors; - } - - fn get_factors_cache(self, v: &mut Self::Output) { - v.clear(); - if self <= 0 { - return; - } - for i in 1..self { - if self % i == 0 { - v.push(i); - } - } - } - } - )* - }; -} -get_factors_impl!(u8 i8 u16 i16 u32 i32 usize isize u64 i64 u128 i128); - -pub fn get_prime_factor_num(num: usize, primes: &[usize]) -> u32 { - let mut count = 0; - let mut rem = num; - let root = (num as f64).sqrt().ceil() as usize; - for p in primes { - if rem == 1 { - break; - } - if p > &root { - if rem > 1 { - count += 1; - } - break; - } - let mut is_factor = false; - while rem != 1 { - if rem % *p == 0 { - rem /= *p; - is_factor = true; - } else { - break; - } - } - if is_factor { - count += 1; - } - } - - count -} - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn test_get_factors() { - let factors = 12_u32.get_factors(); - assert_eq!(factors, vec![1, 2, 3, 4, 6]); - } - - #[test] - fn test_is_prime() { - assert!(31_u32.is_prime()); - assert!(!64_u16.is_prime()); - } -} diff --git a/project_euler/todo.md b/project_euler/todo.md deleted file mode 100644 index 72c6b2d5..00000000 --- a/project_euler/todo.md +++ /dev/null @@ -1,4 +0,0 @@ - -# TODO -- remove num-bigint from deps -- remove num-traits from deps