day12
This commit is contained in:
parent
0407edf928
commit
c88b97182d
137
src/day12.rs
Normal file
137
src/day12.rs
Normal file
@ -0,0 +1,137 @@
|
||||
use aoc_runner_derive::{aoc, aoc_generator};
|
||||
|
||||
use Instruction::*;
|
||||
use itertools::Itertools;
|
||||
|
||||
#[derive(Debug)]
|
||||
enum Instruction {
|
||||
MoveNorth(i32),
|
||||
MoveSouth(i32),
|
||||
MoveEast(i32),
|
||||
MoveWest(i32),
|
||||
TurnLeft(i32),
|
||||
TurnRight(i32),
|
||||
MoveForward(i32)
|
||||
}
|
||||
|
||||
impl From<(char, i32)> for Instruction {
|
||||
fn from(value: (char, i32)) -> Self {
|
||||
match value {
|
||||
(i, v) if i == 'N' => MoveNorth(v),
|
||||
(i, v) if i == 'S' => MoveSouth(v),
|
||||
(i, v) if i == 'E' => MoveEast(v),
|
||||
(i, v) if i == 'W' => MoveWest(v),
|
||||
(i, v) if i == 'L' => TurnLeft(v),
|
||||
(i, v) if i == 'R' => TurnRight(v),
|
||||
(i, v) if i == 'F' => MoveForward(v),
|
||||
_ => unreachable!()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[aoc_generator(day12)]
|
||||
fn parse(input: &str) -> Vec<Instruction> {
|
||||
input
|
||||
.lines()
|
||||
.map(|line| {
|
||||
(line.chars().next().unwrap(), line[1..].parse::<i32>().unwrap()).into()
|
||||
})
|
||||
.collect_vec()
|
||||
}
|
||||
|
||||
const DIR_POS_MODIFIER: [(i32, i32); 4] = [(1, 0), (0, -1), (-1, 0), (0, 1)];
|
||||
|
||||
#[aoc(day12, part1)]
|
||||
fn part1(input: &Vec<Instruction>) -> i32 {
|
||||
let mut x = 0;
|
||||
let mut y = 0;
|
||||
let mut direction = 0; // 0 is east, thus 90 is south, 180 is west, and 270 is north
|
||||
|
||||
for instr in input {
|
||||
match instr {
|
||||
MoveNorth(val) => y += val,
|
||||
MoveSouth(val) => y -= val,
|
||||
MoveEast(val) => x += val,
|
||||
MoveWest(val) => x -= val,
|
||||
TurnLeft(val) => {
|
||||
direction -= val;
|
||||
if direction < 0 {
|
||||
direction += 360;
|
||||
}
|
||||
},
|
||||
TurnRight(val) => {
|
||||
direction += val;
|
||||
if direction >= 360 {
|
||||
direction -= 360
|
||||
}
|
||||
},
|
||||
MoveForward(val) => {
|
||||
let (xmod, ymod) = DIR_POS_MODIFIER[(direction / 90) as usize];
|
||||
x += xmod * val;
|
||||
y += ymod * val;
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
x.abs() + y.abs()
|
||||
}
|
||||
|
||||
#[aoc(day12, part2)]
|
||||
fn part2(input: &Vec<Instruction>) -> i32 {
|
||||
let mut way_x = 10;
|
||||
let mut way_y = 1;
|
||||
|
||||
let mut ship_x: i32 = 0;
|
||||
let mut ship_y: i32 = 0;
|
||||
|
||||
for instr in input {
|
||||
match instr {
|
||||
MoveNorth(val) => way_y += val,
|
||||
MoveSouth(val) => way_y -= val,
|
||||
MoveEast(val) => way_x += val,
|
||||
MoveWest(val) => way_x -= val,
|
||||
TurnLeft(val) => {
|
||||
for _ in 0..(val / 90) {
|
||||
let tmp = way_y;
|
||||
way_y = way_x;
|
||||
way_x = -tmp;
|
||||
}
|
||||
},
|
||||
TurnRight(val) => {
|
||||
for _ in 0..(val / 90) {
|
||||
let tmp = way_y;
|
||||
way_y = -way_x;
|
||||
way_x = tmp;
|
||||
}
|
||||
},
|
||||
MoveForward(val) => {
|
||||
ship_x += way_x * val;
|
||||
ship_y += way_y * val;
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
ship_x.abs() + ship_y.abs()
|
||||
}
|
||||
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
const EX: &str = r"F10
|
||||
N3
|
||||
F7
|
||||
R90
|
||||
F11";
|
||||
|
||||
#[test]
|
||||
fn part1_example() {
|
||||
assert_eq!(part1(&parse(EX)), 25);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn part2_example() {
|
||||
assert_eq!(part2(&parse(EX)), 286);
|
||||
}
|
||||
}
|
@ -1,3 +1,4 @@
|
||||
mod day12;
|
||||
mod day10;
|
||||
mod day9;
|
||||
mod day8;
|
||||
|
Loading…
Reference in New Issue
Block a user