summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorToby Vincent <tobyv@tobyvin.dev>2023-12-11 18:20:48 -0600
committerToby Vincent <tobyv@tobyvin.dev>2023-12-11 18:20:48 -0600
commit1cf9aad70f43d5e0d2001835ba5cd158059b6b36 (patch)
treec08e611c3e880fc061cfc5c3227c42a5b2834e55
parent2340a8df2ab69d549c14cf508fde297ebd266437 (diff)
feat: impl day 10
-rw-r--r--src/day_10.rs73
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?,
})
}