--- /dev/null
+use std::error::Error;
+use std::path::Path;
+use std::collections::HashSet;
+
+fn is_valid_design(design: &str, patterns: &HashSet<&str>) -> bool {
+
+ if design.is_empty() {
+ return true
+ }
+
+ for i in 0..design.len() {
+ if patterns.contains(&design[0..=i]) &&
+ is_valid_design(&design[(i+1)..design.len()], patterns)
+ {
+ return true
+ }
+ }
+
+ false
+}
+
+fn run_part1(input: &str) -> Result<u32, Box<dyn Error>> {
+ println!("Running {} - part 1", get_day());
+
+ let (patterns, designs) = input.split_once("\n\n").unwrap();
+ let patterns: HashSet<&str> = patterns.split(", ")
+ .collect();
+
+ let res = designs.lines()
+ .filter(|d| is_valid_design(d, &patterns))
+ .count() as u32;
+
+ Ok(res)
+}
+
+fn run_part2(input: &str) -> Result<u32, Box<dyn Error>> {
+ println!("Running {} - part 2", get_day());
+
+ Ok(0)
+}
+
+pub fn run(input: &str) -> Result<(), Box<dyn Error>> {
+ let res = run_part1(input)?;
+ println!("{res}");
+
+ let res = run_part2(input)?;
+ println!("{res}");
+
+ Ok(())
+}
+
+fn get_day() -> String {
+ let filename = file!();
+ Path::new(filename).file_stem().unwrap().to_str().unwrap().to_string()
+}
+
+#[cfg(test)]
+mod tests {
+ use super::*;
+
+ static TEXT_INPUT: &str = "\
+r, wr, b, g, bwu, rb, gb, br
+
+brwrr
+bggr
+gbbr
+rrbgbr
+ubwu
+bwurrg
+brgr
+bbrgwb";
+
+ static TEXT_INPUT_1: &str = "\
+abcde
+
+abcde
+abcdee";
+
+ static TEXT_INPUT_2: &str = "\
+a, b, c, d, e
+
+abcde
+abcdee";
+
+ static TEXT_INPUT_3: &str = "\
+a, b, bc, d, ee
+
+abcde
+abcdee
+abcdeea";
+
+ #[test]
+ fn test_part1() {
+ assert_eq!(6, run_part1(TEXT_INPUT).unwrap());
+ assert_eq!(1, run_part1(TEXT_INPUT_1).unwrap());
+ assert_eq!(2, run_part1(TEXT_INPUT_2).unwrap());
+ assert_eq!(2, run_part1(TEXT_INPUT_3).unwrap());
+ }
+
+ #[test]
+ fn test_part2() {
+ assert_eq!(0, run_part2(TEXT_INPUT).unwrap());
+ }
+}
pub mod day16;
pub mod day17;
pub mod day18;
+pub mod day19;
fn main() {
let args: Vec<String> = env::args().collect();
"day16" => day16::run(&input)?,
"day17" => day17::run(&input)?,
"day18" => day18::run(&input)?,
+ "day19" => day19::run(&input)?,
_ => return Err(format!("unknown or unimplemented day \"{day}\"").into()),
}
Ok(())