1
0
Fork 0

Compare commits

...

2 Commits

Author SHA1 Message Date
Andrew Coleman 30bd722f3e remove derive(Debug) 2023-12-28 22:20:58 -05:00
Andrew Coleman 055946115a day16 solution 2023-12-28 22:20:46 -05:00
3 changed files with 221 additions and 1 deletions

View File

@ -3,7 +3,6 @@ use aoc_runner_derive::{aoc, aoc_generator};
type Board = Vec<Vec<char>>;
type Pair = (usize, usize);
#[derive(Debug)]
struct Map {
rows: Board,
cols: Board,

220
2023/src/day16.rs Normal file
View File

@ -0,0 +1,220 @@
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);
}
}

View File

@ -15,5 +15,6 @@ mod day12;
mod day13;
mod day14;
mod day15;
mod day16;
aoc_lib! { year = 2023 }