summaryrefslogtreecommitdiffstats
path: root/src/bin/2023/day10.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/bin/2023/day10.rs')
-rw-r--r--src/bin/2023/day10.rs131
1 files changed, 131 insertions, 0 deletions
diff --git a/src/bin/2023/day10.rs b/src/bin/2023/day10.rs
new file mode 100644
index 0000000..ef055e5
--- /dev/null
+++ b/src/bin/2023/day10.rs
@@ -0,0 +1,131 @@
+#![allow(dead_code)]
+#![allow(unused_variables)]
+
+use advent_of_code::prelude::*;
+
+#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Default)]
+pub enum Tile {
+ #[default]
+ Floor,
+ Start,
+ UpDown,
+ LeftRight,
+ UpRight,
+ UpLeft,
+ DownRight,
+ DownLeft,
+}
+
+impl Tile {
+ fn points_left(&self) -> bool {
+ matches!(
+ self,
+ Self::Start | Self::LeftRight | Self::UpLeft | Self::DownLeft
+ )
+ }
+
+ fn points_right(&self) -> bool {
+ matches!(
+ self,
+ Self::Start | Self::LeftRight | Self::UpRight | Self::DownRight
+ )
+ }
+
+ fn points_up(&self) -> bool {
+ matches!(
+ self,
+ Self::Start | Self::UpDown | Self::UpLeft | Self::UpRight
+ )
+ }
+
+ fn points_down(&self) -> bool {
+ matches!(
+ self,
+ Self::Start | Self::UpDown | Self::DownLeft | Self::DownRight
+ )
+ }
+
+ fn connects(
+ &self,
+ other: &Self,
+ direction: (Ordering, Ordering),
+ ) -> bool {
+ match direction {
+ (Ordering::Less, Ordering::Equal) => {
+ self.points_up() && other.points_down()
+ }
+ (Ordering::Greater, Ordering::Equal) => {
+ self.points_down() && other.points_up()
+ }
+ (Ordering::Equal, Ordering::Less) => {
+ self.points_left() && other.points_right()
+ }
+ (Ordering::Equal, Ordering::Greater) => {
+ self.points_right() && other.points_left()
+ }
+ _ => false,
+ }
+ }
+}
+
+pub fn parse(fh: File) -> Result<Grid<Tile>> {
+ Ok(parse::grid(parse::raw_lines(fh), |c, _, _| match c {
+ b'.' => Tile::Floor,
+ b'S' => Tile::Start,
+ b'|' => Tile::UpDown,
+ b'-' => Tile::LeftRight,
+ b'L' => Tile::UpRight,
+ b'J' => Tile::UpLeft,
+ b'F' => Tile::DownRight,
+ b'7' => Tile::DownLeft,
+ _ => panic!("bad tile {c}"),
+ }))
+}
+
+pub fn part1(map: Grid<Tile>) -> Result<i64> {
+ let mut cur = map
+ .indexed_cells()
+ .find_map(|(pos, tile)| {
+ if *tile == Tile::Start {
+ Some(pos)
+ } else {
+ None
+ }
+ })
+ .unwrap();
+ let mut pipe_loop = vec![];
+ while pipe_loop.len() < 2
+ || pipe_loop[0] != pipe_loop[pipe_loop.len() - 1]
+ {
+ pipe_loop.push(cur);
+ for pos in map.adjacent(cur.0, cur.1, false) {
+ if pipe_loop.len() > 1 && pos == pipe_loop[pipe_loop.len() - 2] {
+ continue;
+ }
+ if map[cur.0][cur.1].connects(
+ &map[pos.0][pos.1],
+ (pos.0.cmp(&cur.0), pos.1.cmp(&cur.1)),
+ ) {
+ cur = pos;
+ break;
+ }
+ }
+ }
+ Ok(i64::try_from(pipe_loop.len() - 1).unwrap() / 2)
+}
+
+pub fn part2(_: Grid<Tile>) -> Result<i64> {
+ todo!()
+}
+
+#[test]
+fn test() {
+ assert_eq!(
+ part1(parse(parse::data(2023, 10).unwrap()).unwrap()).unwrap(),
+ 7086
+ );
+ assert_eq!(
+ part2(parse(parse::data(2023, 10).unwrap()).unwrap()).unwrap(),
+ 0
+ );
+}