Skip to content

Commit

Permalink
day10: Initial solution
Browse files Browse the repository at this point in the history
  • Loading branch information
pedantic79 committed Jan 3, 2024
1 parent b717b52 commit 3c7d4f8
Show file tree
Hide file tree
Showing 4 changed files with 179 additions and 1 deletion.
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@
- [solution](src/day08.rs)
- [Day 9: Mirage Maintenance](https://adventofcode.com/2023/day/9)
- [solution](src/day09.rs)
- [Day 10: Pipe Maze](https://adventofcode.com/2023/day/10)
- [solution](src/day10.rs)
<!-- Insert before -->

See:
Expand Down
2 changes: 1 addition & 1 deletion input
Submodule input updated from 50c959 to e4fc4d
175 changes: 175 additions & 0 deletions src/day10.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,175 @@
use ahash::{HashSet, HashSetExt};
use aoc_runner_derive::{aoc, aoc_generator};

#[derive(Debug)]
enum Dir {
Down,
Left,
Up,
Right,
}

impl Dir {
fn next_pos(&self, r: &mut usize, c: &mut usize) {
match self {
Dir::Down => *r += 1,
Dir::Left => *c -= 1,
Dir::Up => *r -= 1,
Dir::Right => *c += 1,
}
}
}

fn next_direction(pipe: u8, dir: &Dir) -> Option<Dir> {
Some(match (pipe, dir) {
(b'|', Dir::Down) => Dir::Down,
(b'|', Dir::Up) => Dir::Up,
(b'-', Dir::Left) => Dir::Left,
(b'-', Dir::Right) => Dir::Right,
(b'L', Dir::Down) => Dir::Right,
(b'L', Dir::Left) => Dir::Up,
(b'J', Dir::Down) => Dir::Left,
(b'J', Dir::Right) => Dir::Up,
(b'7', Dir::Right) => Dir::Down,
(b'7', Dir::Up) => Dir::Left,
(b'F', Dir::Up) => Dir::Right,
(b'F', Dir::Left) => Dir::Down,
_ => return None,
})
}

#[aoc_generator(day10)]
pub fn generator(input: &str) -> (Vec<Vec<u8>>, (usize, usize)) {
let mut start = (0, 0);

let grid = input
.lines()
.enumerate()
.map(|(row, line)| {
line.bytes()
.enumerate()
.map(|(col, cell)| {
if cell == b'S' {
start = (row, col)
}
cell
})
.collect()
})
.collect();
(grid, start)
}

#[aoc(day10, part1)]
pub fn part1((grid, start): &(Vec<Vec<u8>>, (usize, usize))) -> usize {
let (mut r, mut c) = *start;
let mut dir = Dir::Down; // assume we can go down first
let mut count = 0;

loop {
count += 1;

dir.next_pos(&mut r, &mut c);
let pipe = grid[r][c];
if pipe == b'S' {
break;
}
dir = next_direction(pipe, &dir)
.unwrap_or_else(|| panic!("Unknown pipe combination {} {:?}", char::from(pipe), dir,));
}

count / 2
}

#[aoc(day10, part2)]
pub fn part2((grid, start): &(Vec<Vec<u8>>, (usize, usize))) -> usize {
let (mut r, mut c) = *start;
let mut dir = Dir::Down; // assume we can go down first
let mut pipe_set = HashSet::new();
pipe_set.insert((r, c));

loop {
dir.next_pos(&mut r, &mut c);
let pipe = grid[r][c];
if pipe == b'S' {
break;
}
pipe_set.insert((r, c));

dir = next_direction(pipe, &dir)
.unwrap_or_else(|| panic!("Unknown pipe combination {} {:?}", char::from(pipe), dir,));
}

let mut count = 0;
for (row, line) in grid.iter().enumerate() {
// we can as assume we're outside by default
let mut inside = false;
for (col, cell) in line.iter().enumerate() {
if pipe_set.contains(&(row, col)) {
// Check what parity we are in.
// If we see a vertical, then we go outside to inside and vice-versa
if b"|JLS".contains(cell) {
inside = !inside;
}
} else {
count += usize::from(inside);
}
}
}
count
}

#[cfg(test)]
mod tests {
use super::*;

const SAMPLE: &str = r"7-F7-
.FJ|7
SJLL7
|F--J
LJ.LJ";

const SAMPLE2: &str = r"FF7FSF7F7F7F7F7F---7
L|LJ||||||||||||F--J
FL-7LJLJ||||||LJL-77
F--JF--7||LJLJ7F7FJ-
L---JF-JLJ.||-FJLJJ7
|F|F-JF---7F7-L7L|7|
|FFJF7L7F-JF7|JL---7
7-L-JL7||F7|L7F-7F7|
L.L7LFJ|||||FJL7||LJ
L7JLJL-JLJLJL--JLJ.L";

#[test]
pub fn input_test() {
println!("{:?}", generator(SAMPLE));

// assert_eq!(generator(SAMPLE), Object());
}

#[test]
pub fn part1_test() {
assert_eq!(part1(&generator(SAMPLE)), 8);
}

#[test]
pub fn part2_test() {
assert_eq!(part2(&generator(SAMPLE2)), 10);
}

mod regression {
use super::*;

const INPUT: &str = include_str!("../input/2023/day10.txt");
const ANSWERS: (usize, usize) = (6640, 411);

#[test]
pub fn test() {
let input = INPUT.trim_end_matches('\n');
let output = generator(input);

assert_eq!(part1(&output), ANSWERS.0);
assert_eq!(part2(&output), ANSWERS.1);
}
}
}
1 change: 1 addition & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,6 @@ pub mod day06;
pub mod day07;
pub mod day08;
pub mod day09;
pub mod day10;
// Insert before
aoc_lib! { year = 2023 }

0 comments on commit 3c7d4f8

Please sign in to comment.