Compare commits
No commits in common. "30bd722f3eec46f72262f27b31321c149cda3ed9" and "b6111fe33729b8aaef5ddd89f0804d8e29ac5776" have entirely different histories.
30bd722f3e
...
b6111fe337
|
@ -3,6 +3,7 @@ use aoc_runner_derive::{aoc, aoc_generator};
|
||||||
type Board = Vec<Vec<char>>;
|
type Board = Vec<Vec<char>>;
|
||||||
type Pair = (usize, usize);
|
type Pair = (usize, usize);
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
struct Map {
|
struct Map {
|
||||||
rows: Board,
|
rows: Board,
|
||||||
cols: Board,
|
cols: Board,
|
||||||
|
|
|
@ -1,220 +0,0 @@
|
||||||
use aoc_runner_derive::{aoc, aoc_generator};
|
|
||||||
use std::collections::HashSet;
|
|
||||||
|
|
||||||
#[aoc_generator(day16)]
|
|
||||||
fn parse(input: &str) -> Vec<Vec<char>> {
|
|
||||||
input
|
|
||||||
.lines()
|
|
||||||
.filter_map(|line| {
|
|
||||||
if !line.is_empty() {
|
|
||||||
Some(line.chars().collect())
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.collect()
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Copy, Clone, Eq, PartialEq, Hash)]
|
|
||||||
enum Dir {
|
|
||||||
North,
|
|
||||||
East,
|
|
||||||
South,
|
|
||||||
West,
|
|
||||||
}
|
|
||||||
|
|
||||||
fn visited_spaces(
|
|
||||||
map: &[Vec<char>],
|
|
||||||
visited: &mut HashSet<(i64, i64, Dir)>,
|
|
||||||
start_x: i64,
|
|
||||||
start_y: i64,
|
|
||||||
start_dir: Dir,
|
|
||||||
depth: usize,
|
|
||||||
) {
|
|
||||||
if start_x < 0
|
|
||||||
|| start_y < 0
|
|
||||||
|| start_x as usize > (map.len() - 1)
|
|
||||||
|| start_y as usize > (map[0].len() - 1)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
let mut x = start_x;
|
|
||||||
let mut y = start_y;
|
|
||||||
let mut dir = start_dir;
|
|
||||||
if visited.contains(&(x, y, dir)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
loop {
|
|
||||||
let now = (x, y, dir);
|
|
||||||
if visited.contains(&now) {
|
|
||||||
return;
|
|
||||||
} else {
|
|
||||||
visited.insert((x, y, dir));
|
|
||||||
}
|
|
||||||
match dir {
|
|
||||||
Dir::North => match map[x as usize][y as usize] {
|
|
||||||
'/' => dir = Dir::East,
|
|
||||||
'\\' => dir = Dir::West,
|
|
||||||
'|' => {}
|
|
||||||
'-' => {
|
|
||||||
visited_spaces(map, visited, x, y, Dir::West, depth + 1);
|
|
||||||
dir = Dir::East;
|
|
||||||
}
|
|
||||||
'.' => {}
|
|
||||||
n @ _ => panic!("unknown map piece {}", n),
|
|
||||||
},
|
|
||||||
Dir::South => match map[x as usize][y as usize] {
|
|
||||||
'/' => dir = Dir::West,
|
|
||||||
'\\' => dir = Dir::East,
|
|
||||||
'|' => {}
|
|
||||||
'-' => {
|
|
||||||
visited_spaces(map, visited, x, y, Dir::West, depth + 1);
|
|
||||||
dir = Dir::East;
|
|
||||||
}
|
|
||||||
'.' => {}
|
|
||||||
n @ _ => panic!("unknown map piece {}", n),
|
|
||||||
},
|
|
||||||
Dir::East => match map[x as usize][y as usize] {
|
|
||||||
'/' => dir = Dir::North,
|
|
||||||
'\\' => dir = Dir::South,
|
|
||||||
'|' => {
|
|
||||||
visited_spaces(map, visited, x, y, Dir::North, depth + 1);
|
|
||||||
dir = Dir::South;
|
|
||||||
}
|
|
||||||
'-' => {}
|
|
||||||
'.' => {}
|
|
||||||
n @ _ => panic!("unknown map piece {}", n),
|
|
||||||
},
|
|
||||||
Dir::West => match map[x as usize][y as usize] {
|
|
||||||
'/' => dir = Dir::South,
|
|
||||||
'\\' => dir = Dir::North,
|
|
||||||
'|' => {
|
|
||||||
visited_spaces(map, visited, x, y, Dir::North, depth + 1);
|
|
||||||
dir = Dir::South;
|
|
||||||
}
|
|
||||||
'-' => {}
|
|
||||||
'.' => {}
|
|
||||||
n @ _ => panic!("unknown map piece {}", n),
|
|
||||||
},
|
|
||||||
}
|
|
||||||
match dir {
|
|
||||||
Dir::North => {
|
|
||||||
x -= 1;
|
|
||||||
if x < 0 {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Dir::South => {
|
|
||||||
x += 1;
|
|
||||||
if x as usize >= map.len() {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Dir::East => {
|
|
||||||
y += 1;
|
|
||||||
if y as usize >= map[0].len() {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Dir::West => {
|
|
||||||
y -= 1;
|
|
||||||
if y < 0 {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn energized_squares(visited: &HashSet<(i64, i64, Dir)>) -> usize {
|
|
||||||
let mut t: HashSet<(i64, i64)> = HashSet::new();
|
|
||||||
for i in visited.iter() {
|
|
||||||
t.insert((i.0, i.1));
|
|
||||||
}
|
|
||||||
t.len()
|
|
||||||
}
|
|
||||||
|
|
||||||
#[aoc(day16, part1)]
|
|
||||||
fn part1(input: &[Vec<char>]) -> usize {
|
|
||||||
let mut visited: HashSet<(i64, i64, Dir)> = HashSet::new();
|
|
||||||
visited_spaces(input, &mut visited, 0, 0, Dir::East, 0);
|
|
||||||
energized_squares(&visited)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[aoc(day16, part2)]
|
|
||||||
fn part2(input: &[Vec<char>]) -> usize {
|
|
||||||
let mut max = 0;
|
|
||||||
let xlen = input.len() - 1;
|
|
||||||
let ylen = input[0].len() - 1;
|
|
||||||
|
|
||||||
for t in 0..=xlen {
|
|
||||||
let mut evisited: HashSet<(i64, i64, Dir)> = HashSet::new();
|
|
||||||
visited_spaces(input, &mut evisited, t as i64, 0, Dir::East, 0);
|
|
||||||
let emax = energized_squares(&evisited);
|
|
||||||
if emax > max {
|
|
||||||
max = emax;
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut wvisited: HashSet<(i64, i64, Dir)> = HashSet::new();
|
|
||||||
visited_spaces(
|
|
||||||
input,
|
|
||||||
&mut wvisited,
|
|
||||||
xlen as i64,
|
|
||||||
(ylen - t) as i64,
|
|
||||||
Dir::West,
|
|
||||||
0,
|
|
||||||
);
|
|
||||||
let wmax = energized_squares(&wvisited);
|
|
||||||
if wmax > max {
|
|
||||||
max = wmax;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for t in 0..=ylen {
|
|
||||||
let mut svisited: HashSet<(i64, i64, Dir)> = HashSet::new();
|
|
||||||
visited_spaces(input, &mut svisited, 0, t as i64, Dir::South, 0);
|
|
||||||
let smax = energized_squares(&svisited);
|
|
||||||
if smax > max {
|
|
||||||
max = smax;
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut nvisited: HashSet<(i64, i64, Dir)> = HashSet::new();
|
|
||||||
visited_spaces(
|
|
||||||
input,
|
|
||||||
&mut nvisited,
|
|
||||||
xlen as i64,
|
|
||||||
(ylen - t) as i64,
|
|
||||||
Dir::North,
|
|
||||||
0,
|
|
||||||
);
|
|
||||||
let nmax = energized_squares(&nvisited);
|
|
||||||
if nmax > max {
|
|
||||||
max = nmax;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
max
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(test)]
|
|
||||||
mod tests {
|
|
||||||
use super::*;
|
|
||||||
|
|
||||||
const SAMPLE_DATA: &'static str = r#".|...\....
|
|
||||||
|.-.\.....
|
|
||||||
.....|-...
|
|
||||||
........|.
|
|
||||||
..........
|
|
||||||
.........\
|
|
||||||
..../.\\..
|
|
||||||
.-.-/..|..
|
|
||||||
.|....-|.\
|
|
||||||
..//.|...."#;
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn sample_data() {
|
|
||||||
let input = parse(&SAMPLE_DATA);
|
|
||||||
assert_eq!(part1(&input), 46);
|
|
||||||
assert_eq!(part2(&input), 51);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -15,6 +15,5 @@ mod day12;
|
||||||
mod day13;
|
mod day13;
|
||||||
mod day14;
|
mod day14;
|
||||||
mod day15;
|
mod day15;
|
||||||
mod day16;
|
|
||||||
|
|
||||||
aoc_lib! { year = 2023 }
|
aoc_lib! { year = 2023 }
|
||||||
|
|
Loading…
Reference in New Issue