[Mark Doyle's Website]

[Advent of Code]

Day 6

use crate::*;
use std::fmt::Display;

fn parse_input(input: &str) -> (Vec<Vec<char>>, (usize, usize)) {
    let matrix = input
        .lines()
        .map(|line| line.chars().collect::<Vec<_>>())
        .collect::<Vec<_>>();

    let mut cur = (0, 0);
    for (i, row) in matrix.iter().enumerate() {
        for (j, ch) in row.iter().enumerate() {
            if *ch == '^' {
                cur = (i, j);
            }
        }
    }

    (matrix, cur)
}

impl Day6 for Year2024 {
    fn part1(input: String) -> impl Display {
        let (matrix, mut cur) = parse_input(&input);

        let mut seen = vec![];

        for row in &matrix {
            for _ in row {
                seen.push(false);
            }
        }
        let width = matrix.get(0).unwrap().len();

        let mut n = 1;
        let mut dir = 0;

        let dirs: [(isize, isize); 4] = [(-1, 0), (0, 1), (1, 0), (0, -1)];

        loop {
            let di = cur.0.wrapping_add_signed(dirs[dir].0);
            let dj = cur.1.wrapping_add_signed(dirs[dir].1);

            let ch = match matrix.get(di).map(|r| r.get(dj)).flatten() {
                Some(ch) => ch,
                None => break,
            };

            if !seen[di * width + dj] && *ch != '#' {
                n += 1;
            }

            if '#' == *ch {
                dir = (dir + 1) % 4;
            } else {
                seen[di * width + dj] = true;
                cur = (di, dj)
            }
        }

        n
    }

    fn part2(input: String) -> impl Display {
        let (mut matrix, start) = parse_input(&input);
        let mut n = 0;
        let dirs: [(isize, isize); 4] = [(-1, 0), (0, 1), (1, 0), (0, -1)];

        for i in 0..matrix.len() {
            for j in 0..matrix[i].len() {
                if (i, j) == start || matrix[i][j] != '.' {
                    continue;
                }

                matrix[i][j] = '#';

                let mut cur = start;
                let mut dir = 0;
                let mut seen = vec![];

                for row in &matrix {
                    for _ in row {
                        seen.push(0);
                    }
                }
                let width = matrix.get(0).unwrap().len();

                while let Some(Some(ch)) = matrix
                    .get(cur.0.wrapping_add_signed(dirs[dir].0))
                    .map(|r| r.get(cur.1.wrapping_add_signed(dirs[dir].1)))
                {
                    let hash = (cur.0 * width + cur.1) * 4 + dir;
                    if seen[cur.0 * width + cur.1] == hash {
                        n += 1;
                        break;
                    }
                    seen[cur.0 * width + cur.1] = hash;

                    if *ch == '#' {
                        dir = (dir + 1) % 4;
                    } else {
                        cur = (
                            cur.0.wrapping_add_signed(dirs[dir].0),
                            cur.1.wrapping_add_signed(dirs[dir].1),
                        );
                    }
                }

                matrix[i][j] = '.';
            }
        }

        n
    }
}
*/_\/_*_\/__*__\/___*___\|*/_\/_*_\/__*__\/___*___\|*/_\/_*_\/__*__\/___*___\|*/_\/_*_\/__*__\/___*___\|*/_\/_*_\/__*__\/___*___\|*/_\/_*_\/__*__\/___*___\|*/_\/_*_\/__*__\/___*___\|*/_\/_*_\/__*__\/___*___\|*/_\/_*_\/__*__\/___*___\|*/_\/_*_\/__*__\/___*___\|*/_\/_*_\/__*__\/___*___\|*/_\/_*_\/__*__\/___*___\|*/_\/_*_\/__*__\/___*___\|*/_\/_*_\/__*__\/___*___\|*/_\/_*_\/__*__\/___*___\|*/_\/_*_\/__*__\/___*___\|*/_\/_*_\/__*__\/___*___\|*/_\/_*_\/__*__\/___*___\|*/_\/_*_\/__*__\/___*___\|*/_\/_*_\/__*__\/___*___\|*/_\/_*_\/__*__\/___*___\|*/_\/_*_\/__*__\/___*___\|*/_\/_*_\/__*__\/___*___\|*/_\/_*_\/__*__\/___*___\|*/_\/_*_\/__*__\/___*___\|*/_\/_*_\/__*__\/___*___\|*/_\/_*_\/__*__\/___*___\|*/_\/_*_\/__*__\/___*___\|*/_\/_*_\/__*__\/___*___\|*/_\/_*_\/__*__\/___*___\|*/_\/_*_\/__*__\/___*___\|*/_\/_*_\/__*__\/___*___\|*/_\/_*_\/__*__\/___*___\|*/_\/_*_\/__*__\/___*___\|*/_\/_*_\/__*__\/___*___\|*/_\/_*_\/__*__\/___*___\|*/_\/_*_\/__*__\/___*___\|*/_\/_*_\/__*__\/___*___\|*/_\/_*_\/__*__\/___*___\|*/_\/_*_\/__*__\/___*___\|*/_\/_*_\/__*__\/___*___\|*/_\/_*_\/__*__\/___*___\|*/_\/_*_\/__*__\/___*___\|*/_\/_*_\/__*__\/___*___\|*/_\/_*_\/__*__\/___*___\|*/_\/_*_\/__*__\/___*___\|*/_\/_*_\/__*__\/___*___\|*/_\/_*_\/__*__\/___*___\|*/_\/_*_\/__*__\/___*___\|*/_\/_*_\/__*__\/___*___\|