solved 24
This commit is contained in:
		
							
								
								
									
										57
									
								
								src/bin/problem_24.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										57
									
								
								src/bin/problem_24.rs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,57 @@
 | 
			
		||||
use std::error::Error;
 | 
			
		||||
 | 
			
		||||
fn main() {
 | 
			
		||||
    let n = 1_000_000;
 | 
			
		||||
    let digits = vec![1, 0, 2, 3, 4, 5, 6, 7, 8, 9];
 | 
			
		||||
    let perm = permutation(digits, n).expect("Should return ok").iter().map(|&digit| digit.to_string()).collect::<Vec<String>>().join("");
 | 
			
		||||
    println!("{perm}");
 | 
			
		||||
    let digits = vec!["0", "1", "2", "3", "4", "5", "6", "7", "8", "9"];
 | 
			
		||||
    //for n in 1..=factorial(digits.len()) {
 | 
			
		||||
        let perm = permutation(digits.clone(), n).expect("Should return ok").join("");
 | 
			
		||||
        println!("{perm}");
 | 
			
		||||
    //}
 | 
			
		||||
    let digits = vec!["a", "b", "c", "d", "e", "f", "g", "h", "i", "j"];
 | 
			
		||||
    let perm = permutation(digits.clone(), n).expect("Should return ok").join("");
 | 
			
		||||
    println!("{perm}");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// Explanation
 | 
			
		||||
///
 | 
			
		||||
/// there are 10! possible permutations
 | 
			
		||||
/// for each first number there are 9!, for each first 2 numbers 8!, etc.
 | 
			
		||||
/// we check how many times we have 9! permutations before we're over 1_000_000
 | 
			
		||||
/// aka. 1000000 / 9!
 | 
			
		||||
/// we take the remainder and check how many times we have 8! before we?re over it
 | 
			
		||||
/// (1000000 % 9!) 8!
 | 
			
		||||
/// etc.
 | 
			
		||||
/// every iteration we remove the digit by the idx from the original permutation
 | 
			
		||||
/// we only check for 999999 permutations because we already have the first one
 | 
			
		||||
///
 | 
			
		||||
fn permutation<T: Copy + Ord>(mut digits: Vec<T>, nth: usize) -> Result<Vec<T>, Box<dyn Error>> {
 | 
			
		||||
    digits.sort();
 | 
			
		||||
    if nth == 1 {
 | 
			
		||||
        return Ok(digits);
 | 
			
		||||
    }
 | 
			
		||||
    if nth > factorial(digits.len()) || nth == 0 {
 | 
			
		||||
        return Err(Box::from("Out of bounds"));
 | 
			
		||||
    }
 | 
			
		||||
    let mut perm = Vec::new();
 | 
			
		||||
    let num_unique_digits = digits.len();
 | 
			
		||||
    let mut remainder = nth - 1;
 | 
			
		||||
    for idx in 1..=digits.len() {
 | 
			
		||||
        let permutations = remainder / factorial(num_unique_digits-idx);
 | 
			
		||||
        remainder = remainder % factorial(num_unique_digits-idx);
 | 
			
		||||
        perm.push(digits[permutations]);
 | 
			
		||||
        digits.remove(permutations);
 | 
			
		||||
    }
 | 
			
		||||
    Ok(perm)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// number of permutations is n! where n is the number of digits
 | 
			
		||||
fn factorial(num: usize) -> usize {
 | 
			
		||||
    let mut fact = 1;
 | 
			
		||||
    for n in 1..=num {
 | 
			
		||||
        fact = fact * n;
 | 
			
		||||
    }
 | 
			
		||||
    fact
 | 
			
		||||
}
 | 
			
		||||
		Reference in New Issue
	
	Block a user