-
Notifications
You must be signed in to change notification settings - Fork 9
/
day12.rs
62 lines (53 loc) · 1.72 KB
/
day12.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
//! # Rain Risk
//!
//! Our [`Point`] utility class comes in handy for this problem.
//!
//! [`Point`]: crate::util::point
use crate::util::parse::*;
use crate::util::point::*;
type Command = (u8, i32);
pub fn parse(input: &str) -> Vec<Command> {
input.lines().map(|line| (line.as_bytes()[0], (&line[1..]).signed())).collect()
}
pub fn part1(input: &[Command]) -> i32 {
let mut position = ORIGIN;
let mut direction = Point::new(1, 0);
for &(command, amount) in input {
match command {
b'N' => position.y -= amount,
b'S' => position.y += amount,
b'E' => position.x += amount,
b'W' => position.x -= amount,
b'L' => direction = rotate(direction, -amount),
b'R' => direction = rotate(direction, amount),
b'F' => position += direction * amount,
_ => unreachable!(),
}
}
position.manhattan(ORIGIN)
}
pub fn part2(input: &[Command]) -> i32 {
let mut position = ORIGIN;
let mut waypoint = Point::new(10, -1);
for &(command, amount) in input {
match command {
b'N' => waypoint.y -= amount,
b'S' => waypoint.y += amount,
b'E' => waypoint.x += amount,
b'W' => waypoint.x -= amount,
b'L' => waypoint = rotate(waypoint, -amount),
b'R' => waypoint = rotate(waypoint, amount),
b'F' => position += waypoint * amount,
_ => unreachable!(),
}
}
position.manhattan(ORIGIN)
}
fn rotate(point: Point, amount: i32) -> Point {
match amount {
90 | -270 => point.clockwise(),
180 | -180 => point * -1,
270 | -90 => point.counter_clockwise(),
_ => unreachable!(),
}
}