From 8b4521b8d0925ac65404f9f7e634e249e68e3a21 Mon Sep 17 00:00:00 2001 From: Justin Wernick Date: Sun, 13 Dec 2020 13:33:23 +0200 Subject: Day 12 --- inputs/day_12.txt | 755 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/bin/day_12.rs | 233 +++++++++++++++++ 2 files changed, 988 insertions(+) create mode 100644 inputs/day_12.txt create mode 100644 src/bin/day_12.rs diff --git a/inputs/day_12.txt b/inputs/day_12.txt new file mode 100644 index 0000000..d7bc269 --- /dev/null +++ b/inputs/day_12.txt @@ -0,0 +1,755 @@ +F93 +R90 +F81 +E3 +F80 +R90 +W4 +R90 +F64 +N1 +R90 +W4 +F11 +W1 +L180 +F28 +R90 +W4 +L180 +F95 +N3 +F71 +L90 +W1 +F1 +E2 +L90 +F85 +W3 +L90 +F28 +E3 +N5 +F47 +S2 +R90 +N2 +L90 +W4 +L180 +W3 +F51 +F77 +L90 +W5 +N5 +W3 +S5 +W5 +R180 +N1 +W3 +S5 +F36 +W1 +F34 +N4 +F40 +E2 +S3 +R90 +W5 +S2 +N4 +R90 +S2 +L90 +N4 +L90 +S2 +E1 +F2 +N4 +F65 +N1 +F46 +R180 +F60 +N4 +F45 +R90 +S3 +L90 +F70 +W4 +L270 +N4 +F49 +E3 +F52 +R180 +F5 +E5 +R90 +F43 +L90 +S4 +F54 +N1 +F7 +S2 +F91 +S4 +N3 +E3 +S4 +L180 +F15 +S2 +F90 +W5 +S2 +F80 +N4 +L90 +R90 +N4 +E2 +R180 +E5 +F62 +L90 +N5 +F77 +N5 +F75 +E2 +L90 +S4 +F55 +E1 +N5 +F57 +R90 +F6 +L90 +N3 +E5 +L180 +N2 +L270 +N5 +F8 +E2 +F88 +E3 +N3 +E4 +R90 +N1 +W5 +R90 +N4 +E3 +S3 +R90 +N1 +E2 +F4 +N4 +R90 +N3 +W5 +L180 +E1 +F2 +N4 +W5 +F80 +S4 +F7 +L180 +F96 +L90 +F16 +L90 +E4 +F78 +W2 +R90 +S3 +F29 +W4 +R90 +E4 +F39 +N1 +F48 +E4 +L180 +E1 +R180 +E2 +R90 +N3 +R180 +W2 +N5 +W5 +E3 +F25 +E1 +L180 +N5 +F44 +L90 +N4 +W4 +L90 +F72 +L90 +S1 +E5 +N5 +R90 +N1 +W3 +S5 +R90 +W1 +F14 +L90 +W2 +R90 +W3 +F76 +S5 +W5 +F93 +W4 +R90 +F57 +E3 +R90 +S3 +W1 +R90 +S3 +F8 +R90 +N2 +F46 +W4 +S1 +L90 +E4 +W5 +L90 +W2 +F69 +N5 +W5 +F80 +N3 +E4 +L90 +E4 +F25 +S3 +R180 +F77 +R90 +W2 +F19 +E4 +L180 +W2 +F37 +S2 +F68 +L90 +E2 +F66 +S1 +R90 +F66 +E2 +L180 +F97 +N3 +W4 +F43 +S4 +R180 +N1 +R270 +E3 +N2 +N3 +F65 +L90 +S2 +L90 +N3 +L90 +S3 +F23 +L270 +W3 +S5 +E2 +R90 +S1 +F85 +N3 +R90 +W4 +F58 +E1 +L90 +N3 +L90 +E2 +S1 +F14 +E2 +N5 +W1 +N3 +E1 +L90 +E3 +F43 +E3 +N3 +F21 +E4 +F53 +E2 +L180 +E4 +F20 +E2 +N2 +E5 +L90 +N4 +W3 +N4 +S2 +L90 +W3 +F96 +L90 +S3 +R90 +N1 +E3 +S5 +L270 +F41 +N5 +W5 +S1 +W5 +R90 +F79 +W3 +L90 +E3 +F22 +N1 +L90 +E2 +L90 +R90 +F20 +L90 +W3 +R90 +W2 +L180 +W4 +F57 +R180 +N3 +L90 +F36 +L90 +E2 +R90 +N2 +E3 +N1 +W4 +W4 +N3 +E5 +F54 +R180 +F98 +W1 +R90 +F21 +S1 +L90 +S2 +L90 +S2 +F90 +E4 +S2 +R90 +N5 +F25 +N4 +W3 +N2 +F27 +S3 +E3 +N3 +F15 +L180 +S4 +F62 +W2 +L180 +E2 +N2 +L90 +R90 +F97 +R90 +S1 +R90 +E2 +F16 +W2 +E1 +F89 +W1 +L180 +S3 +W2 +S3 +E1 +F92 +F30 +N1 +E2 +S1 +F76 +E1 +S5 +W5 +F28 +W4 +L90 +F44 +E4 +N5 +F25 +R90 +F59 +S4 +F58 +S2 +F19 +W5 +S4 +E5 +N3 +F37 +E1 +L90 +F40 +E5 +F56 +S2 +W5 +F73 +N5 +F2 +L90 +F18 +E2 +N5 +L90 +F56 +R90 +F18 +W1 +S5 +E1 +N1 +L90 +W2 +E4 +N4 +E1 +W4 +N4 +L90 +N3 +R90 +W5 +S5 +F2 +R180 +F96 +R90 +W3 +F26 +L90 +S4 +E2 +F43 +S2 +R90 +F61 +W5 +F93 +R90 +F95 +L90 +E4 +R90 +N4 +F47 +R90 +W5 +L90 +F42 +L90 +W5 +F87 +R90 +N1 +N2 +E4 +F64 +S5 +L270 +F86 +S4 +W3 +S1 +L90 +F72 +R270 +W1 +F17 +S1 +E2 +R90 +W1 +N1 +F42 +N5 +L90 +F87 +F66 +L90 +N2 +W2 +L90 +S5 +F7 +R90 +N4 +L270 +F2 +W1 +N4 +F94 +W5 +R180 +S4 +F15 +E4 +F76 +N1 +E2 +F68 +S3 +F50 +R270 +E5 +F77 +R90 +S3 +E2 +N3 +S4 +F39 +S1 +E5 +S3 +L90 +E4 +S2 +W3 +F54 +R90 +F44 +L90 +W3 +F59 +R90 +N3 +F37 +E1 +F75 +R90 +F31 +W3 +F70 +S5 +L90 +E1 +F67 +W4 +L90 +S1 +W5 +S1 +S4 +W2 +E2 +S3 +R90 +S2 +E5 +L90 +F43 +R90 +E1 +S5 +F42 +L90 +W1 +N2 +E1 +L180 +S4 +W1 +L90 +F81 +E1 +R180 +N5 +R180 +N5 +L180 +F65 +R90 +F64 +W4 +S4 +R90 +F70 +E1 +S1 +F50 +E2 +S4 +E4 +N2 +S1 +R90 +E4 +R90 +F70 +R90 +N4 +F71 +R180 +F80 +S3 +L90 +N5 +L180 +F11 +N1 +R90 +W2 +N1 +R90 +W4 +R90 +F67 +W3 +R90 +W5 +L90 +E4 +F90 +L90 +N4 +L180 +F48 +R90 +W2 +F94 +R90 +N4 +L90 +W2 +F2 +L90 +W1 +E5 +S2 +W5 +S5 +E2 +N3 +W5 +N1 +F98 +S3 +W3 +L90 +S3 +W4 +R90 +W1 +F64 +N5 +R90 +S5 +W5 +F84 +S1 +E3 +L90 +S3 +E5 +F6 +N4 +W1 +R90 +E4 +F14 +N1 +R90 +F31 +L90 +F24 +F4 +N4 +F54 +S3 +R270 +F98 +E1 +L180 +F2 +E4 +F70 +W1 +R180 +N5 +F23 diff --git a/src/bin/day_12.rs b/src/bin/day_12.rs new file mode 100644 index 0000000..489cdca --- /dev/null +++ b/src/bin/day_12.rs @@ -0,0 +1,233 @@ +use bevy::prelude::*; +use std::fs::File; +use std::io::{BufRead, BufReader}; +use std::ops::Deref; + +fn main() { + App::build() + .add_resource(WindowDescriptor { + title: "Advent of Code".to_string(), + width: 1920, + height: 1080, + ..Default::default() + }) + .add_resource(ClearColor(Color::rgb(0., 0., 0.))) + .add_startup_system(setup_camera.system()) + .add_startup_system(read_input_file.system()) + .add_system(move_normal_ship.system()) + .add_system(move_waypoint_ship.system()) + .add_plugins(DefaultPlugins) + .run(); +} + +fn setup_camera(mut commands: Commands) { + commands.spawn(Camera2dComponents::default()); +} + +#[derive(PartialEq, Eq, Clone, Copy)] +struct Position { + x: i64, + y: i64, +} +impl Position { + fn manhattan_distance(&self, other: &Position) -> i64 { + (self.x - other.x).abs() + (self.y - other.y).abs() + } +} +impl std::ops::Add<&Position> for &Position { + type Output = Position; + fn add(self, other: &Position) -> Self::Output { + Position { + x: self.x + other.x, + y: self.y + other.y, + } + } +} +impl std::ops::Mul for Position { + type Output = Position; + fn mul(self, other: i64) -> Self::Output { + Position { + x: self.x * other, + y: self.y * other, + } + } +} + +enum Facing { + North, + South, + East, + West, +} +impl Facing { + fn right(&mut self) { + use Facing::*; + *self = match self { + North => East, + East => South, + South => West, + West => North, + } + } + + fn reverse(&mut self) { + self.right(); + self.right(); + } + + fn left(&mut self) { + self.reverse(); + self.right(); + } +} + +struct Instructions(Vec); +#[derive(Clone)] +enum Instruction { + North(i64), + South(i64), + East(i64), + West(i64), + Left(i64), + Right(i64), + Forward(i64), +} + +struct InstructionPointer(usize); + +struct Waypoint(Position); + +fn read_input_file(mut commands: Commands) { + let f = File::open("./inputs/day_12.txt").unwrap(); + + let instructions: Vec = BufReader::new(f) + .lines() + .map(|line| { + let line = line.unwrap(); + let line = line.trim(); + + let val: i64 = line[1..].parse().unwrap(); + let instruction = match line.chars().next().unwrap() { + 'N' => Instruction::North(val), + 'S' => Instruction::South(val), + 'E' => Instruction::East(val), + 'W' => Instruction::West(val), + 'L' => Instruction::Left(val), + 'R' => Instruction::Right(val), + 'F' => Instruction::Forward(val), + other => panic!("Unknown instruction: {}", other), + }; + instruction + }) + .collect(); + + commands.spawn(( + Instructions(instructions.clone()), + InstructionPointer(0), + Facing::East, + Position { x: 0, y: 0 }, + )); + + commands.spawn(( + Waypoint(Position { x: 10, y: 1 }), + Instructions(instructions), + InstructionPointer(0), + Position { x: 0, y: 0 }, + )); +} + +fn move_normal_ship( + mut q: Query< + Without< + Waypoint, + ( + &Instructions, + &mut InstructionPointer, + &mut Facing, + &mut Position, + ), + >, + >, +) { + for (instructions, mut instruction_pointer, mut facing, mut position) in q.iter_mut() { + if let Some(instruction) = instructions.0.get(instruction_pointer.0) { + use Instruction::*; + match instruction { + North(val) => position.y += val, + South(val) => position.y -= val, + East(val) => position.x += val, + West(val) => position.x -= val, + Left(90) | Right(270) => facing.left(), + Left(180) | Right(180) => facing.reverse(), + Left(270) | Right(90) => facing.right(), + Left(val) | Right(val) => panic!("Unknown left/right val: {}", val), + Forward(val) => match facing.deref() { + Facing::North => position.y += val, + Facing::South => position.y -= val, + Facing::East => position.x += val, + Facing::West => position.x -= val, + }, + }; + + instruction_pointer.0 += 1; + } else { + println!( + "Normal Ship at destination: {} x {}, Manhattan distance: {}", + position.x, + position.y, + position.manhattan_distance(&Position { x: 0, y: 0 }) + ); + } + } +} + +fn move_waypoint_ship( + instructions: &Instructions, + mut waypoint: Mut, + mut instruction_pointer: Mut, + mut position: Mut, +) { + if let Some(instruction) = instructions.0.get(instruction_pointer.0) { + use Instruction::*; + match instruction { + North(val) => waypoint.0.y += val, + South(val) => waypoint.0.y -= val, + East(val) => waypoint.0.x += val, + West(val) => waypoint.0.x -= val, + Left(90) | Right(270) => { + waypoint.0 = Position { + x: -waypoint.0.y, + y: waypoint.0.x, + } + } + Left(180) | Right(180) => { + waypoint.0 = Position { + x: -waypoint.0.x, + y: -waypoint.0.y, + } + } + Left(270) | Right(90) => { + waypoint.0 = Position { + x: waypoint.0.y, + y: -waypoint.0.x, + } + } + Left(val) | Right(val) => panic!("Unknown left/right val: {}", val), + Forward(val) => *position = position.deref() + &(waypoint.0 * *val), + }; + + // println!( + // "Position: {} x {}. Waypoint: {} x {}", + // position.x, position.y, waypoint.0.x, waypoint.0.y + // ); + + instruction_pointer.0 += 1; + } else { + println!( + "Waypoint Ship at destination: {} x {}, Manhattan distance: {}", + position.x, + position.y, + position.manhattan_distance(&Position { x: 0, y: 0 }) + ); + } +} -- cgit v1.2.3