1use crate::util::hash::*;
11use crate::util::parse::*;
12use crate::util::point::*;
13
14type Pair = (u8, i32);
15
16pub fn parse(input: &str) -> Vec<Pair> {
17 let first = input.bytes().filter(u8::is_ascii_uppercase);
18 let second = input.iter_signed();
19 first.zip(second).collect()
20}
21
22pub fn part1(input: &[Pair]) -> i32 {
23 let mut position = ORIGIN;
24 let mut direction = UP;
25
26 for &(turn, amount) in input {
27 direction =
28 if turn == b'L' { direction.counter_clockwise() } else { direction.clockwise() };
29 position += direction * amount;
30 }
31
32 position.manhattan(ORIGIN)
33}
34
35pub fn part2(input: &[Pair]) -> i32 {
36 let mut position = ORIGIN;
37 let mut direction = UP;
38 let mut visited = FastSet::with_capacity(1000);
39
40 for &(turn, amount) in input {
41 direction =
42 if turn == b'L' { direction.counter_clockwise() } else { direction.clockwise() };
43
44 for _ in 0..amount {
45 position += direction;
46 if !visited.insert(position) {
47 return position.manhattan(ORIGIN);
48 }
49 }
50 }
51
52 unreachable!()
53}