From e8c2ceae5b084227642037e6c17a4492f3a982ab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stefan=20B=C3=BChler?= Date: Sat, 12 Dec 2020 12:03:28 +0100 Subject: [PATCH] day 12 --- data/day12/input | 770 +++++++++++++++++++++++++++++++++++++++++++++++ src/bin/day12.rs | 183 +++++++++++ 2 files changed, 953 insertions(+) create mode 100644 data/day12/input create mode 100644 src/bin/day12.rs diff --git a/data/day12/input b/data/day12/input new file mode 100644 index 0000000..c64cbfd --- /dev/null +++ b/data/day12/input @@ -0,0 +1,770 @@ +R90 +F58 +S2 +E4 +F28 +W3 +N2 +F25 +E1 +F24 +W2 +F91 +S3 +F83 +L90 +F24 +R90 +N3 +R90 +F5 +W5 +E1 +S1 +E5 +F47 +F83 +N1 +F64 +W2 +R90 +S1 +R180 +N2 +R180 +S3 +F35 +E2 +S3 +W2 +R270 +F57 +E5 +F100 +N3 +L90 +F70 +E5 +L90 +F65 +L90 +S2 +W5 +F73 +L90 +E3 +R90 +W2 +S2 +L180 +E4 +W3 +R90 +E2 +F18 +N4 +W5 +R90 +S1 +F55 +W2 +L90 +S1 +L180 +E4 +N1 +R90 +F31 +N5 +E4 +R90 +W4 +F18 +W4 +N2 +L90 +F6 +N3 +L180 +F89 +R90 +N4 +L180 +S4 +W1 +F87 +N1 +F80 +E4 +R90 +N4 +F38 +E5 +F74 +S4 +R180 +S1 +L90 +W1 +F88 +S1 +F42 +S1 +R90 +F2 +R90 +E2 +S1 +F57 +E1 +F53 +R180 +F97 +W2 +R90 +F70 +R180 +W1 +R180 +W5 +E5 +N1 +E5 +F63 +N3 +F24 +L90 +S5 +W5 +R90 +W4 +F27 +R90 +E2 +L180 +E4 +F16 +L90 +F47 +S3 +E1 +S2 +L90 +W5 +F80 +E4 +F10 +N5 +E3 +N4 +W2 +L90 +E1 +F83 +R180 +S4 +L90 +E1 +F94 +N2 +R90 +S5 +L180 +E1 +F40 +E5 +L180 +W5 +F57 +E1 +N5 +W5 +F62 +L180 +W3 +F12 +E4 +F93 +R270 +F8 +S3 +W3 +L90 +W1 +N1 +E4 +L90 +E2 +S2 +E1 +L270 +E5 +N5 +F81 +L90 +W5 +F82 +E5 +L90 +F24 +F3 +F14 +L180 +N5 +E1 +F11 +R90 +F22 +L90 +S1 +F82 +S4 +F38 +L90 +F31 +R180 +W4 +F88 +E3 +R90 +N5 +F9 +S3 +W4 +L90 +W5 +R90 +F5 +S4 +F91 +N4 +S4 +W4 +S4 +F78 +N2 +F67 +L180 +N3 +R90 +F65 +N2 +E1 +F46 +E2 +L180 +S4 +E2 +F98 +L90 +W2 +N1 +E3 +F7 +S4 +F90 +S2 +W3 +R90 +F30 +E4 +F2 +L90 +F17 +E4 +R90 +F94 +N3 +E5 +R180 +S4 +F76 +E2 +F94 +R90 +N5 +W2 +F89 +W1 +F83 +N5 +W5 +F62 +S1 +W4 +N5 +E2 +R90 +F14 +R90 +N5 +W4 +R180 +E2 +R90 +L90 +F67 +N4 +L90 +E4 +F93 +W5 +F85 +L180 +F45 +W2 +F78 +N3 +F90 +L90 +W1 +S2 +L90 +S5 +E5 +F82 +S4 +F36 +E5 +L90 +E1 +F13 +S2 +E3 +F65 +L90 +E3 +E4 +F1 +W5 +S3 +F14 +L90 +F47 +L90 +S3 +W4 +F18 +E1 +N3 +E5 +F58 +E5 +S1 +W2 +F48 +W5 +F65 +N5 +E1 +N3 +R90 +N2 +L90 +N4 +F21 +R90 +F58 +W1 +F7 +R90 +E4 +N5 +F47 +W4 +L90 +N4 +R90 +E1 +L180 +F8 +E3 +W4 +F41 +E3 +S5 +E5 +S3 +E3 +F14 +N4 +R90 +W3 +L90 +E5 +R180 +W4 +S1 +N2 +F93 +L90 +F41 +R180 +F37 +R90 +E1 +L180 +N5 +F96 +W3 +R90 +E1 +F88 +S2 +E2 +L90 +N2 +W4 +F34 +E4 +F69 +L90 +N3 +F18 +W3 +S4 +F44 +E2 +L90 +N2 +F55 +R90 +E1 +L90 +S5 +E2 +N3 +L90 +N1 +F55 +W5 +N2 +E2 +F20 +S2 +W5 +S1 +W5 +R180 +F100 +F44 +S2 +L90 +E3 +F98 +N3 +R90 +W4 +F14 +N2 +F87 +W5 +F12 +L180 +S2 +W1 +N1 +W1 +R90 +L180 +F64 +E2 +F41 +L90 +F20 +R270 +F91 +N4 +L180 +F28 +W4 +F40 +R90 +F40 +F36 +E3 +L270 +F76 +L90 +N2 +F15 +N5 +E4 +L180 +S1 +R90 +E1 +F81 +R90 +F96 +N1 +E5 +R90 +S5 +L90 +S1 +S4 +R90 +F30 +E1 +N5 +E2 +S3 +F97 +N3 +R90 +N1 +R90 +E3 +R180 +E3 +F8 +R90 +W2 +F27 +L90 +N5 +W3 +L90 +E5 +R180 +S1 +L90 +F51 +S4 +L180 +N1 +W4 +F71 +W2 +R90 +E4 +F29 +E4 +L90 +L90 +F68 +W2 +F57 +E3 +R90 +S2 +F94 +W4 +S2 +L180 +E3 +N2 +F52 +E3 +S1 +S5 +R90 +E1 +F35 +W3 +F53 +R270 +E3 +F81 +S2 +L90 +W4 +F86 +N5 +E4 +R90 +N5 +F99 +L180 +F65 +R90 +S2 +W3 +F33 +E3 +R270 +F34 +E1 +F56 +S2 +E5 +R180 +N2 +E3 +N3 +F30 +N2 +F22 +E5 +F10 +N2 +F16 +N1 +F31 +R90 +E2 +F78 +E4 +R180 +S3 +R90 +F80 +E5 +S1 +F49 +E1 +S2 +E4 +N4 +R90 +F9 +W1 +E4 +N3 +N5 +E4 +L90 +S5 +E2 +R90 +F74 +R180 +N2 +F98 +S2 +W4 +W4 +F73 +E2 +N4 +E1 +F25 +S2 +E5 +L90 +F96 +N2 +E3 +N3 +F16 +S5 +L90 +F43 +S2 +R90 +S1 +F46 +S3 +F82 +S5 +S4 +E5 +F58 +R90 +F51 +R90 +N4 +L90 +W3 +S4 +R90 +F15 +E1 +S4 +W3 +S2 +W1 +R90 +F76 +S1 +L180 +F5 +R180 +E1 +L180 +W3 +F47 +W4 +F68 +E5 +F75 +W3 +N1 +R90 +S1 +W5 +R90 +E2 +F78 +W2 +L90 +F24 +W5 +R90 +F75 +E1 +F35 +E5 +R90 +F57 +L180 +S1 +L90 +F90 +R180 +F63 +S3 +R180 +W3 +F79 +N5 +E4 +F81 +E3 +F6 +R90 +E4 +L90 +W5 +L180 +W2 +S4 +F26 +L90 +E5 +S3 +L90 +F3 +L90 +S2 +R90 +F55 +W5 +S1 +E3 +F63 +L180 +N2 +E2 +L90 +S4 +E3 +F18 +W4 +N2 +W5 +R90 +E5 +L90 +F96 +N3 +F7 +N1 +F87 +R90 +F53 +R90 +W5 +S3 +F94 diff --git a/src/bin/day12.rs b/src/bin/day12.rs new file mode 100644 index 0000000..c1d0c3e --- /dev/null +++ b/src/bin/day12.rs @@ -0,0 +1,183 @@ +const INPUT: &str = include_str!("../../data/day12/input"); + +#[derive(Clone, Copy, PartialEq, Eq, Debug)] +enum Rotate { + Left, + Back, + Right, +} + +#[derive(Clone, Copy, PartialEq, Eq, Debug)] +enum Action { + Forward(u32), + RotateWaypoint(Rotate), + MoveWaypoint(Direction, u32), +} + +impl Action { + fn parse(line: &str) -> Self { + let dir = match line.as_bytes()[0] { + b'N' => |n| Self::MoveWaypoint(Direction::North, n), + b'E' => |n| Self::MoveWaypoint(Direction::East, n), + b'W' => |n| Self::MoveWaypoint(Direction::West, n), + b'S' => |n| Self::MoveWaypoint(Direction::South, n), + b'F' => Self::Forward, + _ => { + let rot = match line { + "L90"|"R270" => Rotate::Left, + "L180"|"R180" => Rotate::Back, + "L270"|"R90" => Rotate::Right, + _ => panic!("Invalid action line: {:?}", line), + }; + return Self::RotateWaypoint(rot); + }, + }; + dir(line[1..].parse().unwrap()) + } + + fn parse_list(input: &str) -> Vec { + input.lines().map(Self::parse).collect() + } +} + +#[derive(Clone, Copy, PartialEq, Eq, Debug)] +enum Direction { + North, + East, + South, + West, +} + +impl Direction { + fn rotate(self, rotate: Rotate) -> Self { + match (rotate, self) { + (Rotate::Left, Self::East)|(Rotate::Right, Self::West)|(Rotate::Back, Self::South) => Self::North, + (Rotate::Left, Self::South)|(Rotate::Right, Self::North)|(Rotate::Back, Self::West) => Self::East, + (Rotate::Left, Self::West)|(Rotate::Right, Self::East)|(Rotate::Back, Self::North) => Self::South, + (Rotate::Left, Self::North)|(Rotate::Right, Self::South)|(Rotate::Back, Self::East) => Self::West, + } + } +} + +impl From for Point { + fn from(d: Direction) -> Self { + match d { + Direction::North => Self { north: 1, east: 0 }, + Direction::East => Self { north: 0, east: 1 }, + Direction::South => Self { north: -1, east: 0 }, + Direction::West => Self { north: 0, east: -1 }, + } + } +} + +#[derive(Clone, Copy, PartialEq, Eq, Debug)] +struct Point { + north: i64, + east: i64, +} + +impl std::ops::Add for Point { + type Output = Self; + + fn add(self, rhs: Point) -> Self::Output { + Self { + north: self.north + rhs.north, + east: self.east + rhs.east, + } + } +} + +impl std::ops::Mul for u32 { + type Output = Point; + + fn mul(self, rhs: Point) -> Self::Output { + Point { + north: (self as i64) * rhs.north, + east: (self as i64) * rhs.east, + } + } +} + +impl std::ops::Mul for Rotate { + type Output = Point; + + fn mul(self, rhs: Point) -> Self::Output { + match self { + Self::Left => Point { north: rhs.east, east: -rhs.north }, + Self::Right => Point { north: -rhs.east, east: rhs.north }, + Self::Back => Point { north: -rhs.north, east: -rhs.east }, + } + } +} + +#[derive(Clone, Copy, PartialEq, Eq, Debug)] +struct ShipPart1 { + direction: Direction, + position: Point, +} + +impl ShipPart1 { + fn new() -> Self { + Self { + direction: Direction::East, + position: Point { north: 0, east: 0 }, + } + } + + fn apply(&mut self, action: Action) { + let (dir, inc) = match action { + Action::RotateWaypoint(rotate) => { + self.direction = self.direction.rotate(rotate); + return; + }, + Action::Forward(inc) => { + (self.direction, inc) + }, + Action::MoveWaypoint(dir, inc) => (dir, inc), + }; + self.position = self.position + inc * Point::from(dir); + } +} + +#[derive(Clone, Copy, PartialEq, Eq, Debug)] +struct ShipPart2 { + waypoint: Point, + position: Point, +} + +impl ShipPart2 { + fn new() -> Self { + Self { + waypoint: Point { north: 1, east: 10 }, + position: Point { north: 0, east: 0 }, + } + } + + fn apply(&mut self, action: Action) { + match action { + Action::RotateWaypoint(rotate) => { + self.waypoint = rotate * self.waypoint; + }, + Action::Forward(inc) => { + self.position = self.position + inc * self.waypoint; + }, + Action::MoveWaypoint(dir, inc) => { + self.waypoint = self.waypoint + inc * Point::from(dir); + } + } + } +} + +fn main() { + let actions = Action::parse_list(INPUT); + let mut ship = ShipPart1::new(); + for &action in &actions { + ship.apply(action); + } + println!("Manhattan distance: {}", ship.position.north.abs() + ship.position.east.abs()); + let mut ship = ShipPart2::new(); + for &action in &actions { + ship.apply(action); + } + println!("Manhattan distance: {}", ship.position.north.abs() + ship.position.east.abs()); +}