From 98f77e7ed7c9592aa066ce4a614b17dc9e1ddf18 Mon Sep 17 00:00:00 2001 From: Jonni Liljamo Date: Fri, 13 Dec 2024 16:52:16 +0200 Subject: [PATCH] feat: day13 --- input/day13/example | 15 +++++++ src/day13/mod.rs | 11 +++++ src/day13/part1.rs | 97 +++++++++++++++++++++++++++++++++++++++++++++ src/day13/part2.rs | 94 +++++++++++++++++++++++++++++++++++++++++++ src/main.rs | 8 ++++ 5 files changed, 225 insertions(+) create mode 100644 input/day13/example create mode 100644 src/day13/mod.rs create mode 100644 src/day13/part1.rs create mode 100644 src/day13/part2.rs diff --git a/input/day13/example b/input/day13/example new file mode 100644 index 0000000..912f482 --- /dev/null +++ b/input/day13/example @@ -0,0 +1,15 @@ +Button A: X+94, Y+34 +Button B: X+22, Y+67 +Prize: X=8400, Y=5400 + +Button A: X+26, Y+66 +Button B: X+67, Y+21 +Prize: X=12748, Y=12176 + +Button A: X+17, Y+86 +Button B: X+84, Y+37 +Prize: X=7870, Y=6450 + +Button A: X+69, Y+23 +Button B: X+27, Y+71 +Prize: X=18641, Y=10279 diff --git a/src/day13/mod.rs b/src/day13/mod.rs new file mode 100644 index 0000000..3966e37 --- /dev/null +++ b/src/day13/mod.rs @@ -0,0 +1,11 @@ +use std::path::Path; + +mod part1; +mod part2; + +pub fn solve(input: &Path) -> anyhow::Result<()> { + println!("part one: {}", part1::part_one(input)?); + println!("part two: {}", part2::part_two(input)?); + + Ok(()) +} diff --git a/src/day13/part1.rs b/src/day13/part1.rs new file mode 100644 index 0000000..272add3 --- /dev/null +++ b/src/day13/part1.rs @@ -0,0 +1,97 @@ +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) +} diff --git a/src/day13/part2.rs b/src/day13/part2.rs new file mode 100644 index 0000000..d308ba4 --- /dev/null +++ b/src/day13/part2.rs @@ -0,0 +1,94 @@ +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() + + 10000000000000, + y: p_line[&p_line.find("Y").unwrap() + 2..p_line.len()] + .parse::() + .unwrap() + + 10000000000000, + }, + } + } +} + +#[derive(Debug)] +struct P { + x: usize, + y: usize, +} + +pub fn part_two(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 m in machines { + println!(); + println!("{}x + {}y = {}", m.a.x, m.b.x, m.p.x); + println!("{}x + {}y = {}", m.a.y, m.b.y, m.p.y); + println!(); + + let b: i64 = (m.p.y as i64 * m.a.x as i64 - m.p.x as i64 * m.a.y as i64) + / (m.b.y as i64 * m.a.x as i64 - m.b.x as i64 * m.a.y as i64); + let a: i64 = (m.p.x as i64 - b * m.b.x as i64) / m.a.x as i64; + if m.a.x as i64 * a + m.b.x as i64 * b == m.p.x as i64 + && m.a.y as i64 * a + m.b.y as i64 * b == m.p.y as i64 + { + answer += a * 3 + b; + println!("yes"); + } + } + + Ok(answer as usize) +} diff --git a/src/main.rs b/src/main.rs index a0fdb09..99c445c 100644 --- a/src/main.rs +++ b/src/main.rs @@ -6,6 +6,7 @@ mod day1; mod day10; mod day11; mod day12; +mod day13; mod day2; mod day3; mod day4; @@ -71,6 +72,10 @@ enum DayArgs { #[arg(short)] input: PathBuf, }, + Day13 { + #[arg(short)] + input: PathBuf, + }, } fn main() -> anyhow::Result<()> { @@ -113,6 +118,9 @@ fn main() -> anyhow::Result<()> { DayArgs::Day12 { input } => { day12::solve(&input)?; } + DayArgs::Day13 { input } => { + day13::solve(&input)?; + } } Ok(()) -- 2.44.1