From da5a57089cd1ac0800ebc073868798ffde9608a9 Mon Sep 17 00:00:00 2001 From: kageru Date: Sat, 12 Dec 2020 14:31:40 +0100 Subject: [PATCH] Add 2020/12 --- 2020/inputs/day12 | 786 ++++++++++++++++++++++++++++++++++++++++++ 2020/src/bin/day12.rs | 85 +++++ 2020/src/grid.rs | 38 +- 3 files changed, 898 insertions(+), 11 deletions(-) create mode 100644 2020/inputs/day12 create mode 100644 2020/src/bin/day12.rs diff --git a/2020/inputs/day12 b/2020/inputs/day12 new file mode 100644 index 0000000..45d3e1d --- /dev/null +++ b/2020/inputs/day12 @@ -0,0 +1,786 @@ +N3 +F18 +L180 +F40 +N3 +R90 +S5 +R90 +N4 +F24 +R90 +E5 +F36 +R180 +W3 +W4 +F63 +N4 +W1 +N1 +E1 +L90 +W1 +N2 +E2 +S2 +F39 +W4 +S3 +F93 +N1 +F83 +S1 +R90 +W3 +R90 +W4 +L90 +F53 +S4 +F4 +L90 +W3 +F83 +L180 +W2 +L90 +W2 +L90 +W1 +N3 +F63 +R90 +N2 +N3 +E4 +F10 +S3 +E4 +R90 +F11 +L90 +R90 +S2 +W2 +F100 +W5 +R270 +F40 +S5 +L90 +E2 +L90 +E2 +L180 +N5 +F81 +N4 +E4 +L180 +F38 +W2 +F22 +W5 +N5 +E1 +N2 +W4 +N2 +F68 +N1 +F2 +S1 +F47 +W5 +F80 +N3 +E3 +S2 +L180 +F87 +L180 +E4 +L90 +E2 +S3 +L180 +E2 +L90 +W2 +N4 +F21 +S4 +W5 +F70 +F4 +N2 +F14 +E2 +S3 +R90 +W3 +N2 +E3 +S1 +F85 +R90 +E1 +F80 +L90 +F100 +R90 +W1 +R180 +S4 +F58 +L90 +N3 +R90 +E1 +F42 +E3 +F93 +S3 +R90 +W2 +N3 +L90 +W3 +W2 +N2 +W1 +S4 +R180 +N5 +R180 +F52 +N5 +F20 +L180 +E5 +R90 +W2 +S4 +E1 +S3 +F75 +R90 +F49 +L180 +N3 +F31 +S3 +E3 +S5 +L180 +N3 +E2 +R270 +W5 +N3 +W5 +N3 +L270 +F54 +R90 +W5 +F73 +S3 +W2 +R90 +N2 +R90 +S5 +R90 +W4 +S2 +L90 +F3 +S2 +R90 +F76 +S3 +F56 +L90 +F5 +N1 +R180 +E3 +N2 +F20 +E2 +L180 +F38 +R180 +W4 +R90 +S3 +N5 +E5 +F26 +S2 +L180 +E4 +R90 +F52 +N3 +L90 +N5 +E4 +F63 +L90 +F48 +W5 +F29 +N1 +E3 +L90 +N5 +L90 +S3 +F8 +N2 +R90 +E4 +S2 +E2 +F10 +W2 +L90 +N2 +R90 +F2 +E2 +N4 +R90 +F74 +W3 +W5 +S2 +R90 +N3 +L90 +E3 +F58 +N4 +E5 +S4 +E3 +F72 +L180 +E3 +S2 +L90 +W4 +S1 +F14 +W1 +N1 +E3 +W4 +L90 +N1 +F97 +R90 +N4 +E3 +F95 +F95 +L90 +S4 +F55 +R90 +W2 +N1 +R90 +F16 +L90 +S5 +F4 +R90 +F24 +S4 +E2 +R90 +W5 +E1 +L270 +F12 +L90 +F100 +W1 +S5 +W2 +S3 +F95 +L90 +F44 +N5 +F79 +S4 +R180 +E2 +S1 +F40 +R90 +W2 +R90 +F67 +S5 +F15 +L90 +N4 +L90 +S5 +E1 +R90 +N3 +W5 +N4 +L270 +F61 +L90 +E1 +L90 +E1 +F38 +E2 +F19 +W2 +L90 +S4 +R180 +W4 +F59 +N1 +F26 +N1 +W5 +F7 +N4 +F72 +E2 +R90 +F59 +N1 +F58 +N5 +F13 +N2 +F2 +S2 +W1 +F85 +R270 +S2 +F17 +R90 +F96 +S2 +L90 +E1 +N4 +F9 +R270 +F58 +N1 +L90 +W2 +S2 +F73 +W1 +S2 +F20 +E2 +S4 +F94 +L180 +F27 +S2 +F48 +N1 +L270 +S2 +F77 +E3 +F10 +W3 +L270 +S4 +F53 +F66 +E5 +S2 +F33 +S5 +L90 +W3 +S3 +E3 +R90 +E1 +F62 +S1 +L90 +S3 +E3 +N1 +S1 +E5 +S2 +F66 +N4 +N1 +W4 +F84 +R180 +F23 +F20 +E1 +S3 +R90 +E2 +F48 +F89 +L90 +F97 +R180 +N3 +F62 +L90 +N5 +F28 +W5 +N4 +L180 +N4 +W1 +N3 +L90 +F95 +N1 +W5 +R180 +N5 +F34 +S1 +W2 +N4 +F3 +S2 +E1 +R90 +E2 +F36 +S4 +E5 +F42 +W1 +L180 +S1 +F74 +F38 +N4 +R270 +N3 +W2 +S4 +L180 +F26 +S4 +F51 +R90 +F83 +R90 +F9 +S2 +W1 +F99 +S4 +W1 +F84 +W1 +R180 +F59 +W5 +R90 +F75 +S1 +F34 +E4 +N3 +L90 +F43 +W5 +N1 +R90 +F59 +W1 +N3 +W4 +S2 +F36 +N5 +W4 +E2 +F96 +R180 +F44 +R90 +F12 +E5 +F24 +W3 +F39 +S2 +L180 +W3 +W4 +F70 +N4 +E4 +F36 +E2 +N1 +F30 +L90 +S2 +F81 +R270 +R90 +F66 +W1 +L90 +W2 +F98 +S1 +E1 +L90 +E3 +N2 +F100 +W3 +N3 +R90 +F88 +E4 +L180 +F52 +L90 +E4 +F76 +W2 +L90 +E3 +F72 +S3 +L180 +F12 +F34 +E5 +F90 +S5 +W5 +E1 +N5 +L180 +E5 +F84 +E5 +E3 +L90 +E3 +F14 +L90 +W3 +L90 +S1 +L90 +W2 +F54 +R90 +S2 +F73 +S4 +E1 +S1 +F55 +E5 +N4 +R180 +L180 +N4 +R90 +F91 +L180 +F5 +E2 +N1 +W2 +F27 +W2 +S5 +R90 +S3 +F39 +S3 +W2 +F59 +F83 +W3 +E3 +E4 +L90 +S1 +R90 +E4 +F81 +E4 +R90 +W5 +F74 +W3 +E3 +F30 +L180 +S2 +E3 +F33 +S3 +R90 +F22 +S5 +F97 +S1 +E2 +F50 +E2 +F19 +E3 +L90 +L90 +S5 +W3 +F80 +F33 +E1 +R90 +N3 +L90 +F70 +L180 +W4 +N2 +R180 +S2 +F38 +S3 +F7 +R90 +E1 +N5 +F86 +W4 +F49 +W4 +F51 +S4 +F47 +R90 +W3 +R180 +R180 +W1 +F98 +S1 +W3 +S4 +L90 +F76 +E1 +F76 +R180 +S4 +R180 +W3 +F26 +N5 +F35 +S2 +F94 +F24 +N2 +F45 +E1 +L90 +F32 +S1 +R180 +F78 +F84 +L90 +N2 +F42 +R90 +F72 +S1 +E3 +N2 +W1 +F23 +E2 +F69 +L90 +F29 +R90 +S5 +W5 +L90 +W1 +S2 +E1 +F96 +S5 +R180 +F26 +S5 +W1 +S3 +F38 +S1 +E2 +S5 +W2 +S5 +F52 +L90 +F11 +E3 +R90 +E4 +F6 +L90 +R90 +W1 +R90 +E3 +F1 +E4 +N3 +E5 +R90 +N2 +R180 +W2 +N5 +F46 +N3 +E5 +F83 +R90 +F42 +S3 +R90 +N5 +F10 diff --git a/2020/src/bin/day12.rs b/2020/src/bin/day12.rs new file mode 100644 index 0000000..ca0a3e5 --- /dev/null +++ b/2020/src/bin/day12.rs @@ -0,0 +1,85 @@ +#![feature(test)] +extern crate test; +use aoc2020::{common::*, grid::*}; + +type Parsed = Vec<(char, i64)>; + +fn read_input() -> String { + read_file(12) +} + +fn parse_input(raw: &str) -> Parsed { + raw.lines() + .map(|l| (l.bytes().next().unwrap() as char, l[1..].parse().unwrap())) + .collect() +} + +fn part1(parsed: &Parsed) -> i64 { + let end_pos = parsed + .iter() + .fold((Direction::Right, Position2D { x: 0, y: 0 }), |(dir, pos), (cmd, dist)| match cmd { + 'N' => (dir, pos + Position2D::from((0, *dist))), + 'S' => (dir, pos - Position2D::from((0, *dist))), + 'E' => (dir, pos + Position2D::from((*dist, 0))), + 'W' => (dir, pos - Position2D::from((*dist, 0))), + 'R' => (dir + (dist / 90) as i8, pos), + 'L' => (dir + -(dist / 90) as i8, pos), + 'F' => (dir, pos + Position2D::from(dir) * *dist), + _ => unreachable!(), + }) + .1; + end_pos.x.abs() + end_pos.y.abs() +} + +fn rotate_waypoint(mut wp: Position2D, deg: i64) -> Position2D { + for _ in 0..((deg / 90 + 4) % 4) { + wp = Position2D { x: wp.y, y: -wp.x }; + } + wp +} + +fn part2(parsed: &Parsed) -> i64 { + let end_pos = parsed + .iter() + .fold( + (Position2D { x: 10, y: 1 }, Position2D { x: 0, y: 0 }), + |(wp, pos), (cmd, dist)| match cmd { + 'N' => (wp + Position2D::from((0, *dist)), pos), + 'S' => (wp - Position2D::from((0, *dist)), pos), + 'E' => (wp + Position2D::from((*dist, 0)), pos), + 'W' => (wp - Position2D::from((*dist, 0)), pos), + 'R' => (rotate_waypoint(wp, *dist), pos), + 'L' => (rotate_waypoint(wp, -dist), pos), + 'F' => (wp, pos + wp * *dist), + _ => unreachable!(), + }, + ) + .1; + end_pos.x.abs() + end_pos.y.abs() +} + +fn main() { + let input = parse_input(&read_input()); + println!("Part 1: {}", part1(&input)); + println!("Part 2: {}", part2(&input)); +} + +#[cfg(test)] +mod tests { + use super::*; + use aoc2020::*; + use paste::paste; + use test::black_box; + + const TEST_INPUT: &str = "F10 +N3 +F7 +R90 +F11"; + + test!(part1() == 25); + test!(part2() == 286); + bench!(part1() == 1838); + bench!(part2() == 89936); + bench_input!(len == 786); +} diff --git a/2020/src/grid.rs b/2020/src/grid.rs index 4bbc32a..19937f7 100644 --- a/2020/src/grid.rs +++ b/2020/src/grid.rs @@ -76,29 +76,47 @@ impl Direction { } } +impl From for Position2D { + fn from(d: Direction) -> Self { + match d { + Direction::Up => Position2D::from((0, 1)), + Direction::Right => Position2D::from((1, 0)), + Direction::Left => Position2D::from((-1, 0)), + Direction::Down => Position2D::from((0, -1)), + } + } +} + impl_op!(+ |a: Direction, b: i8| -> Direction { match b { - -1 => match a { + -1 | 3 => match a { Direction::Up => Direction::Left, Direction::Right => Direction::Up, Direction::Down => Direction::Right, Direction::Left => Direction::Down, }, - 1 => match a { + 1 | -3 => match a { Direction::Up => Direction::Right, Direction::Right => Direction::Down, Direction::Down => Direction::Left, Direction::Left => Direction::Up, }, - 0 => a, + 0 | 4 | -4 => a, + 2 | -2 => match a { + Direction::Up => Direction::Down, + Direction::Right => Direction::Left, + Direction::Down => Direction::Up, + Direction::Left => Direction::Right, + }, n => unreachable!(format!("Illegal turn value: {}", n)), } }); -impl_op!(+ |a: Position2D, b: Position2D| -> Position2D { +impl_op!(+|a: Position2D, b: Position2D| -> Position2D { Position2D { x: a.x + b.x, - y: a.y + b.y } + y: a.y + b.y + } }); impl_op!(-|a: Position2D, b: Position2D| -> Position2D { @@ -108,14 +126,12 @@ impl_op!(-|a: Position2D, b: Position2D| -> Position2D { } }); -impl_op!(+ |a: Position2D, b: Direction| -> Position2D { a + match b { - Direction::Up => Position2D::from((0, 1)), - Direction::Right => Position2D::from((1, 0)), - Direction::Left => Position2D::from((-1, 0)), - Direction::Down => Position2D::from((0, -1)), - } +impl_op!(+|a: Position2D, b: Direction| -> Position2D { + a + Position2D::from(b) }); +impl_op!(-|a: Position2D, b: Direction| -> Position2D { a - Position2D::from(b) }); + impl_op!(*|a: Position2D, b: i64| -> Position2D { Position2D { x: a.x * b, y: a.y * b } }); impl AddAssign for Direction {