use std::collections::HashSet; use aoc_runner_derive::{aoc as aoc_run, aoc_generator}; type Position = (i32, i32); #[aoc_generator(day9)] fn parse_input(input: &str) -> Vec { let mut out = Vec::new(); let (mut x, mut y) = (0, 0); out.push((x, y)); for line in input.lines() { let mut split = line.split_ascii_whitespace(); let dir = split.next().unwrap(); let num: i32 = split.next().unwrap().parse().unwrap(); for _ in 0..num { match dir { "U" => y += 1, "D" => y -= 1, "L" => x -= 1, "R" => x += 1, _ => unreachable!(), } out.push((x, y)); } } out } #[aoc_run(day9, part1)] fn part1(input: &[Position]) -> usize { let mut tail = (0, 0); let mut set = HashSet::new(); set.insert(tail); for mv in input { tail = new_tail(mv, &tail); set.insert(tail); } set.len() } #[aoc_run(day9, part2)] fn part2(input: &[Position]) -> u32 { 0 } fn new_tail(head: &Position, tail: &Position) -> Position { let dy = head.1 - tail.1; let dx = head.0 - tail.0; match (dx, dy) { (m, n) if m.abs() < 2 && n.abs() < 2 => *tail, (m, _) if m.abs() == 2 => (tail.0 + m / 2, tail.1 + dy), (_, m) if m.abs() == 2 => (tail.0 + dx, tail.1 + m / 2), _ => unreachable!(), } }