Did some project euler
This commit is contained in:
		
							
								
								
									
										21
									
								
								src/bin/problem_10.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								src/bin/problem_10.rs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,21 @@
 | 
			
		||||
fn main() {
 | 
			
		||||
    let mut primes = vec![];
 | 
			
		||||
 | 
			
		||||
    for n in 2..=2_000_000 {
 | 
			
		||||
        let prime_check_max = (n as f64).sqrt().ceil() as usize;
 | 
			
		||||
        let mut is_prime = true;
 | 
			
		||||
        for prime in primes.clone() {
 | 
			
		||||
            if n % prime == 0 {
 | 
			
		||||
                is_prime = false;
 | 
			
		||||
                break;
 | 
			
		||||
            } else if prime > prime_check_max {
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        if is_prime {
 | 
			
		||||
            primes.push(n);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    println!("{}", primes.iter().sum::<usize>());
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										83
									
								
								src/bin/problem_11.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										83
									
								
								src/bin/problem_11.rs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,83 @@
 | 
			
		||||
fn main() {
 | 
			
		||||
    let grid = get_grid();
 | 
			
		||||
    let greatests = [find_h(grid.clone()), find_v(grid.clone()), find_diag_lr(grid.clone()), find_diag_rl(grid)];
 | 
			
		||||
    println!("{}", greatests.iter().max().unwrap());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
fn get_grid() -> Vec<Vec<usize>> {
 | 
			
		||||
    vec![
 | 
			
		||||
        vec![08, 02, 22, 97, 38, 15, 00, 40, 00, 75, 04, 05, 07, 78, 52, 12, 50, 77, 91, 08],
 | 
			
		||||
        vec![49, 49, 99, 40, 17, 81, 18, 57, 60, 87, 17, 40, 98, 43, 69, 48, 04, 56, 62, 00],
 | 
			
		||||
        vec![81, 49, 31, 73, 55, 79, 14, 29, 93, 71, 40, 67, 53, 88, 30, 03, 49, 13, 36, 65],
 | 
			
		||||
        vec![52, 70, 95, 23, 04, 60, 11, 42, 69, 24, 68, 56, 01, 32, 56, 71, 37, 02, 36, 91],
 | 
			
		||||
        vec![22, 31, 16, 71, 51, 67, 63, 89, 41, 92, 36, 54, 22, 40, 40, 28, 66, 33, 13, 80],
 | 
			
		||||
        vec![24, 47, 32, 60, 99, 03, 45, 02, 44, 75, 33, 53, 78, 36, 84, 20, 35, 17, 12, 50],
 | 
			
		||||
        vec![32, 98, 81, 28, 64, 23, 67, 10, 26, 38, 40, 67, 59, 54, 70, 66, 18, 38, 64, 70],
 | 
			
		||||
        vec![67, 26, 20, 68, 02, 62, 12, 20, 95, 63, 94, 39, 63, 08, 40, 91, 66, 49, 94, 21],
 | 
			
		||||
        vec![24, 55, 58, 05, 66, 73, 99, 26, 97, 17, 78, 78, 96, 83, 14, 88, 34, 89, 63, 72],
 | 
			
		||||
        vec![21, 36, 23, 09, 75, 00, 76, 44, 20, 45, 35, 14, 00, 61, 33, 97, 34, 31, 33, 95],
 | 
			
		||||
        vec![78, 17, 53, 28, 22, 75, 31, 67, 15, 94, 03, 80, 04, 62, 16, 14, 09, 53, 56, 92],
 | 
			
		||||
        vec![16, 39, 05, 42, 96, 35, 31, 47, 55, 58, 88, 24, 00, 17, 54, 24, 36, 29, 85, 57],
 | 
			
		||||
        vec![86, 56, 00, 48, 35, 71, 89, 07, 05, 44, 44, 37, 44, 60, 21, 58, 51, 54, 17, 58],
 | 
			
		||||
        vec![19, 80, 81, 68, 05, 94, 47, 69, 28, 73, 92, 13, 86, 52, 17, 77, 04, 89, 55, 40],
 | 
			
		||||
        vec![04, 52, 08, 83, 97, 35, 99, 16, 07, 97, 57, 32, 16, 26, 26, 79, 33, 27, 98, 66],
 | 
			
		||||
        vec![88, 36, 68, 87, 57, 62, 20, 72, 03, 46, 33, 67, 46, 55, 12, 32, 63, 93, 53, 69],
 | 
			
		||||
        vec![04, 42, 16, 73, 38, 25, 39, 11, 24, 94, 72, 18, 08, 46, 29, 32, 40, 62, 76, 36],
 | 
			
		||||
        vec![20, 69, 36, 41, 72, 30, 23, 88, 34, 62, 99, 69, 82, 67, 59, 85, 74, 04, 36, 16],
 | 
			
		||||
        vec![20, 73, 35, 29, 78, 31, 90, 01, 74, 31, 49, 71, 48, 86, 81, 16, 23, 57, 05, 54],
 | 
			
		||||
        vec![01, 70, 54, 71, 83, 51, 54, 69, 16, 92, 33, 48, 61, 43, 52, 01, 89, 19, 67, 48],
 | 
			
		||||
    ]
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
fn find_h(grid: Vec<Vec<usize>>) -> usize {
 | 
			
		||||
    let mut greatest = 0;
 | 
			
		||||
    for line in grid {
 | 
			
		||||
        let greatest_in_line = line.windows(4).map(|nums| { nums.iter().product::<usize>() }).max().unwrap();
 | 
			
		||||
        if greatest_in_line > greatest {
 | 
			
		||||
            greatest = greatest_in_line;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    greatest
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
fn find_v(grid: Vec<Vec<usize>>) -> usize {
 | 
			
		||||
    let mut greatest = 0;
 | 
			
		||||
    let side_len = grid.len();
 | 
			
		||||
    for line_quadruplets in grid.windows(4) {
 | 
			
		||||
        for idx in 0..side_len {
 | 
			
		||||
            let prod = line_quadruplets[0][idx] *  line_quadruplets[1][idx] * line_quadruplets[2][idx] * line_quadruplets[3][idx];
 | 
			
		||||
            if prod > greatest {
 | 
			
		||||
                greatest = prod;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    greatest
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
fn find_diag_lr(grid: Vec<Vec<usize>>) -> usize {
 | 
			
		||||
    let mut greatest = 0;
 | 
			
		||||
    let side_len = grid.len();
 | 
			
		||||
    for line_quadruplets in grid.windows(4) {
 | 
			
		||||
        for idx in 0..side_len-3 {
 | 
			
		||||
            let prod = line_quadruplets[0][idx] *  line_quadruplets[1][idx+1] * line_quadruplets[2][idx+2] * line_quadruplets[3][idx+3];
 | 
			
		||||
            if prod > greatest {
 | 
			
		||||
                greatest = prod;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    greatest
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
fn find_diag_rl(grid: Vec<Vec<usize>>) -> usize {
 | 
			
		||||
    let mut greatest = 0;
 | 
			
		||||
    let side_len = grid.len();
 | 
			
		||||
    for line_quadruplets in grid.windows(4) {
 | 
			
		||||
        for idx in 3..side_len {
 | 
			
		||||
            let prod = line_quadruplets[0][idx] *  line_quadruplets[1][idx-1] * line_quadruplets[2][idx-2] * line_quadruplets[3][idx-3];
 | 
			
		||||
            if prod > greatest {
 | 
			
		||||
                greatest = prod;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    greatest
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										29
									
								
								src/bin/problem_12.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										29
									
								
								src/bin/problem_12.rs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,29 @@
 | 
			
		||||
fn main() {
 | 
			
		||||
    let mut n = 1;
 | 
			
		||||
    loop {
 | 
			
		||||
        let triangular_num = triangular(n);
 | 
			
		||||
        let divisors = get_divisors(triangular_num);
 | 
			
		||||
        if divisors.len() > 500 {
 | 
			
		||||
            println!("{triangular_num}");
 | 
			
		||||
            break;
 | 
			
		||||
        }
 | 
			
		||||
        n +=1;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
fn triangular(nth: usize) -> usize {
 | 
			
		||||
    (1..=nth).sum::<usize>()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
fn get_divisors(n: usize) -> Vec<usize> {
 | 
			
		||||
    let mut divisors = vec![1];
 | 
			
		||||
    let mut potential_divisor = 2;
 | 
			
		||||
    while (potential_divisor * potential_divisor) < n {
 | 
			
		||||
        if n % potential_divisor == 0 {
 | 
			
		||||
            divisors.push(potential_divisor);
 | 
			
		||||
            divisors.push(n / potential_divisor);
 | 
			
		||||
        }
 | 
			
		||||
        potential_divisor = potential_divisor + 1;
 | 
			
		||||
    }
 | 
			
		||||
    divisors
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										114
									
								
								src/bin/problem_13.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										114
									
								
								src/bin/problem_13.rs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,114 @@
 | 
			
		||||
use project_euler::number::Number;
 | 
			
		||||
 | 
			
		||||
fn main() {
 | 
			
		||||
    let mut sum = Number::from(0);
 | 
			
		||||
    for number in get_nums() {
 | 
			
		||||
        sum = sum + number;
 | 
			
		||||
    }
 | 
			
		||||
    println!("{sum}");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
fn get_nums() -> Vec<Number> {
 | 
			
		||||
    vec![
 | 
			
		||||
        Number::from("37107287533902102798797998220837590246510135740250"),
 | 
			
		||||
        Number::from("46376937677490009712648124896970078050417018260538"),
 | 
			
		||||
        Number::from("74324986199524741059474233309513058123726617309629"),
 | 
			
		||||
        Number::from("91942213363574161572522430563301811072406154908250"),
 | 
			
		||||
        Number::from("23067588207539346171171980310421047513778063246676"),
 | 
			
		||||
        Number::from("89261670696623633820136378418383684178734361726757"),
 | 
			
		||||
        Number::from("28112879812849979408065481931592621691275889832738"),
 | 
			
		||||
        Number::from("44274228917432520321923589422876796487670272189318"),
 | 
			
		||||
        Number::from("47451445736001306439091167216856844588711603153276"),
 | 
			
		||||
        Number::from("70386486105843025439939619828917593665686757934951"),
 | 
			
		||||
        Number::from("62176457141856560629502157223196586755079324193331"),
 | 
			
		||||
        Number::from("64906352462741904929101432445813822663347944758178"),
 | 
			
		||||
        Number::from("92575867718337217661963751590579239728245598838407"),
 | 
			
		||||
        Number::from("58203565325359399008402633568948830189458628227828"),
 | 
			
		||||
        Number::from("80181199384826282014278194139940567587151170094390"),
 | 
			
		||||
        Number::from("35398664372827112653829987240784473053190104293586"),
 | 
			
		||||
        Number::from("86515506006295864861532075273371959191420517255829"),
 | 
			
		||||
        Number::from("71693888707715466499115593487603532921714970056938"),
 | 
			
		||||
        Number::from("54370070576826684624621495650076471787294438377604"),
 | 
			
		||||
        Number::from("53282654108756828443191190634694037855217779295145"),
 | 
			
		||||
        Number::from("36123272525000296071075082563815656710885258350721"),
 | 
			
		||||
        Number::from("45876576172410976447339110607218265236877223636045"),
 | 
			
		||||
        Number::from("17423706905851860660448207621209813287860733969412"),
 | 
			
		||||
        Number::from("81142660418086830619328460811191061556940512689692"),
 | 
			
		||||
        Number::from("51934325451728388641918047049293215058642563049483"),
 | 
			
		||||
        Number::from("62467221648435076201727918039944693004732956340691"),
 | 
			
		||||
        Number::from("15732444386908125794514089057706229429197107928209"),
 | 
			
		||||
        Number::from("55037687525678773091862540744969844508330393682126"),
 | 
			
		||||
        Number::from("18336384825330154686196124348767681297534375946515"),
 | 
			
		||||
        Number::from("80386287592878490201521685554828717201219257766954"),
 | 
			
		||||
        Number::from("78182833757993103614740356856449095527097864797581"),
 | 
			
		||||
        Number::from("16726320100436897842553539920931837441497806860984"),
 | 
			
		||||
        Number::from("48403098129077791799088218795327364475675590848030"),
 | 
			
		||||
        Number::from("87086987551392711854517078544161852424320693150332"),
 | 
			
		||||
        Number::from("59959406895756536782107074926966537676326235447210"),
 | 
			
		||||
        Number::from("69793950679652694742597709739166693763042633987085"),
 | 
			
		||||
        Number::from("41052684708299085211399427365734116182760315001271"),
 | 
			
		||||
        Number::from("65378607361501080857009149939512557028198746004375"),
 | 
			
		||||
        Number::from("35829035317434717326932123578154982629742552737307"),
 | 
			
		||||
        Number::from("94953759765105305946966067683156574377167401875275"),
 | 
			
		||||
        Number::from("88902802571733229619176668713819931811048770190271"),
 | 
			
		||||
        Number::from("25267680276078003013678680992525463401061632866526"),
 | 
			
		||||
        Number::from("36270218540497705585629946580636237993140746255962"),
 | 
			
		||||
        Number::from("24074486908231174977792365466257246923322810917141"),
 | 
			
		||||
        Number::from("91430288197103288597806669760892938638285025333403"),
 | 
			
		||||
        Number::from("34413065578016127815921815005561868836468420090470"),
 | 
			
		||||
        Number::from("23053081172816430487623791969842487255036638784583"),
 | 
			
		||||
        Number::from("11487696932154902810424020138335124462181441773470"),
 | 
			
		||||
        Number::from("63783299490636259666498587618221225225512486764533"),
 | 
			
		||||
        Number::from("67720186971698544312419572409913959008952310058822"),
 | 
			
		||||
        Number::from("95548255300263520781532296796249481641953868218774"),
 | 
			
		||||
        Number::from("76085327132285723110424803456124867697064507995236"),
 | 
			
		||||
        Number::from("37774242535411291684276865538926205024910326572967"),
 | 
			
		||||
        Number::from("23701913275725675285653248258265463092207058596522"),
 | 
			
		||||
        Number::from("29798860272258331913126375147341994889534765745501"),
 | 
			
		||||
        Number::from("18495701454879288984856827726077713721403798879715"),
 | 
			
		||||
        Number::from("38298203783031473527721580348144513491373226651381"),
 | 
			
		||||
        Number::from("34829543829199918180278916522431027392251122869539"),
 | 
			
		||||
        Number::from("40957953066405232632538044100059654939159879593635"),
 | 
			
		||||
        Number::from("29746152185502371307642255121183693803580388584903"),
 | 
			
		||||
        Number::from("41698116222072977186158236678424689157993532961922"),
 | 
			
		||||
        Number::from("62467957194401269043877107275048102390895523597457"),
 | 
			
		||||
        Number::from("23189706772547915061505504953922979530901129967519"),
 | 
			
		||||
        Number::from("86188088225875314529584099251203829009407770775672"),
 | 
			
		||||
        Number::from("11306739708304724483816533873502340845647058077308"),
 | 
			
		||||
        Number::from("82959174767140363198008187129011875491310547126581"),
 | 
			
		||||
        Number::from("97623331044818386269515456334926366572897563400500"),
 | 
			
		||||
        Number::from("42846280183517070527831839425882145521227251250327"),
 | 
			
		||||
        Number::from("55121603546981200581762165212827652751691296897789"),
 | 
			
		||||
        Number::from("32238195734329339946437501907836945765883352399886"),
 | 
			
		||||
        Number::from("75506164965184775180738168837861091527357929701337"),
 | 
			
		||||
        Number::from("62177842752192623401942399639168044983993173312731"),
 | 
			
		||||
        Number::from("32924185707147349566916674687634660915035914677504"),
 | 
			
		||||
        Number::from("99518671430235219628894890102423325116913619626622"),
 | 
			
		||||
        Number::from("73267460800591547471830798392868535206946944540724"),
 | 
			
		||||
        Number::from("76841822524674417161514036427982273348055556214818"),
 | 
			
		||||
        Number::from("97142617910342598647204516893989422179826088076852"),
 | 
			
		||||
        Number::from("87783646182799346313767754307809363333018982642090"),
 | 
			
		||||
        Number::from("10848802521674670883215120185883543223812876952786"),
 | 
			
		||||
        Number::from("71329612474782464538636993009049310363619763878039"),
 | 
			
		||||
        Number::from("62184073572399794223406235393808339651327408011116"),
 | 
			
		||||
        Number::from("66627891981488087797941876876144230030984490851411"),
 | 
			
		||||
        Number::from("60661826293682836764744779239180335110989069790714"),
 | 
			
		||||
        Number::from("85786944089552990653640447425576083659976645795096"),
 | 
			
		||||
        Number::from("66024396409905389607120198219976047599490197230297"),
 | 
			
		||||
        Number::from("64913982680032973156037120041377903785566085089252"),
 | 
			
		||||
        Number::from("16730939319872750275468906903707539413042652315011"),
 | 
			
		||||
        Number::from("94809377245048795150954100921645863754710598436791"),
 | 
			
		||||
        Number::from("78639167021187492431995700641917969777599028300699"),
 | 
			
		||||
        Number::from("15368713711936614952811305876380278410754449733078"),
 | 
			
		||||
        Number::from("40789923115535562561142322423255033685442488917353"),
 | 
			
		||||
        Number::from("44889911501440648020369068063960672322193204149535"),
 | 
			
		||||
        Number::from("41503128880339536053299340368006977710650566631954"),
 | 
			
		||||
        Number::from("81234880673210146739058568557934581403627822703280"),
 | 
			
		||||
        Number::from("82616570773948327592232845941706525094512325230608"),
 | 
			
		||||
        Number::from("22918802058777319719839450180888072429661980811197"),
 | 
			
		||||
        Number::from("77158542502016545090413245809786882778948721859617"),
 | 
			
		||||
        Number::from("72107838435069186155435662884062257473692284509516"),
 | 
			
		||||
        Number::from("20849603980134001723930671666823555245252804609722"),
 | 
			
		||||
        Number::from("53503534226472524250874054075591789781264330331690"),
 | 
			
		||||
    ]
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										35
									
								
								src/bin/problem_14.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										35
									
								
								src/bin/problem_14.rs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,35 @@
 | 
			
		||||
fn main() {
 | 
			
		||||
    let longest = find_longest(1_000_000);
 | 
			
		||||
    println!("{longest}");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
fn collatz_seq(start: usize) -> Vec<usize> {
 | 
			
		||||
    let mut sequence = vec![start];
 | 
			
		||||
    let mut curr = start;
 | 
			
		||||
    loop {
 | 
			
		||||
        if curr == 1 {
 | 
			
		||||
            break;
 | 
			
		||||
        }
 | 
			
		||||
        if curr % 2 == 0{
 | 
			
		||||
            curr /= 2;
 | 
			
		||||
        } else {
 | 
			
		||||
            curr = 3 * curr + 1;
 | 
			
		||||
        }
 | 
			
		||||
        sequence.push(curr);
 | 
			
		||||
    }
 | 
			
		||||
    sequence
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
fn find_longest(max_start: usize) -> usize {
 | 
			
		||||
    let mut biggest = (0, 0);
 | 
			
		||||
 | 
			
		||||
    for i in 1..max_start {
 | 
			
		||||
        let seq = collatz_seq(i);
 | 
			
		||||
        if seq.len() > biggest.1 {
 | 
			
		||||
            biggest = (i, seq.len());
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    biggest.0
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										10
									
								
								src/bin/problem_15.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								src/bin/problem_15.rs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,10 @@
 | 
			
		||||
use project_euler::number::Number;
 | 
			
		||||
 | 
			
		||||
fn main() {
 | 
			
		||||
    let width = Number::from(20);
 | 
			
		||||
    let height = Number::from(20);
 | 
			
		||||
    let a = (width.clone()+height.clone()).fact();
 | 
			
		||||
    let b = width.clone().fact()*height.clone().fact();
 | 
			
		||||
    let euler_15 = a/b;
 | 
			
		||||
    println!("({width}+{height})!/{width}!*{height}!={euler_15}");
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										18
									
								
								src/bin/problem_16.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								src/bin/problem_16.rs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,18 @@
 | 
			
		||||
use project_euler::number::Number;
 | 
			
		||||
 | 
			
		||||
fn main() {
 | 
			
		||||
    let power = get_power(1000);
 | 
			
		||||
    println!("{}", power.digits.iter().sum::<isize>())
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
fn get_power(exp: usize) -> Number {
 | 
			
		||||
    let mut number = Number::from(1);
 | 
			
		||||
    if exp == 0 {
 | 
			
		||||
        return number;
 | 
			
		||||
    }
 | 
			
		||||
    for _n in 1..=exp {
 | 
			
		||||
        number = number * 2;
 | 
			
		||||
    }
 | 
			
		||||
    number
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										114
									
								
								src/bin/problem_17.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										114
									
								
								src/bin/problem_17.rs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,114 @@
 | 
			
		||||
use project_euler::number::Number;
 | 
			
		||||
 | 
			
		||||
fn main() {
 | 
			
		||||
    let mut num_letters = 0;
 | 
			
		||||
    for n in 1..=1000 {
 | 
			
		||||
        num_letters += number_to_words(Number::from(n)).len();
 | 
			
		||||
    }
 | 
			
		||||
    println!("{num_letters}");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
fn number_to_words(n: Number) -> String {
 | 
			
		||||
    let mut number_string = String::new();
 | 
			
		||||
    let digits = n.clone().digits;
 | 
			
		||||
    for (pos, &digit) in digits.iter().enumerate() {
 | 
			
		||||
        if digits.len() > 1 && digits.len() - 2 == pos {
 | 
			
		||||
            if digit == 1 {
 | 
			
		||||
                if digits[digits.len()-1] == 0 {
 | 
			
		||||
                    number_string.push_str("ten");
 | 
			
		||||
                }
 | 
			
		||||
                if digits[digits.len()-1] == 1 {
 | 
			
		||||
                    number_string.push_str("eleven");
 | 
			
		||||
                }
 | 
			
		||||
                if digits[digits.len()-1] == 2 {
 | 
			
		||||
                    number_string.push_str("twelve");
 | 
			
		||||
                }
 | 
			
		||||
                if digits[digits.len()-1] == 3 {
 | 
			
		||||
                    number_string.push_str("thirteen");
 | 
			
		||||
                }
 | 
			
		||||
                if digits[digits.len()-1] == 4 {
 | 
			
		||||
                    number_string.push_str("fourteen");
 | 
			
		||||
                }
 | 
			
		||||
                if digits[digits.len()-1] == 5 {
 | 
			
		||||
                    number_string.push_str("fifteen");
 | 
			
		||||
                }
 | 
			
		||||
                if digits[digits.len()-1] == 6 {
 | 
			
		||||
                    number_string.push_str("sixteen");
 | 
			
		||||
                }
 | 
			
		||||
                if digits[digits.len()-1] == 7 {
 | 
			
		||||
                    number_string.push_str("seventeen");
 | 
			
		||||
                }
 | 
			
		||||
                if digits[digits.len()-1] == 8 {
 | 
			
		||||
                    number_string.push_str("eighteen");
 | 
			
		||||
                }
 | 
			
		||||
                if digits[digits.len()-1] == 9 {
 | 
			
		||||
                    number_string.push_str("nineteen");
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            if digit == 2 {
 | 
			
		||||
                number_string.push_str("twenty");
 | 
			
		||||
            }
 | 
			
		||||
            if digit == 3 {
 | 
			
		||||
                number_string.push_str("thirty");
 | 
			
		||||
            }
 | 
			
		||||
            if digit == 4 {
 | 
			
		||||
                number_string.push_str("forty");
 | 
			
		||||
            }
 | 
			
		||||
            if digit == 5 {
 | 
			
		||||
                number_string.push_str("fifty");
 | 
			
		||||
            }
 | 
			
		||||
            if digit == 6 {
 | 
			
		||||
                number_string.push_str("sixty");
 | 
			
		||||
            }
 | 
			
		||||
            if digit == 7 {
 | 
			
		||||
                number_string.push_str("seventy");
 | 
			
		||||
            }
 | 
			
		||||
            if digit == 8 {
 | 
			
		||||
                number_string.push_str("eighty");
 | 
			
		||||
            }
 | 
			
		||||
            if digit == 9 {
 | 
			
		||||
                number_string.push_str("ninety");
 | 
			
		||||
            }
 | 
			
		||||
        } else if digits.len() == 1 || (digits.len() - 2 != pos && !(digits.len() - 1 == pos && digits[digits.len() - 2] == 1)) {
 | 
			
		||||
            if digit == 1 {
 | 
			
		||||
                number_string.push_str("one");
 | 
			
		||||
            }
 | 
			
		||||
            if digit == 2 {
 | 
			
		||||
                number_string.push_str("two");
 | 
			
		||||
            }
 | 
			
		||||
            if digit == 3 {
 | 
			
		||||
                number_string.push_str("three");
 | 
			
		||||
            }
 | 
			
		||||
            if digit == 4 {
 | 
			
		||||
                number_string.push_str("four");
 | 
			
		||||
            }
 | 
			
		||||
            if digit == 5 {
 | 
			
		||||
                number_string.push_str("five");
 | 
			
		||||
            }
 | 
			
		||||
            if digit == 6 {
 | 
			
		||||
                number_string.push_str("six");
 | 
			
		||||
            }
 | 
			
		||||
            if digit == 7 {
 | 
			
		||||
                number_string.push_str("seven");
 | 
			
		||||
            }
 | 
			
		||||
            if digit == 8 {
 | 
			
		||||
                number_string.push_str("eight");
 | 
			
		||||
            }
 | 
			
		||||
            if digit == 9 {
 | 
			
		||||
                number_string.push_str("nine");
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        if digits.len() > 2 && pos == digits.len() - 3 && digit != 0 {
 | 
			
		||||
            number_string.push_str("hundred");
 | 
			
		||||
            if !(digits[pos + 1] == 0 && digits[pos + 2] == 0) {
 | 
			
		||||
                number_string.push_str("and");
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        if digits.len() > 3 && pos == digits.len() - 4 && digit != 0 {
 | 
			
		||||
            number_string.push_str("thousand");
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    println!("{n}: {number_string}");
 | 
			
		||||
    number_string
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										17
									
								
								src/bin/problem_20.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								src/bin/problem_20.rs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,17 @@
 | 
			
		||||
use project_euler::number::Number;
 | 
			
		||||
 | 
			
		||||
fn main() {
 | 
			
		||||
    let factorial = get_factorial(100);
 | 
			
		||||
     dbg!(factorial.digits.iter().sum::<isize>());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
fn get_factorial(factorial: isize) -> Number {
 | 
			
		||||
    let mut number = Number::from(1);
 | 
			
		||||
    if factorial == 0 {
 | 
			
		||||
        return number;
 | 
			
		||||
    }
 | 
			
		||||
    for n in 1..=factorial {
 | 
			
		||||
        number = number * n;
 | 
			
		||||
    }
 | 
			
		||||
    number
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										45
									
								
								src/bin/problem_21.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										45
									
								
								src/bin/problem_21.rs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,45 @@
 | 
			
		||||
use std::collections::HashMap;
 | 
			
		||||
use std::time::Instant;
 | 
			
		||||
 | 
			
		||||
fn main() {
 | 
			
		||||
    let now = Instant::now();
 | 
			
		||||
    let mut amicable_cache: HashMap<isize, isize> = HashMap::new();
 | 
			
		||||
    let mut despicable_cache: HashMap<isize, isize> = HashMap::new();
 | 
			
		||||
    let mut sum_amicable = 0;
 | 
			
		||||
    for i in 2..=10 {
 | 
			
		||||
        if amicable_cache.get(&i).is_some() {
 | 
			
		||||
            continue;
 | 
			
		||||
        }
 | 
			
		||||
        if despicable_cache.get(&i).is_some() {
 | 
			
		||||
            continue;
 | 
			
		||||
        }
 | 
			
		||||
        let divisors = get_divisors(i);
 | 
			
		||||
        let sum_divisors = divisors.iter().sum();
 | 
			
		||||
        let other_divisors = get_divisors(sum_divisors);
 | 
			
		||||
        let other_sum_divisors = other_divisors.iter().sum();
 | 
			
		||||
        if sum_divisors == other_sum_divisors {
 | 
			
		||||
            println!("{:?}", divisors);
 | 
			
		||||
            amicable_cache.insert(other_sum_divisors, sum_divisors);
 | 
			
		||||
            sum_amicable += sum_divisors + other_sum_divisors;
 | 
			
		||||
        } else {
 | 
			
		||||
            println!("{:?}", divisors);
 | 
			
		||||
            despicable_cache.insert(other_sum_divisors, sum_divisors);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    println!("{:?}", amicable_cache);
 | 
			
		||||
    println!("{sum_amicable}");
 | 
			
		||||
    println!("Time={} µs", now.elapsed().as_micros());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
fn get_divisors(n: isize) -> Vec<isize> {
 | 
			
		||||
    let mut divisors = vec![1];
 | 
			
		||||
    let mut potential_divisor = 2;
 | 
			
		||||
    while (potential_divisor * potential_divisor) < n {
 | 
			
		||||
        if n % potential_divisor == 0 {
 | 
			
		||||
            divisors.push(potential_divisor);
 | 
			
		||||
            divisors.push(n / potential_divisor);
 | 
			
		||||
        }
 | 
			
		||||
        potential_divisor = potential_divisor + 1;
 | 
			
		||||
    }
 | 
			
		||||
    divisors
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										68
									
								
								src/bin/problem_25.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										68
									
								
								src/bin/problem_25.rs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,68 @@
 | 
			
		||||
use project_euler::number::Number;
 | 
			
		||||
 | 
			
		||||
fn main() {
 | 
			
		||||
    let fib_idx = find_fib(1000);
 | 
			
		||||
    println!("{fib_idx}");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Way too slow, from 20 onward we go from µs to ms and from 32 we measure in seconds
 | 
			
		||||
//fn fib_recursion(n: Number) -> usize {
 | 
			
		||||
//    let one = Number::from(1);
 | 
			
		||||
//    if n == one {
 | 
			
		||||
//        return 1;
 | 
			
		||||
//    }
 | 
			
		||||
//    let two = Number::from(2);
 | 
			
		||||
//    if n == two {
 | 
			
		||||
//        return 1;
 | 
			
		||||
//    }
 | 
			
		||||
//    fib_recursion(n.clone() - two) + fib_recursion(n - one)
 | 
			
		||||
//}
 | 
			
		||||
 | 
			
		||||
// almost as fast as the no recursion solution but more complicated and more memory intensiv
 | 
			
		||||
// creating an inner function to not have to pass in the hashmap from outside makes it slightly slower
 | 
			
		||||
//fn fib_recursion_cached(n: Number) -> Number {
 | 
			
		||||
//    let mut cache: HashMap<Number, Number> = HashMap::new();
 | 
			
		||||
//    fn inner_fib_recursion_cached(n: Number, cache: &mut HashMap<Number, Number>) -> Number {
 | 
			
		||||
//        let one = Number::from(1);
 | 
			
		||||
//        if n == one {
 | 
			
		||||
//            return one;
 | 
			
		||||
//        }
 | 
			
		||||
//        let two = Number::from(2);
 | 
			
		||||
//        if n == two {
 | 
			
		||||
//            return one;
 | 
			
		||||
//        }
 | 
			
		||||
//        match cache.get(&n) {
 | 
			
		||||
//            Some(res) => return res.clone(),
 | 
			
		||||
//            None => {
 | 
			
		||||
//                let res = inner_fib_recursion_cached(n.clone() - two, cache) + inner_fib_recursion_cached(n.clone() - one, cache);
 | 
			
		||||
//                cache.insert(n.clone(), res.clone());
 | 
			
		||||
//                return res;
 | 
			
		||||
//            },
 | 
			
		||||
//        }
 | 
			
		||||
//    }
 | 
			
		||||
//    inner_fib_recursion_cached(n, &mut cache)
 | 
			
		||||
//}
 | 
			
		||||
 | 
			
		||||
// faster than recursion
 | 
			
		||||
fn fib(n: usize) -> Number {
 | 
			
		||||
    let mut last_two = (Number::from(1), Number::from(1));
 | 
			
		||||
    let mut iteration = 1;
 | 
			
		||||
    while iteration < n {
 | 
			
		||||
        last_two = (last_two.1.clone(), last_two.0 + last_two.1);
 | 
			
		||||
        iteration += 1;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    last_two.0
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
fn find_fib(num_digits: usize) -> usize {
 | 
			
		||||
    let mut n = 1;
 | 
			
		||||
    loop {
 | 
			
		||||
        let fib = fib(n);
 | 
			
		||||
        let fib_len = fib.digits.len();
 | 
			
		||||
        if fib_len == num_digits {
 | 
			
		||||
            return n;
 | 
			
		||||
        }
 | 
			
		||||
        n += 1;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										14
									
								
								src/bin/problem_29.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								src/bin/problem_29.rs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,14 @@
 | 
			
		||||
use std::collections::HashSet;
 | 
			
		||||
use project_euler::number::Number;
 | 
			
		||||
 | 
			
		||||
fn main() {
 | 
			
		||||
    let mut terms: HashSet<Number> = HashSet::new();
 | 
			
		||||
    let max = 100;
 | 
			
		||||
    for a in 2..=max {
 | 
			
		||||
        for b in 2..=max {
 | 
			
		||||
            let a_num = Number::from(a);
 | 
			
		||||
            terms.insert(a_num.pow(b as u32));
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    println!("{}", terms.len());
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										28
									
								
								src/bin/problem_30.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										28
									
								
								src/bin/problem_30.rs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,28 @@
 | 
			
		||||
use project_euler::number::Number;
 | 
			
		||||
 | 
			
		||||
fn main() {
 | 
			
		||||
    println!("{}", nth_powers(5))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
fn nth_powers(nth: u32) -> isize {
 | 
			
		||||
    let mut powers = vec![];
 | 
			
		||||
    let mut max = 9isize.pow(nth);
 | 
			
		||||
    let mut idx = 1;
 | 
			
		||||
    loop {
 | 
			
		||||
        let attempt = max * idx;
 | 
			
		||||
        if Number::from(attempt).digits.len() < idx as usize {
 | 
			
		||||
            max = (idx - 1) * max;
 | 
			
		||||
            break;
 | 
			
		||||
        }
 | 
			
		||||
        idx += 1;
 | 
			
		||||
    }
 | 
			
		||||
    for n in 2..=max {
 | 
			
		||||
        let num = Number::from(n);
 | 
			
		||||
        let digits = num.digits;
 | 
			
		||||
        let sum = digits.iter().map(|&x| x.pow(nth)).sum();
 | 
			
		||||
        if n == sum {
 | 
			
		||||
            powers.push(n);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    powers.iter().sum()
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										35
									
								
								src/bin/problem_34.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										35
									
								
								src/bin/problem_34.rs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,35 @@
 | 
			
		||||
use project_euler::number::Number;
 | 
			
		||||
 | 
			
		||||
fn main() {
 | 
			
		||||
    let factorials_sum = digit_factorials();
 | 
			
		||||
    println!("{factorials_sum}");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
fn factorial(num: isize) -> isize {
 | 
			
		||||
    let mut fact = 1;
 | 
			
		||||
    for n in 1..=num {
 | 
			
		||||
        fact = fact * n;
 | 
			
		||||
    }
 | 
			
		||||
    fact
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
fn digit_factorials() -> isize {
 | 
			
		||||
    let mut factorials = vec![];
 | 
			
		||||
    let mut max = factorial(9);
 | 
			
		||||
    let mut idx = 1;
 | 
			
		||||
    loop {
 | 
			
		||||
        let attempt = max * idx;
 | 
			
		||||
        if Number::from(attempt).digits.len() < idx as usize {
 | 
			
		||||
            max = (idx - 1) * max;
 | 
			
		||||
            break;
 | 
			
		||||
        }
 | 
			
		||||
        idx += 1;
 | 
			
		||||
    }
 | 
			
		||||
    for n in 3..=max {
 | 
			
		||||
        let digits_fact_sum = Number::from(n).digits.iter().map(|&digit| factorial(digit)).sum();
 | 
			
		||||
        if n == digits_fact_sum {
 | 
			
		||||
            factorials.push(n);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    factorials.iter().sum()
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										13
									
								
								src/bin/problem_48.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								src/bin/problem_48.rs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,13 @@
 | 
			
		||||
use project_euler::number::Number;
 | 
			
		||||
 | 
			
		||||
fn main() {
 | 
			
		||||
    println!("{}", power_series(1000));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
fn power_series(length: usize) -> Number {
 | 
			
		||||
    let mut number = Number::from(0);
 | 
			
		||||
    for i in 1..=length {
 | 
			
		||||
        number = number + Number::from(i as isize).pow(i as u32);
 | 
			
		||||
    }
 | 
			
		||||
    number
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										16
									
								
								src/bin/problem_9.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								src/bin/problem_9.rs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,16 @@
 | 
			
		||||
fn main() {
 | 
			
		||||
    for a in 0..=1000 {
 | 
			
		||||
        for b in a..=(1000 - a) {
 | 
			
		||||
            let c = 1000 - (a + b);
 | 
			
		||||
            if b == c { continue; }
 | 
			
		||||
            if is_triplet(a, b, c) {
 | 
			
		||||
                println!("a + b + c = {a} + {b} + {c} = {}", a + b + c);
 | 
			
		||||
                println!("abc = {}", a * b * c);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
fn is_triplet(a: usize, b: usize, c: usize) -> bool {
 | 
			
		||||
    return a * a + b * b == c * c
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										392
									
								
								src/lib.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										392
									
								
								src/lib.rs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,392 @@
 | 
			
		||||
pub mod number {
 | 
			
		||||
    use std::cmp::{min, Ordering};
 | 
			
		||||
    use std::fmt::{Display, Formatter};
 | 
			
		||||
    use std::iter::zip;
 | 
			
		||||
    use std::ops::{Add, Mul, Div, Sub, Rem};
 | 
			
		||||
 | 
			
		||||
    #[derive(Clone, Debug, Eq, PartialEq, Hash)]
 | 
			
		||||
    pub enum Sign {
 | 
			
		||||
        Positif,
 | 
			
		||||
        Negatif,
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    #[derive(Clone, Debug, Eq, PartialEq, Hash)]
 | 
			
		||||
    pub struct Number {
 | 
			
		||||
        pub digits: Vec<isize>,
 | 
			
		||||
        pub sign: Sign,
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    impl Number {
 | 
			
		||||
        pub fn get_digit(n: isize, pos: usize) -> isize {
 | 
			
		||||
            let modulo = 10isize.pow(pos as u32 + 1);
 | 
			
		||||
            let divisor = modulo / 10;
 | 
			
		||||
            (n % modulo) / divisor
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        pub const fn byte_to_digit(b: u8) -> isize {
 | 
			
		||||
            // wrapping_sub('0' as u32) same as - 48 but less magical
 | 
			
		||||
            (b as isize).wrapping_sub('0' as isize)
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        pub fn handle_overflows(&mut self) {
 | 
			
		||||
            let new_digits = &mut self.digits;
 | 
			
		||||
            let digits_len = new_digits.len();
 | 
			
		||||
            let mut digits_idx = digits_len - 1;
 | 
			
		||||
            loop {
 | 
			
		||||
                let digit_or_num = new_digits[digits_idx];
 | 
			
		||||
                let digit_len = if digit_or_num != 0 { (digit_or_num.abs() as f64 + 1.0).log10().ceil() as usize } else { 1 };
 | 
			
		||||
                for i in 0..digit_len {
 | 
			
		||||
                    let new_digit = Self::get_digit(digit_or_num, i);
 | 
			
		||||
                    let (digit_idx, is_overflow) = digits_idx.overflowing_sub(i);
 | 
			
		||||
                    if is_overflow {
 | 
			
		||||
                        new_digits.insert(0, new_digit);
 | 
			
		||||
                        digits_idx += 1;
 | 
			
		||||
                    } else {
 | 
			
		||||
                        let digit = new_digits.get_mut(digit_idx).unwrap();
 | 
			
		||||
                        if i == 0 {
 | 
			
		||||
                            *digit = new_digit;
 | 
			
		||||
                        } else {
 | 
			
		||||
                            *digit += new_digit;
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
                if digits_idx == 0 {
 | 
			
		||||
                    break;
 | 
			
		||||
                }
 | 
			
		||||
                digits_idx -= 1;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        pub fn handle_underflows(&mut self) {
 | 
			
		||||
            let new_digits = &mut self.digits;
 | 
			
		||||
            let mut digits_len = new_digits.len();
 | 
			
		||||
            for digit in new_digits.clone() {
 | 
			
		||||
                match digit.cmp(&0) {
 | 
			
		||||
                    Ordering::Equal => {
 | 
			
		||||
                        if digits_len == 1 {
 | 
			
		||||
                            return;
 | 
			
		||||
                        }
 | 
			
		||||
                        digits_len -= 1;
 | 
			
		||||
                        new_digits.remove(0);
 | 
			
		||||
                    },
 | 
			
		||||
                    Ordering::Less => {
 | 
			
		||||
                        self.sign = Sign::Negatif;
 | 
			
		||||
                        break;
 | 
			
		||||
                    },
 | 
			
		||||
                    _ => break
 | 
			
		||||
                };
 | 
			
		||||
            }
 | 
			
		||||
            let mut digits_idx = digits_len - 1;
 | 
			
		||||
            loop {
 | 
			
		||||
                let digit = new_digits[digits_idx];
 | 
			
		||||
                if self.sign == Sign::Positif && digit < 0 && digits_idx > 0 {
 | 
			
		||||
                    let mut_digit = new_digits.get_mut(digits_idx).unwrap();
 | 
			
		||||
                    *mut_digit = 10 - digit.abs();
 | 
			
		||||
                    let mut_digit = new_digits.get_mut(digits_idx-1).unwrap();
 | 
			
		||||
                    *mut_digit -= 1;
 | 
			
		||||
                } else {
 | 
			
		||||
                    let mut_digit = new_digits.get_mut(digits_idx).unwrap();
 | 
			
		||||
                    *mut_digit = digit.abs();
 | 
			
		||||
                }
 | 
			
		||||
                if digits_idx == 0 {
 | 
			
		||||
                    break;
 | 
			
		||||
                }
 | 
			
		||||
                digits_idx -= 1;
 | 
			
		||||
            }
 | 
			
		||||
            for digit in new_digits.clone() {
 | 
			
		||||
                match digit.cmp(&0) {
 | 
			
		||||
                    Ordering::Equal => {new_digits.remove(0);},
 | 
			
		||||
                    _ => break
 | 
			
		||||
                };
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        pub fn pow(self, n: u32) -> Self {
 | 
			
		||||
            let mut result = self.clone();
 | 
			
		||||
            if ((self.digits.len() * 8) as u32) < isize::BITS {
 | 
			
		||||
                let number = isize::from(self);
 | 
			
		||||
                for _i in 1..n {
 | 
			
		||||
                    result = result * number;
 | 
			
		||||
                }
 | 
			
		||||
                result
 | 
			
		||||
            } else {
 | 
			
		||||
                let number = self.clone();
 | 
			
		||||
                for _i in 1..n {
 | 
			
		||||
                    result = result * number.clone();
 | 
			
		||||
                }
 | 
			
		||||
                result
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        pub fn fact(self) -> Self {
 | 
			
		||||
            let mut fact = Number::from(1);
 | 
			
		||||
            if ((self.digits.len() * 8) as u32) < isize::BITS {
 | 
			
		||||
                let max = isize::from(self);
 | 
			
		||||
                for n in 1..=max {
 | 
			
		||||
                    fact = fact * n;
 | 
			
		||||
                }
 | 
			
		||||
                fact
 | 
			
		||||
            } else {
 | 
			
		||||
                panic!("starting number too big")
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        fn div_with_rem(n1: Number, n2: Number) -> (Number, Number) {
 | 
			
		||||
            let n1_len = n1.digits.len();
 | 
			
		||||
            let n2_len = n2.digits.len();
 | 
			
		||||
            if n2_len > n1_len {
 | 
			
		||||
                return (Number::from(0), n2);
 | 
			
		||||
            }
 | 
			
		||||
            let dividend = n1.digits[..n2_len].to_vec();
 | 
			
		||||
            let mut quotient = vec![];
 | 
			
		||||
            let mut remainder = Number {
 | 
			
		||||
                digits: dividend.clone(),
 | 
			
		||||
                sign: Sign::Positif
 | 
			
		||||
            };
 | 
			
		||||
            let mut iteration = 1;
 | 
			
		||||
            loop {
 | 
			
		||||
                let mut factor = 0;
 | 
			
		||||
                loop {
 | 
			
		||||
                    let temp_remainder = remainder.clone() - n2.clone();
 | 
			
		||||
                    if temp_remainder.sign == Sign::Negatif {
 | 
			
		||||
                        quotient.push(factor);
 | 
			
		||||
                        break;
 | 
			
		||||
                    }
 | 
			
		||||
                    remainder = temp_remainder;
 | 
			
		||||
                    factor += 1;
 | 
			
		||||
                }
 | 
			
		||||
                if n1_len == n2_len + iteration - 1 {
 | 
			
		||||
                    break;
 | 
			
		||||
                }
 | 
			
		||||
                remainder.digits.push(n1.digits[n2_len+iteration-1]);
 | 
			
		||||
                iteration += 1;
 | 
			
		||||
            }
 | 
			
		||||
            let mut res = Number {
 | 
			
		||||
                digits: quotient,
 | 
			
		||||
                sign: Sign::Positif
 | 
			
		||||
            };
 | 
			
		||||
            res.handle_overflows();
 | 
			
		||||
            for digit in res.clone().digits {
 | 
			
		||||
                if digit != 0 {
 | 
			
		||||
                    break;
 | 
			
		||||
                }
 | 
			
		||||
                res.digits.remove(0);
 | 
			
		||||
            }
 | 
			
		||||
            for digit in remainder.clone().digits {
 | 
			
		||||
                if digit != 0 || remainder.digits.len() == 1 {
 | 
			
		||||
                    break;
 | 
			
		||||
                }
 | 
			
		||||
                remainder.digits.remove(0);
 | 
			
		||||
            }
 | 
			
		||||
            (res, remainder)
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    impl From<Number> for isize {
 | 
			
		||||
        fn from(value: Number) -> Self {
 | 
			
		||||
            let mut num = 0;
 | 
			
		||||
            for (pos, &digit) in value.digits.iter().rev().enumerate() {
 | 
			
		||||
                num += digit * 10isize.pow(pos as u32);
 | 
			
		||||
            }
 | 
			
		||||
            num
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    impl From<Number> for String {
 | 
			
		||||
        fn from(value: Number) -> Self {
 | 
			
		||||
            let string_vec: Vec<String> = value.digits.iter().map(|&digit| digit.to_string()).collect();
 | 
			
		||||
            string_vec.concat()
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    impl From<&str> for Number {
 | 
			
		||||
        fn from(value: &str) -> Self {
 | 
			
		||||
            let bytes = value.as_bytes();
 | 
			
		||||
            let (sign, idx_start) = match bytes[0] {
 | 
			
		||||
                b'-' => (Sign::Negatif, 1),
 | 
			
		||||
                _ => (Sign::Positif, 0),
 | 
			
		||||
            };
 | 
			
		||||
            let mut digits = vec![];
 | 
			
		||||
            for &byte in &bytes[idx_start..] {
 | 
			
		||||
                let digit = Self::byte_to_digit(byte);
 | 
			
		||||
                digits.push(digit);
 | 
			
		||||
            }
 | 
			
		||||
            Self {
 | 
			
		||||
                digits,
 | 
			
		||||
                sign
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    impl From<isize> for Number {
 | 
			
		||||
        fn from(value: isize) -> Self {
 | 
			
		||||
            let mut sign = Sign::Positif;
 | 
			
		||||
            if value < 0 {
 | 
			
		||||
                sign = Sign::Negatif;
 | 
			
		||||
            }
 | 
			
		||||
            let num_len = if value > 0 { (value as f64 + 1.0).log10().ceil() as usize } else { 1 };
 | 
			
		||||
            let mut digits = vec![];
 | 
			
		||||
            for digit_idx in 0..num_len {
 | 
			
		||||
                let digit = Self::get_digit(value, digit_idx);
 | 
			
		||||
                digits.push(digit);
 | 
			
		||||
            }
 | 
			
		||||
            let digits = digits.iter().rev().map(|&digit| digit).collect();
 | 
			
		||||
            Self {
 | 
			
		||||
                digits,
 | 
			
		||||
                sign
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    impl Display for Number {
 | 
			
		||||
        fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
 | 
			
		||||
            let number_string = self.digits.iter().map(|&digit| { digit.to_string() }).collect::<Vec<String>>().join("");
 | 
			
		||||
            match self.sign {
 | 
			
		||||
                Sign::Positif => write!(f, "{number_string}"),
 | 
			
		||||
                Sign::Negatif => write!(f, "-{number_string}"),
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    impl Add for Number {
 | 
			
		||||
        type Output = Self;
 | 
			
		||||
 | 
			
		||||
        fn add(self, rhs: Self) -> Self::Output {
 | 
			
		||||
            let self_len = self.digits.len();
 | 
			
		||||
            let rhs_len = rhs.digits.len();
 | 
			
		||||
            let mut self_digits = self.digits.clone();
 | 
			
		||||
            let mut rhs_digits = rhs.digits.clone();
 | 
			
		||||
            if self_len != rhs_len {
 | 
			
		||||
                let difference = (self_len).abs_diff(rhs_len);
 | 
			
		||||
                let pad = vec![0isize; difference];
 | 
			
		||||
                if min(self_len, rhs_len) == self_len {
 | 
			
		||||
                    self_digits = [pad, self.digits].concat();
 | 
			
		||||
                } else {
 | 
			
		||||
                    rhs_digits = [pad, rhs.digits].concat();
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            let zipped = zip(self_digits.iter(), rhs_digits.iter());
 | 
			
		||||
            let added = zipped.map(|(self_digit, rhs_digit)| { self_digit + rhs_digit }).collect();
 | 
			
		||||
            let mut overflown_number = Self {
 | 
			
		||||
                digits: added,
 | 
			
		||||
                sign: Sign::Positif
 | 
			
		||||
            };
 | 
			
		||||
            overflown_number.handle_overflows();
 | 
			
		||||
            overflown_number
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    impl Sub for Number {
 | 
			
		||||
        type Output = Self;
 | 
			
		||||
 | 
			
		||||
        fn sub(self, rhs: Self) -> Self::Output {
 | 
			
		||||
            let self_len = self.digits.len();
 | 
			
		||||
            let rhs_len = rhs.digits.len();
 | 
			
		||||
            let mut self_digits = self.digits.clone();
 | 
			
		||||
            let mut rhs_digits = rhs.digits.clone();
 | 
			
		||||
            if self_len != rhs_len {
 | 
			
		||||
                let difference = (self_len).abs_diff(rhs_len);
 | 
			
		||||
                let pad = vec![0isize; difference];
 | 
			
		||||
                if min(self_len, rhs_len) == self_len {
 | 
			
		||||
                    self_digits = [pad, self.digits].concat();
 | 
			
		||||
                } else {
 | 
			
		||||
                    rhs_digits = [pad, rhs.digits].concat();
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            let zipped = zip(self_digits.iter(), rhs_digits.iter());
 | 
			
		||||
            let added = zipped.map(|(self_digit, rhs_digit)| { self_digit - rhs_digit }).collect();
 | 
			
		||||
            let mut underflown_number = Self {
 | 
			
		||||
                digits: added,
 | 
			
		||||
                sign: Sign::Positif
 | 
			
		||||
            };
 | 
			
		||||
            underflown_number.handle_underflows();
 | 
			
		||||
            underflown_number
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    impl Mul for Number {
 | 
			
		||||
        type Output = Self;
 | 
			
		||||
 | 
			
		||||
        fn mul(self, rhs: Self) -> Self::Output {
 | 
			
		||||
            let multiplied = self.digits.iter().rev().enumerate().map(|(pos, &digit)| {
 | 
			
		||||
                let mut mult = digit * rhs.clone();
 | 
			
		||||
                mult.digits = [mult.digits, vec![0; pos]].concat();
 | 
			
		||||
                mult
 | 
			
		||||
            });
 | 
			
		||||
            let mut overflown_number = multiplied.reduce(|acc, num| acc + num).unwrap();
 | 
			
		||||
            overflown_number.handle_overflows();
 | 
			
		||||
            overflown_number
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    impl Mul<Number> for isize {
 | 
			
		||||
        type Output = Number;
 | 
			
		||||
 | 
			
		||||
        fn mul(self, rhs: Number) -> Self::Output {
 | 
			
		||||
            let multiplied = rhs.digits.iter().map(|digit| { digit * self }).collect();
 | 
			
		||||
            let mut overflown_number = Number {
 | 
			
		||||
                digits: multiplied,
 | 
			
		||||
                sign: Sign::Positif
 | 
			
		||||
            };
 | 
			
		||||
            overflown_number.handle_overflows();
 | 
			
		||||
            overflown_number
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    impl Mul<isize> for Number {
 | 
			
		||||
        type Output = Self;
 | 
			
		||||
 | 
			
		||||
        fn mul(self, rhs: isize) -> Self::Output {
 | 
			
		||||
            let multiplied = self.digits.iter().map(|digit| { digit * rhs }).collect();
 | 
			
		||||
            let mut overflown_number = Self {
 | 
			
		||||
                digits: multiplied,
 | 
			
		||||
                sign: Sign::Positif
 | 
			
		||||
            };
 | 
			
		||||
            overflown_number.handle_overflows();
 | 
			
		||||
            overflown_number
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    impl Div for Number {
 | 
			
		||||
        type Output = Self;
 | 
			
		||||
 | 
			
		||||
        fn div(self, rhs: Self) -> Self::Output {
 | 
			
		||||
            Self::div_with_rem(self, rhs).0
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    impl Rem for Number {
 | 
			
		||||
        type Output = Self;
 | 
			
		||||
 | 
			
		||||
        fn rem(self, rhs: Self) -> Self::Output {
 | 
			
		||||
            Self::div_with_rem(self, rhs).1
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    #[cfg(test)]
 | 
			
		||||
    mod number_tests {
 | 
			
		||||
        use crate::number::{Number, Sign};
 | 
			
		||||
 | 
			
		||||
        #[test]
 | 
			
		||||
        fn test_from_isize() {
 | 
			
		||||
            let number = Number::from(-1234);
 | 
			
		||||
            assert_eq!(number, Number { digits: vec![1234], sign: Sign::Negatif });
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        #[test]
 | 
			
		||||
        fn test_get_digit() {
 | 
			
		||||
            let num = 12345;
 | 
			
		||||
            let digit_1 = Number::get_digit(num, 0);
 | 
			
		||||
            let digit_2 = Number::get_digit(num, 1);
 | 
			
		||||
            let digit_3 = Number::get_digit(num, 2);
 | 
			
		||||
            let digit_4 = Number::get_digit(num, 3);
 | 
			
		||||
            let digit_5 = Number::get_digit(num, 4);
 | 
			
		||||
            assert_eq!(digit_1, 5);
 | 
			
		||||
            assert_eq!(digit_2, 4);
 | 
			
		||||
            assert_eq!(digit_3, 3);
 | 
			
		||||
            assert_eq!(digit_4, 2);
 | 
			
		||||
            assert_eq!(digit_5, 1);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
		Reference in New Issue
	
	Block a user