1use crate::util::grid::*;
8use crate::util::point::*;
9
10pub fn parse(input: &str) -> Vec<&str> {
11 input.lines().collect()
12}
13
14pub fn part1(input: &[&str]) -> String {
16 let keypad = "123\n456\n789";
17 code(input, keypad, ORIGIN, |p| p.x.abs() <= 1 && p.y.abs() <= 1)
18}
19
20pub fn part2(input: &[&str]) -> String {
22 let keypad = "##1##\n#234#\n56789\n#ABC#\n##D##";
23 code(input, keypad, Point::new(-2, 0), |p| p.manhattan(ORIGIN) <= 2)
24}
25
26fn code(input: &[&str], keypad: &str, start: Point, inside: impl Fn(Point) -> bool) -> String {
29 let digits = Grid::parse(keypad);
30 let center = Point::new(digits.width / 2, digits.height / 2);
32
33 let mut position = start;
34 let mut result = String::new();
35
36 for line in input {
37 for b in line.bytes() {
38 let next = position + Point::from(b);
39 if inside(next) {
40 position = next;
41 }
42 }
43 result.push(digits[position + center] as char);
44 }
45
46 result
47}