2025 – Ongoing
When I found out about Project Euler I was especially interested in the challenge to solve a
problem efficiently. Below is how I have gone about approaching the problems I have solved so
far. Project Euler allows problems 1 to 100 to be shared for educational purposes, and I am a
big fan of allowing others the ability to have that "aha!" moment as well so I have removed
function calls and any outputted answers.
For more information, check out the Project Euler site here. (opens in a new tab)
(opens Project Euler in a new tab) 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 main() {
let mut multiples_sum = 0;
for i in 0..1000 {
if i % 3 == 0 || i % 5 == 0 {
multiples_sum += i;
}
}
}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 get_even_fib_sum(max_val: i32) -> i32 {
let mut even_sum = 2;
let mut sequence = [1, 2, 3];
while sequence[2] < max_val {
sequence = [sequence[1], sequence[2], sequence[1] + sequence[2]];
if sequence[2] % 2 == 0 {
even_sum += sequence[2];
}
}
even_sum
}The prime factors of 13195 are 5, 7, 13 and 29.
What is the largest prime factor of the number 600851475143?
// function to determine if number is prime
fn is_prime(n: i64) -> bool {
if n % 2 == 0 {
return false;
}
if n == 3 {
return true;
}
let mut search_val = 3;
let max_val = ((n as f64).sqrt().ceil() as i64) + 1;
while search_val <= max_val {
if n % search_val == 0 {
return false
}
search_val += 2;
}
return true;
}
// start at the maximum possible prime number, then work
// down until the first prime is found
fn largest_prime(num: i64) -> i64 {
let mut val = (num as f64).sqrt().ceil() as i64 + 1;
while val > 0 {
if (num % val) == 0 {
if is_prime(val) {
return val
}
}
val -= 1;
}
1
}A palindromic number reads the same both ways. The largest palindrome made from the product of two 2-digit numbers is 9009 = 91 × 99.
Find the largest palindrome made from the product of two 3-digit numbers.
// function to determine if a number is a palindrome
fn is_palindrome(num: i64) -> bool {
// convert to string
let num_string = num.to_string();
// store in vector
let num_vec = num_string.split("").collect::<Vec<_>>();
// start on either ends of the vector, check if values are the same
let (mut start, mut end) = (1, num_vec.len() - 2);
while start < end {
// if any do not match, return false
if num_vec[start] != num_vec[end] {
return false
}
start += 1;
end -= 1;
}
return true
}
// finds the largest palindromic number made from the products
// of two numbers that are each digit_num in length
fn largest_palindrome(digit_num: u32) -> i64{
let (mut digit1, mut digit2) = (0, 0);
let mut largest_pal: i64 = 0;
// max val that is digit_num number of digits
let max_val = 1 * (10i32.pow(digit_num)) - 1;
// iterate through the combinations of numbers that are digit_num in length
for x1 in 0..=max_val / 10 {
for x2 in 0..=max_val / 10 {
let product: i64 = (max_val - x1) as i64 * (max_val - x2) as i64;
if is_palindrome(product) {
if max_val - x1 >= digit1 || max_val - x2 >= digit2 {
if product > largest_pal {
largest_pal = product;
(digit1, digit2) = (max_val - x1, max_val - x2);
}
}
// end if both values that are multiplied are less than the
// current max palindromic number factors
else if max_val - x1 < digit1 && max_val - x2 < digit2{
break
}
}
}
}
return largest_pal;
}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?
// div_by_all takes num as input and finds the smallest positive number that is
// evenly divisible by all numbers from 1 to num
fn div_by_all(num: i64) -> i64 {
// set value equal to max number to be divided by
let mut test_val = num;
// begin loop to check for each value of test_val, increment by num each loop
loop {
for i in 2..=num {
if test_val % i != 0 {
break;
}
// if all numbers are checked, the number has been found
else if i == num {
return test_val;
}
}
test_val += num;
}
}The sum of the squares of the first ten natural numbers is: 1² + 2² + … + 10² = 385
The square of the sum of the first ten natural numbers is: (1 + 2 + … + 10)² = 55² = 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 sum_square_diff(num: i32) -> i32 {
let mut sum_of_squares = 0;
let mut square_of_sum = 0;
for x in 1..=num {
sum_of_squares += x.pow(2);
square_of_sum += x;
}
square_of_sum = square_of_sum.pow(2);
square_of_sum - sum_of_squares
}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 is_prime(n: i64) -> bool {
if n % 2 == 0 {
return false;
}
if n == 3 {
return true;
}
let mut search_val = 3 as i64;
let max_val = ((n as f64).sqrt().ceil() as i64) + 1;
while search_val <= max_val {
if n % search_val == 0 {
return false;
}
search_val += 2;
}
return true;
}
fn find_nth_prime(n: i64) -> i64{
let mut curr_prime = 1;
let mut x = 1;
while curr_prime < n {
x += 2;
if is_prime(x) {
curr_prime += 1;
}
}
x
}A Pythagorean triplet is a set of three natural numbers, a < b < c, for which a² + b² = c².
For example, 3² + 4² = 9 + 16 = 25 = 5².
There exists exactly one Pythagorean triplet for which a + b + c = 1000. Find the product abc.
// return true if the triplet is a Pythagorean triplet
fn is_triplet(a: i32, b: i32, c: i32) -> bool {
if a < b && b < c {
if a.pow(2) + b.pow(2) == c.pow(2) {
return true
}
}
false
}
fn find_triplets(sum_val: i32) -> (i32, i32, i32) {
let (mut a, mut b, mut c) = (1, 2, sum_val - 3);
while a < b {
while b < c {
if is_triplet(a, b, c){
return (a, b, c)
}
(b, c) = (b + 1, c - 1);
}
(a, b) = (a + 1, a + 2);
c = sum_val - a - b;
}
(a, b, c)
}Work out the first ten digits of the sum of the following one-hundred 50-digit numbers (listed below).
fn find_large_sum(numbers: Vec<&str>) -> String {
let mut sum = String::new();
let (mut processed_nums, mut remainder) = (0, 0);
// create copy of vector to perform pop operation on
let mut numbers_list: Vec<String> = vec![];
for number in 0..numbers.len() {
numbers_list.push(numbers[number].to_string());
}
while processed_nums < numbers.len(){
processed_nums = 0;
// pop last digit of each number, add it to the remainder value
for num in 0..numbers_list.len() {
let digit = numbers_list[num].pop();
if digit.is_some() {
remainder += digit.unwrap().to_digit(10).unwrap();
}
// once all values no longer have a number to pop, we know we are done
else{
processed_nums += 1;
}
}
sum = (remainder % 10).to_string() + ∑
remainder = remainder / 10;
}
// put rest of remainder on front of number
sum = remainder.to_string() + ∑
sum
}
let numbers = vec![
"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",
];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 10,000.
fn sum_amicable_nums(val: i32) -> i32 {
let mut amicable_sum = 0;
let mut known_amicables: Vec<i32> = Vec::new();
for a in 1..=val {
let da = find_divisor_sum(a);
if !known_amicables.contains(&a) && !known_amicables.contains(&da){
let db = find_divisor_sum(da);
if (a == db) && (da != a) && (a < 10000) && (da < 10000){
known_amicables.push(a);
known_amicables.push(da);
amicable_sum += a + da;
}
}
}
amicable_sum
}
fn find_divisor_sum(val: i32) -> i32 {
let mut divisor_sum = 0;
for x in 1..=(val / 2) + 1{
if val % x == 0 {
divisor_sum += x;
}
}
divisor_sum
}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 is_abundant(val: i32) -> bool {
let mut div_sum: i32 = 1;
for x in 2..=val / 2 {
if val % x == 0 {
div_sum += x;
}
}
if div_sum > val {
true
}
else {
false
}
}
fn find_abundant_nums(max: i32) -> Vec<i32> {
let mut abundant_nums: Vec<i32> = Vec::new();
for x in 1..=max {
if is_abundant(x){
abundant_nums.push(x);
}
}
abundant_nums
}
fn find_abundant_sums(abundant_nums: Vec<i32>, max: i32) -> Vec<i32> {
let mut abundant_sums: Vec<i32> = vec![0; max as usize];
for x in 0..abundant_nums.len() {
for y in x..abundant_nums.len() {
let sum = abundant_nums[x] + abundant_nums[y];
if sum < max {
abundant_sums[sum as usize] = 1;
}
}
}
abundant_sums
}
fn find_non_sums_sum(abundant_sums: Vec<i32>) -> usize {
let mut sum: usize = 0;
for val in 1..abundant_sums.len() {
if abundant_sums[val] == 0 {
sum += val;
}
}
sum
}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 factorial(val: usize) -> usize {
let mut product = 1;
for x in 1..=val {
product *= x;
}
product
}
fn find_lexicographic_permutation(mut digits: Vec::<usize>, mut p_target: usize) -> usize {
let mut permutation = String::from("");
p_target -= 1;
for _x in 1..digits.len() {
let digit = p_target / factorial(digits.len() - 1);
permutation = format!("{}{}", &permutation, digits[digit]);
digits.remove(digit);
p_target %= factorial(digits.len());
}
if digits == [0] {
permutation = format!("{}{}", &permutation, 0);
}
permutation.parse::<usize>().unwrap()
}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 longest_recurring_cycle (val: f64) {
let mut d = 2;
for x in 2..val as i32 {
let fraction: f64 = 1.0 / x as f64;
println!("x: {}, {:.}", x, fraction);
}
}
fn main() {
let start = std::time::Instant::now();
longest_recurring_cycle(1000 as f64);
println!("Elapsed: {:?}", start.elapsed());
}Problems from projecteuler.net(opens in a new tab), licensed under CC BY-NC-SA 4.0(opens in a new tab).