From 8e9dc7c388d392aeb9c14924728d8a8e5301d55b Mon Sep 17 00:00:00 2001 From: Jan-Bulthuis Date: Sat, 21 Dec 2024 13:03:49 +0100 Subject: [PATCH] day21 flawed --- aoc_2024/src/day20.rs | 6 -- aoc_2024/src/day21.rs | 241 ++++++++++++++++++++++++++++++++++++++++++ aoc_2024/src/lib.rs | 1 + 3 files changed, 242 insertions(+), 6 deletions(-) create mode 100644 aoc_2024/src/day21.rs diff --git a/aoc_2024/src/day20.rs b/aoc_2024/src/day20.rs index 6847a33..4cc7bdb 100644 --- a/aoc_2024/src/day20.rs +++ b/aoc_2024/src/day20.rs @@ -111,9 +111,6 @@ fn part1(input: &Input) -> usize { && dist[ny as usize][nx as usize] >= dist[y as usize][x] + min_saving + 2 }) - // .inspect(|v| { - // println!("{:?} {:?}", (x, y), v); - // }) .count() } else { 0 @@ -195,9 +192,6 @@ fn part2(input: &Input) -> usize { + dx.unsigned_abs() + dy.unsigned_abs() }) - // .inspect(|v| { - // println!("{:?} {:?}", (x, y), v); - // }) .count() } else { 0 diff --git a/aoc_2024/src/day21.rs b/aoc_2024/src/day21.rs new file mode 100644 index 0000000..cbed375 --- /dev/null +++ b/aoc_2024/src/day21.rs @@ -0,0 +1,241 @@ +use aoc_runner_derive::{aoc, aoc_generator}; + +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +enum Button { + Directional(DirectionalButton), + Numeric(NumericButton), +} + +impl Button { + fn pos(&self) -> (isize, isize) { + match self { + Button::Directional(button) => button.pos(), + Button::Numeric(button) => button.pos(), + } + } + + fn to(&self, other: &Button) -> Vec { + match (self, other) { + (Button::Directional(a), Button::Directional(b)) => a.to(b), + (Button::Numeric(a), Button::Numeric(b)) => a.to(b), + _ => unimplemented!(), + } + } +} + +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +enum DirectionalButton { + Up, + Down, + Left, + Right, + A, +} + +impl DirectionalButton { + fn pos(&self) -> (isize, isize) { + match self { + DirectionalButton::Up => (1, 0), + DirectionalButton::Down => (1, 1), + DirectionalButton::Left => (0, 1), + DirectionalButton::Right => (2, 1), + DirectionalButton::A => (2, 0), + } + } + + fn to(&self, other: &DirectionalButton) -> Vec { + let start = self.pos(); + let end = other.pos(); + let mut x = if start.0 < end.0 { + vec![DirectionalButton::Right; (end.0 - start.0) as usize] + } else { + vec![DirectionalButton::Left; (start.0 - end.0) as usize] + }; + let mut y = if start.1 < end.1 { + vec![DirectionalButton::Down; (end.1 - start.1) as usize] + } else { + vec![DirectionalButton::Up; (start.1 - end.1) as usize] + }; + if end.0 == 0 { + y.append(&mut x); + y + } else { + x.append(&mut y); + x + } + } +} + +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +enum NumericButton { + Number(u8), + A, +} + +impl NumericButton { + fn pos(&self) -> (isize, isize) { + match self { + NumericButton::Number(1) => (0, 2), + NumericButton::Number(2) => (1, 2), + NumericButton::Number(3) => (2, 2), + NumericButton::Number(4) => (0, 1), + NumericButton::Number(5) => (1, 1), + NumericButton::Number(6) => (2, 1), + NumericButton::Number(7) => (0, 0), + NumericButton::Number(8) => (1, 0), + NumericButton::Number(9) => (2, 0), + NumericButton::Number(0) => (1, 3), + NumericButton::A => (2, 3), + _ => unreachable!(), + } + } + + fn to(&self, other: &NumericButton) -> Vec { + let start = self.pos(); + let end = other.pos(); + let mut x = if start.0 < end.0 { + vec![DirectionalButton::Right; (end.0 - start.0) as usize] + } else { + vec![DirectionalButton::Left; (start.0 - end.0) as usize] + }; + let mut y = if start.1 < end.1 { + vec![DirectionalButton::Down; (end.1 - start.1) as usize] + } else { + vec![DirectionalButton::Up; (start.1 - end.1) as usize] + }; + if end.1 != 3 { + y.append(&mut x); + y + } else { + x.append(&mut y); + x + } + } +} + +type Input = Vec>; + +#[aoc_generator(day21)] +fn parse(input: &str) -> Input { + input + .lines() + .map(|line| { + line.chars() + .map(|c| match c { + '0' => NumericButton::Number(0), + '1' => NumericButton::Number(1), + '2' => NumericButton::Number(2), + '3' => NumericButton::Number(3), + '4' => NumericButton::Number(4), + '5' => NumericButton::Number(5), + '6' => NumericButton::Number(6), + '7' => NumericButton::Number(7), + '8' => NumericButton::Number(8), + '9' => NumericButton::Number(9), + 'A' => NumericButton::A, + _ => unreachable!(), + }) + .map(Button::Numeric) + .collect() + }) + .collect() +} + +#[aoc(day21, part1)] +fn part1(input: &Input) -> usize { + input + .iter() + .cloned() + .map(|instruction| { + let mut instructions = vec![]; + let mut stack = vec![]; + let num_robots = 3; + let mut positions = vec![Button::Numeric(NumericButton::A)]; + for _ in 1..num_robots { + positions.push(Button::Directional(DirectionalButton::A)); + } + for button in instruction.iter().rev() { + stack.push((0, *button)); + } + + while let Some((robot, button)) = stack.pop() { + if robot == num_robots { + instructions.push(button); + continue; + } + + println!( + "move {} from {:?} to {:?} = {:?}", + robot, + positions[robot].pos(), + button.pos(), + button + ); + + let instructions = positions[robot].to(&button); + stack.push((robot + 1, Button::Directional(DirectionalButton::A))); + for instruction in instructions.iter().rev() { + stack.push((robot + 1, Button::Directional(*instruction))); + } + positions[robot] = button; + } + + let numeric = instruction + .iter() + .filter_map(|button| match button { + Button::Numeric(NumericButton::Number(numeric)) => Some(numeric), + _ => None, + }) + .fold(String::new(), |mut acc, num| { + acc.push_str(&num.to_string()); + acc + }) + .parse::() + .unwrap(); + + dbg!(instructions.len()); + println!( + "{}", + instructions + .iter() + .map(|instruction| match instruction { + Button::Directional(DirectionalButton::Up) => '^', + Button::Directional(DirectionalButton::Down) => 'v', + Button::Directional(DirectionalButton::Left) => '<', + Button::Directional(DirectionalButton::Right) => '>', + Button::Directional(DirectionalButton::A) => 'A', + _ => unreachable!(), + }) + .collect::() + ); + numeric * instructions.len() + }) + .sum() +} + +// #[aoc(day21, part2)] +// fn part2(input: &Input) -> usize { +// todo!() +// } + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn part1_example() { + // assert_eq!(part1(&parse("179A")), 68 * 179); + assert_eq!(part1(&parse("379A")), 64 * 379); + assert_eq!(part1(&parse("456A")), 64 * 456); + assert_eq!(part1(&parse("980A")), 60 * 980); + assert_eq!(part1(&parse("029A")), 68 * 29); + } + + // #[test] + // fn part2_example() { + // assert_eq!(part2(&parse("")), 0); + // } +} + +// 89666 too low +// 97150 wrong diff --git a/aoc_2024/src/lib.rs b/aoc_2024/src/lib.rs index 21a9bff..df49ff2 100644 --- a/aoc_2024/src/lib.rs +++ b/aoc_2024/src/lib.rs @@ -1,3 +1,4 @@ +mod day21; mod day1; mod day10; mod day11;