diff --git a/src/day19/1.rs b/src/day19/1.rs new file mode 100644 index 0000000..73ed073 --- /dev/null +++ b/src/day19/1.rs @@ -0,0 +1,61 @@ +#![feature(test)] +extern crate test; + +use fxhash::FxHashSet; + +const INPUTS: [&str; 2] = [ + "r, wr, b, g, bwu, rb, gb, br + +brwrr +bggr +gbbr +rrbgbr +ubwu +bwurrg +brgr +bbrgwb", + include_str!("./input.txt"), +]; + +pub fn run(input: &str) -> i64 { + let (towels, to_make) = input.split_once("\n\n").unwrap(); + let towels = towels.split(", ").map(|x| x.bytes().collect::>()).collect::>>(); + let to_make = to_make.lines().map(|x| x.bytes().collect::>()); + + let mut count = 0; + for pattern in to_make { + count += test(&towels, &pattern) as i64; + } + count +} + +fn test(towels: &FxHashSet>, pattern: &[u8]) -> bool { + let n = pattern.len(); + let mut dp = vec![false; n + 1]; + dp[0] = true; + + for i in 1..n+1 { + for j in 0..i { + if dp[j] && towels.contains(&pattern[j..i]) { + dp[i] = true; + break; + } + } + } + + dp[n] +} + +fn main() { + for input in INPUTS.iter() { + println!("answer = {}", run(input)); + } +} + +#[bench] +fn part1(b: &mut test::Bencher) { + b.iter(|| { + let v = run(INPUTS[1]); + test::black_box(v); + }); +} diff --git a/src/day19/2.rs b/src/day19/2.rs new file mode 100644 index 0000000..878ccb7 --- /dev/null +++ b/src/day19/2.rs @@ -0,0 +1,61 @@ +#![feature(test)] +extern crate test; + +use fxhash::FxHashSet; + +const INPUTS: [&str; 2] = [ + "r, wr, b, g, bwu, rb, gb, br + +brwrr +bggr +gbbr +rrbgbr +ubwu +bwurrg +brgr +bbrgwb", + include_str!("./input.txt"), +]; + +pub fn run(input: &str) -> i64 { + let (towels, to_make) = input.split_once("\n\n").unwrap(); + let towels = towels.split(", ").map(|x| x.bytes().collect::>()).collect::>>(); + let to_make = to_make.lines().map(|x| x.bytes().collect::>()); + + let mut count = 0; + for pattern in to_make { + let sum = test(&towels, &pattern); + count += sum; + } + count +} + +fn test(towels: &FxHashSet>, pattern: &[u8]) -> i64 { + let n = pattern.len(); + let mut dp = vec![0; n + 1]; + dp[0] = 1; // only 1 way to make an empty string + + for i in 1..n+1 { + for j in 0..i { + if towels.contains(&pattern[j..i]) { + dp[i] += dp[j]; + } + } + } + + dp[n] +} + +fn main() { + for input in INPUTS.iter() { + println!("answer = {}", run(input)); + } +} + +#[bench] +fn part1(b: &mut test::Bencher) { + b.iter(|| { + let v = run(INPUTS[1]); + test::black_box(v); + }); +}