diff options
author | Toby Vincent <tobyv@tobyvin.dev> | 2023-12-11 18:20:48 -0600 |
---|---|---|
committer | Toby Vincent <tobyv@tobyvin.dev> | 2023-12-11 18:20:48 -0600 |
commit | 1cf9aad70f43d5e0d2001835ba5cd158059b6b36 (patch) | |
tree | c08e611c3e880fc061cfc5c3227c42a5b2834e55 /src | |
parent | 2340a8df2ab69d549c14cf508fde297ebd266437 (diff) |
feat: impl day 10
Diffstat (limited to 'src')
-rw-r--r-- | src/day_10.rs | 73 |
1 files changed, 28 insertions, 45 deletions
diff --git a/src/day_10.rs b/src/day_10.rs index 00d26d7..c97bf40 100644 --- a/src/day_10.rs +++ b/src/day_10.rs @@ -21,58 +21,35 @@ impl Solution for Day10 { type Answer2 = usize; fn part_1(input: &str) -> anyhow::Result<Self::Answer1> { - let graph: Graph = input.parse()?; - - let mut path = Vec::new(); - let mut pos = graph.start; - let mut c = &'S'; - let mut next_edge = Edge::ALL.into_iter().find(|e| { - e.traverse(pos) - .and_then(|p| graph.inner.get(&p)) - .map(|c| e.valid_edge(c)) - .unwrap_or_default() - }); - - while let Some(edge) = next_edge { - path.push((edge, c)); - pos = edge.traverse(pos).context("Out-of-bounds move")?; - c = graph.inner.get(&pos).context("Failed to get postion")?; - next_edge = edge.exit(c); - if c == &'S' { - break; - } - } + let mut graph: Graph = input.parse()?; - Ok(path.len() / 2) + Ok(graph.solve()? / 2) } fn part_2(input: &str) -> anyhow::Result<Self::Answer2> { let mut graph: Graph = input.parse()?; graph.solve()?; - println!("{graph}"); Ok(graph .inner .iter() .filter(|(pos, _)| graph.is_included(pos)) .count()) - - // 543 > } } type Position = (usize, usize); -type Path = BTreeMap<usize, BTreeMap<usize, char>>; #[derive(Default)] struct Graph { inner: HashMap<Position, char>, start: Position, - path: Path, + path: BTreeMap<usize, BTreeMap<usize, char>>, } impl Graph { - fn solve(&mut self) -> anyhow::Result<()> { + fn solve(&mut self) -> anyhow::Result<usize> { + let mut steps = 0; let mut pos = self.start; let mut next_edge = Edge::ALL.into_iter().find(|e| { e.traverse(pos) @@ -84,28 +61,28 @@ impl Graph { let start_edge = next_edge.to_owned().unwrap(); while let Some(edge) = next_edge { + steps += 1; self.path .entry(pos.0) - .and_modify(|v: &mut BTreeMap<usize, char>| { + .and_modify(|v| { v.insert(pos.1, *c); }) .or_insert(BTreeMap::from([(pos.1, *c)])); pos = edge.traverse(pos).context("Out-of-bounds move")?; c = self.inner.get(&pos).context("Failed to get postion")?; if c == &'S' { - self.path - .entry(pos.0) - .and_modify(|v: &mut BTreeMap<usize, char>| { - assert_eq!( - Some('S'), - v.insert(pos.1, edge.as_char(&start_edge).unwrap()) - ); - }); + self.path.entry(pos.0).and_modify(|v| { + assert_eq!( + Some('S'), + v.insert(pos.1, edge.as_char(&start_edge).unwrap()) + ); + }); break; } - next_edge = edge.exit(c); + next_edge = edge.next(c); } - Ok(()) + + Ok(steps) } fn is_included(&self, pos: &Position) -> bool { @@ -138,7 +115,7 @@ impl Graph { } } - left % 2 != 0 || right % 2 != 0 + left % 2 != 0 && right % 2 != 0 } } @@ -175,6 +152,7 @@ impl std::fmt::Debug for Graph { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let (height, width) = self.inner.keys().max().unwrap(); for row in 0..height + 1 { + write!(f, "{row:03}: ")?; let Some(btree) = self.path.get(&row) else { writeln!(f)?; continue; @@ -197,6 +175,7 @@ impl std::fmt::Display for Graph { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let (height, width) = self.inner.keys().max().unwrap(); for row in 0..height + 1 { + write!(f, "{row:03}: ")?; let Some(btree) = self.path.get(&row) else { writeln!(f)?; continue; @@ -250,7 +229,7 @@ impl Edge { } } - fn exit(&self, &c: &char) -> Option<Self> { + fn next(&self, &c: &char) -> Option<Self> { Some(match (self, c) { (Edge::Up, '|') => Edge::Up, (Edge::Up, '7') => Edge::Left, @@ -271,11 +250,15 @@ impl Edge { fn as_char(&self, other: &Edge) -> Option<char> { Some(match (self, other) { (Edge::Up, Edge::Down) | (Edge::Down, Edge::Up) => '|', - (Edge::Up, Edge::Left) | (Edge::Left, Edge::Up) => 'J', - (Edge::Up, Edge::Right) | (Edge::Right, Edge::Up) => 'L', - (Edge::Down, Edge::Left) | (Edge::Left, Edge::Down) => '7', - (Edge::Down, Edge::Right) | (Edge::Right, Edge::Down) => 'F', (Edge::Left, Edge::Right) | (Edge::Right, Edge::Left) => '-', + (Edge::Up, Edge::Left) => '7', + (Edge::Left, Edge::Down) => 'F', + (Edge::Left, Edge::Up) => 'L', + (Edge::Down, Edge::Left) => 'J', + (Edge::Up, Edge::Right) => 'F', + (Edge::Right, Edge::Down) => '7', + (Edge::Right, Edge::Up) => 'J', + (Edge::Down, Edge::Right) => 'L', _ => None?, }) } |