use std::{ fs::File, io::{BufRead, BufReader}, path::Path, }; #[derive(Debug)] struct M { a: P, b: P, p: P, } impl M { fn from_lines(lines: &[String]) -> Self { let a_line = &lines[0]; let b_line = &lines[1]; let p_line = &lines[2]; Self { a: P { x: a_line[&a_line.find("X").unwrap() + 2..a_line.find(",").unwrap()] .parse() .unwrap(), y: a_line[&a_line.find("Y").unwrap() + 2..a_line.len()] .parse() .unwrap(), }, b: P { x: b_line[&b_line.find("X").unwrap() + 2..b_line.find(",").unwrap()] .parse() .unwrap(), y: b_line[&b_line.find("Y").unwrap() + 2..b_line.len()] .parse() .unwrap(), }, p: P { x: p_line[&p_line.find("X").unwrap() + 2..p_line.find(",").unwrap()] .parse() .unwrap(), y: p_line[&p_line.find("Y").unwrap() + 2..p_line.len()] .parse() .unwrap(), }, } } } #[derive(Debug)] struct P { x: usize, y: usize, } pub fn part_one(input: &Path) -> anyhow::Result { let reader = BufReader::new(File::open(input)?); let machines: Vec = reader .lines() .filter_map(|l| { let l = l.unwrap(); if !l.is_empty() { Some(l) } else { None } }) .collect::>() .chunks(3) .map(|l| -> M { M::from_lines(l) }) .collect(); let mut answer = 0; for machine in machines { let mut oks: Vec = vec![]; let (mut x, mut y) = (0, 0); 'a: for a in 1..101 { x += machine.a.x; y += machine.a.y; let (mut x, mut y) = (x, y); for b in 1..101 { x += machine.b.x; y += machine.b.y; if x == machine.p.x && y == machine.p.y { oks.push(a * 3 + b); continue 'a; } } } if !oks.is_empty() { oks.sort(); answer += oks.first().unwrap(); } } Ok(answer) }