AoC2020/src/bin/day12_part2.rs

103 lines
2.5 KiB
Rust

use std::error::Error;
use std::fs::File;
use std::io::{self, BufRead};
#[derive(PartialEq, Copy, Clone)]
enum Movement {
North(u32),
South(u32),
East(u32),
West(u32),
Forward(u32),
TurnLeft(u32),
TurnRight(u32),
}
fn line_to_movement(line: &str) -> Movement {
let cmd = line.get(0..1).unwrap();
let arg: u32 = line.get(1..).unwrap().parse().unwrap();
match cmd {
"N" => Movement::North(arg),
"S" => Movement::South(arg),
"W" => Movement::West(arg),
"E" => Movement::East(arg),
"F" => Movement::Forward(arg),
"R" => Movement::TurnRight(arg),
"L" => Movement::TurnLeft(arg),
_ => panic!("Unkown command: {}", line),
}
}
struct Ship {
x: i32,
y: i32,
waypoint_x: i32,
waypoint_y: i32,
}
impl Ship {
fn new() -> Ship {
Ship {
x: 0,
y: 0,
waypoint_x: 10,
waypoint_y: -1,
}
}
fn get_manhattan_distance(&self) -> u32 {
self.x.abs() as u32 + self.y.abs() as u32
}
fn do_turn_left(&mut self, arg: u32) {
for _ in 0..(arg / 90) {
let wp_x = self.waypoint_x;
let wp_y = self.waypoint_y;
self.waypoint_x = wp_y;
self.waypoint_y = -wp_x;
}
}
fn do_turn_right(&mut self, arg: u32) {
for _ in 0..(arg / 90) {
let wp_x = self.waypoint_x;
let wp_y = self.waypoint_y;
self.waypoint_x = -wp_y;
self.waypoint_y = wp_x;
}
}
fn do_move(&mut self, m: Movement) {
match m {
Movement::North(d) => self.waypoint_y -= d as i32,
Movement::South(d) => self.waypoint_y += d as i32,
Movement::West(d) => self.waypoint_x -= d as i32,
Movement::East(d) => self.waypoint_x += d as i32,
Movement::Forward(d) => {
self.x += self.waypoint_x * d as i32;
self.y += self.waypoint_y * d as i32;
}
Movement::TurnLeft(arg) => self.do_turn_left(arg),
Movement::TurnRight(arg) => self.do_turn_right(arg),
};
}
}
fn main() -> Result<(), Box<dyn Error>> {
let file = File::open("inputs/day12.txt")?;
let lines = io::BufReader::new(file).lines().map(|l| l.unwrap());
let moves = lines.map(|l| line_to_movement(&l));
let ship = moves.fold(Ship::new(), |mut s, m| {
s.do_move(m);
s
});
println!("Distance: {}", ship.get_manhattan_distance());
Ok(())
}