This commit is contained in:
Andrew Glaze 2023-12-28 15:43:02 -05:00
parent 0407edf928
commit c88b97182d
2 changed files with 138 additions and 0 deletions

137
src/day12.rs Normal file
View 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);
}
}

View File

@ -1,3 +1,4 @@
mod day12;
mod day10;
mod day9;
mod day8;