From 3b18b90bda08b74ba32a1a977bdd9fefccbebbe7 Mon Sep 17 00:00:00 2001 From: Gabe Venberg Date: Wed, 22 Nov 2023 17:00:27 -0600 Subject: [PATCH] day 09. --- Cargo.lock | 2 ++ days/day09/Cargo.toml | 2 ++ days/day09/src/main.rs | 4 ++-- days/day09/src/parse.rs | 24 +++++++++++++++++------- days/day09/src/part2.rs | 13 +++++++++---- days/day09/src/rope.rs | 6 +++--- 6 files changed, 35 insertions(+), 16 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 451aeb5..316f05f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -65,6 +65,8 @@ name = "day09" version = "0.1.0" dependencies = [ "aoc_libs", + "once_cell", + "regex", ] [[package]] diff --git a/days/day09/Cargo.toml b/days/day09/Cargo.toml index ec42136..eadb393 100644 --- a/days/day09/Cargo.toml +++ b/days/day09/Cargo.toml @@ -7,3 +7,5 @@ edition.workspace = true [dependencies] aoc_libs.workspace = true +regex.workspace = true +once_cell.workspace = true diff --git a/days/day09/src/main.rs b/days/day09/src/main.rs index bfe732a..f92bdf7 100644 --- a/days/day09/src/main.rs +++ b/days/day09/src/main.rs @@ -12,6 +12,6 @@ fn main() { println!("Part One"); println!("Result: {}", part1::part1(&structured_input)); - // println!("Part Two"); - // println!("Result: {}", part2::part2(&structured_input)); + println!("Part Two"); + println!("Result: {}", part2::part2(&structured_input)); } diff --git a/days/day09/src/parse.rs b/days/day09/src/parse.rs index 0e4ac55..9c4588d 100644 --- a/days/day09/src/parse.rs +++ b/days/day09/src/parse.rs @@ -1,3 +1,6 @@ +use once_cell::sync::Lazy; +use regex::Regex; + #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub enum Direction { Up, @@ -6,18 +9,25 @@ pub enum Direction { Left, } +static PARSE_REGEX: Lazy = Lazy::new(|| Regex::new(r"^([URDL]) (\d+)$").unwrap()); + pub fn parse(input: &str) -> Vec { let mut ret = Vec::new(); for line in input.lines() { - let mut chars = line.chars(); - let dir = match chars.next().unwrap() { - 'U' => Direction::Up, - 'R' => Direction::Right, - 'D' => Direction::Down, - 'L' => Direction::Left, + let captures = PARSE_REGEX + .captures(line) + .unwrap_or_else(|| panic!("invalid line {}", line)); + let dir = match &captures[1] { + "U" => Direction::Up, + "R" => Direction::Right, + "D" => Direction::Down, + "L" => Direction::Left, _ => panic!("invalid direction char"), }; - for _ in 0..chars.nth(1).unwrap().to_digit(10).unwrap() { + for _ in 0..captures[2] + .parse() + .unwrap_or_else(|_| panic!("invalid line {}", line)) + { ret.push(dir) } } diff --git a/days/day09/src/part2.rs b/days/day09/src/part2.rs index 18ae9ef..98b19fd 100644 --- a/days/day09/src/part2.rs +++ b/days/day09/src/part2.rs @@ -2,25 +2,30 @@ use std::collections::HashSet; use aoc_libs::points::Point; -use crate::{rope::Rope, parse::Direction}; +use crate::{parse::Direction, rope::Rope}; pub fn part2(input: &Vec) -> usize { let mut visited: HashSet = HashSet::new(); let mut rope: Rope<10> = Rope::new(); + visited.insert(*rope.get_tail_pos()); for direction in input { - visited.insert(*rope.get_tail_pos()); rope.update_rope(direction); - println!("{}", rope) + visited.insert(*rope.get_tail_pos()); } visited.len() } #[cfg(test)] mod tests { + use crate::parse::parse; + use super::*; #[test] fn test_part2() { - assert_eq!(0, 0); + let input = parse(concat!( + "R 5\n", "U 8\n", "L 8\n", "D 3\n", "R 17\n", "D 10\n", "L 25\n", "U 20\n", + )); + assert_eq!(part2(&input), 36); } } diff --git a/days/day09/src/rope.rs b/days/day09/src/rope.rs index 94bd527..8f21c71 100644 --- a/days/day09/src/rope.rs +++ b/days/day09/src/rope.rs @@ -23,14 +23,12 @@ impl Rope { Direction::Down => Point { x: 0, y: -1 }, Direction::Left => Point { x: -1, y: 0 }, }; - println!("direction is {:?}", direction); for segment in 1..self.segments.len() { self.segments[segment] += Rope::::update_single_segment_pair( &self.segments[segment - 1], &self.segments[segment], ) } - println!("{}", self); } pub fn get_tail_pos(&self) -> &Point { @@ -77,7 +75,7 @@ impl Display for Rope<{ L }> { } for segment in self.segments.iter().skip(1) { - let delta = *segment-self.segments[0]; + let delta = *segment - self.segments[0]; let upoint = delta.to_upoint(&zero_point).unwrap(); grid[upoint.y][upoint.x] = 'T' } @@ -138,9 +136,11 @@ mod tests { let mut visited: HashSet = HashSet::new(); let mut rope: Rope<2> = Rope::new(); visited.insert(*rope.get_tail_pos()); + println!("{}", rope); for direction in input { rope.update_rope(&direction); visited.insert(*rope.get_tail_pos()); + println!("{}", rope); } // let mut graph = [ // ['.', '.', '.', '.', '.', '.'],