AoC2020/src/bin/day12.rs

113 lines
2.9 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),
}
}
#[derive(PartialEq, Copy, Clone)]
enum Direction {
North,
South,
East,
West,
}
struct Ship {
x: i32,
y: i32,
direction: Direction,
}
impl Ship {
fn new() -> Ship {
Ship {
x: 0,
y: 0,
direction: Direction::East,
}
}
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) {
self.direction = match self.direction {
Direction::North => Direction::West,
Direction::South => Direction::East,
Direction::West => Direction::South,
Direction::East => Direction::North,
}
}
}
fn do_turn_right(&mut self, arg: u32) {
for _ in 0..(arg / 90) {
self.direction = match self.direction {
Direction::North => Direction::East,
Direction::South => Direction::West,
Direction::West => Direction::North,
Direction::East => Direction::South,
};
}
}
fn do_move(&mut self, m: Movement) {
match m {
Movement::North(d) => self.y -= d as i32,
Movement::South(d) => self.y += d as i32,
Movement::West(d) => self.x -= d as i32,
Movement::East(d) => self.x += d as i32,
Movement::Forward(d) => match self.direction {
Direction::North => self.y -= d as i32,
Direction::South => self.y += d as i32,
Direction::West => self.x -= d as i32,
Direction::East => self.x += 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(())
}