diff --git a/src/euler31/src/main.rs b/src/euler31/src/main.rs index 8dd9fa4..61cf129 100644 --- a/src/euler31/src/main.rs +++ b/src/euler31/src/main.rs @@ -1,114 +1,13 @@ -#![allow(dead_code)] -use std::{cmp::Reverse, collections::HashSet}; - -const VALUE: u8 = 200; - -type Values = Vec; +const COIN_SIZES: [usize; 8] = [1, 2, 5, 10, 20, 50, 100, 200]; +const TARGET: usize = 200; fn main() { - let x = vec![VALUE]; - let mut cases = HashSet::new(); - cases.insert(x.clone()); - solve(x, &mut cases, -1); - let mut cases_ordered: Vec<_> = cases.iter().collect(); - cases_ordered.sort_unstable_by_key(|v| v.len()); - for case in cases_ordered { - println!("{}", case.show()); - } - println!("{}", cases.len()); -} - -fn solve(x: Values, cases: &mut HashSet, max_depth: isize) { - // println!("solving {}", x.show()); - if max_depth == 0 { - return; - } - for (i, val) in x.iter().enumerate() { - for variant in divide(*val) { - let mut copy = x.clone(); - copy.splice(i..i + 1, variant); - debug_assert_eq!(copy.iter().sum::(), VALUE); - // copy.sort_unstable(); - // copy.sort_unstable_by_key(|&i| Reverse(i)); - // println!("{}", copy.show()); - let mut sorted = copy.clone(); - sorted.sort_unstable(); - if cases.contains(&sorted) { - // eprintln!("already seen: {}", copy.show()); - continue; - } else { - cases.insert(sorted); - solve(copy, cases, max_depth - 1) - } + let mut ways = [0; TARGET + 1]; + ways[0] = 1; + for value in COIN_SIZES { + for i in value..=TARGET { + ways[i] += ways[i - value]; } } -} - -trait Display { - fn show(&self) -> String; -} - -impl Display for Values { - fn show(&self) -> String { - self.iter() - .map(|i| i.to_string()) - .reduce(|mut accum, elem| { - accum.push_str(", "); - accum.push_str(&elem); - accum - }) - .unwrap() - } -} - -fn divide(x: u8) -> Vec { - if x == 200 { - vec![vec![100, 100]] - } else if x == 100 { - vec![vec![50, 50]] - } else if x == 50 { - vec![vec![20, 20, 10], vec![20, 10, 10, 10], vec![10; 5]] - } else if x == 20 { - vec![vec![10, 10]] - } else if x == 10 { - vec![vec![5, 5]] - } else if x == 5 { - vec![vec![2, 2, 1], vec![2, 1, 1, 1], vec![1; 5]] - } else if x == 2 { - vec![vec![1, 1]] - } else { - vec![vec![x]] - } -} - -#[cfg(test)] -mod test { - use crate::solve; - use std::collections::HashSet; - - use crate::VALUE; - - #[test] - fn test_1() { - let x = vec![VALUE]; - let mut hs = HashSet::new(); - hs.insert(x.clone()); - solve(x, &mut hs, 1); - assert_eq!(hs.len(), 2); - assert!(hs.contains(&vec![VALUE])); - assert!(hs.contains(&vec![100, 100])); - } - - #[test] - fn test_2() { - let x = vec![VALUE]; - let mut hs = HashSet::new(); - hs.insert(x.clone()); - solve(x, &mut hs, 3); - assert_eq!(hs.len(), 4); - assert!(hs.contains(&vec![VALUE])); - assert!(hs.contains(&vec![100, 100])); - assert!(hs.contains(&vec![100, 50, 50])); - assert!(hs.contains(&vec![50, 50, 50, 50])); - } + println!("{:#?}", ways); }