[TASK] Finished day 12

This commit is contained in:
2020-12-12 11:16:50 +01:00
parent 4a8c5580ff
commit 9684b28a65
7 changed files with 986 additions and 10 deletions

174
src/day12.rs Normal file
View File

@@ -0,0 +1,174 @@
use super::util;
use crate::day12::Heading::{North, East, South, West};
use std::mem::swap;
pub fn solve()
{
let lines = util::read_file("input/day12.txt");
let instructions = lines.iter().map(|s| Instruction::parse(s)).collect::<Vec<_>>();
let ship_state = execute(&instructions);
let part1 = ship_state.manhattan_distance();
println!("Day 12 Part 1: {}", part1);
let ship_state2 = execute_with_waypoint(&instructions);
let part2 = ship_state2.manhattan_distance();
println!("Day 12 Part 2: {}", part2);
}
fn execute(instructions: &Vec<Instruction>) -> ShipState {
let mut res = ShipState { position_n: 0, position_e: 0, heading: East };
for instruction in instructions {
res.apply(&instruction);
}
return res;
}
fn execute_with_waypoint(instructions: &Vec<Instruction>) -> ShipState {
let mut ship = ShipState { position_n: 0, position_e: 0, heading: East };
let mut waypoint = WaypointState { position_n: 1, position_e: 10 };
for instruction in instructions {
// println!("Instruction: {}{}", instruction.action, instruction.amount);
if instruction.action == 'F' {
ship.position_n += waypoint.position_n * instruction.amount as i32;
ship.position_e += waypoint.position_e * instruction.amount as i32;
} else {
waypoint.apply(instruction);
}
// println!("Ship: {:?}, Waypoint: {:?}", ship, waypoint);
}
return ship;
}
#[derive(Debug)]
struct ShipState {
position_n: i32,
position_e: i32,
heading: Heading,
}
impl ShipState {
fn manhattan_distance(&self) -> i32 {
return self.position_n.abs() + self.position_e.abs();
}
fn apply(&mut self, instruction: &Instruction) {
match instruction.action {
'N'=> self.position_n += instruction.amount as i32,
'S' => self.position_n -= instruction.amount as i32,
'E' => self.position_e += instruction.amount as i32,
'W' => self.position_e -= instruction.amount as i32,
'L' => self.turn_left(instruction.amount),
'R' => self.turn_left(360 - (instruction.amount % 360)),
'F' => self.move_forward(instruction.amount),
_ => panic!("Unknown instruction: {}", instruction.action)
}
}
fn move_forward(&mut self, amount: u32) {
match self.heading {
North => self.position_n += amount as i32,
East => self.position_e += amount as i32,
South => self.position_n -= amount as i32,
West => self.position_e -= amount as i32,
}
}
fn turn_left(&mut self, amount: u32) {
assert_eq!(amount % 90, 0, "Only rotations of (multiples of) 90 degrees are supported");
let count = amount / 90;
for _ in 0..count {
self.heading = self.heading.turn_left();
}
}
}
#[derive(Debug)]
struct WaypointState {
position_n: i32,
position_e: i32,
}
impl WaypointState {
fn apply(&mut self, instruction: &Instruction) {
match instruction.action {
'N'=> self.position_n += instruction.amount as i32,
'S' => self.position_n -= instruction.amount as i32,
'E' => self.position_e += instruction.amount as i32,
'W' => self.position_e -= instruction.amount as i32,
'L' => self.rotate_left_around_origin(instruction.amount),
'R' => self.rotate_left_around_origin(360 - instruction.amount),
_ => panic!("Unknown instruction: {}", instruction.action)
}
}
fn rotate_left_around_origin(&mut self , amount: u32) {
assert_eq!(amount % 90, 0, "Only rotations of (multiples of) 90 degrees are supported");
if amount % 360 == 0 { return; }
match amount % 360 {
90 => {
swap(&mut self.position_n, &mut self.position_e);
self.position_e *= -1;
}
180 => {
self.position_n *= -1;
self.position_e *= -1;
}
270 => {
swap(&mut self.position_n, &mut self.position_e);
self.position_n *= -1;
}
_ => panic!("Unsupported amount of degrees")
}
}
}
#[derive(Debug)]
struct Instruction {
action: char,
amount: u32,
}
#[derive(Debug)]
enum Heading {
North, East, South, West
}
impl Heading {
fn turn_left(&self) -> Heading {
return match self {
North => West,
West => South,
South => East,
East => North
};
}
}
impl Instruction {
fn parse(line: &String) -> Instruction {
return Instruction {
action: line.chars().next().unwrap(),
amount: line[1..].parse::<u32>().unwrap(),
}
}
}

View File

@@ -2,4 +2,12 @@ use super::util;
pub fn solve() {
let lines = util::read_file("input/dayX.txt");
let part1 = 0;
println!("Day X Part 1: {}", part1);
let part2 = 0;
println!("Day X Part 2: {}", part2);
}

View File

@@ -13,8 +13,9 @@ mod day8;
mod day9;
mod day10;
mod day11;
mod day12;
const MAX_DAY: u8 = 11;
const MAX_DAY: u8 = 12;
const BENCHMARK_AMOUNT: u32 = 100;
fn solve(day: u8) {
@@ -30,6 +31,7 @@ fn solve(day: u8) {
9 => day9::solve(),
10 => day10::solve(),
11 => day11::solve(),
12 => day12::solve(),
_ => println!("This day is not yet implemented")
}
}