diff --git a/Cargo.lock b/Cargo.lock index 68abe3f..ba878a1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -27,6 +27,7 @@ dependencies = [ "itertools 0.12.0", "lazy_static", "lcmx", + "petgraph", "prime_factorization", "rayon", "regex", @@ -89,6 +90,18 @@ version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07" +[[package]] +name = "equivalent" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" + +[[package]] +name = "fixedbitset" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ce7134b9999ecaf8bcd65542e436736ef32ddca1b3e06094cb6ec5755203b80" + [[package]] name = "fs-err" version = "2.11.0" @@ -115,6 +128,22 @@ dependencies = [ "wasi", ] +[[package]] +name = "hashbrown" +version = "0.14.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604" + +[[package]] +name = "indexmap" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d530e1a18b1cb4c484e6e34556a0d948706958449fca0cab753d649f2bce3d1f" +dependencies = [ + "equivalent", + "hashbrown", +] + [[package]] name = "itertools" version = "0.10.5" @@ -245,6 +274,16 @@ dependencies = [ "autocfg", ] +[[package]] +name = "petgraph" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1d3afd2628e69da2be385eb6f2fd57c8ac7977ceeff6dc166ff1657b0e386a9" +dependencies = [ + "fixedbitset", + "indexmap", +] + [[package]] name = "ppv-lite86" version = "0.2.17" diff --git a/Cargo.toml b/Cargo.toml index 5f4d583..f694cc5 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,6 +12,7 @@ fs-err = "2.9.0" itertools = "0.12.0" lazy_static = "1.4.0" lcmx = "0.1.3" +petgraph = "0.6.4" prime_factorization = "1.0.4" rayon = "1.6.1" regex = "1.7.0" diff --git a/examples/day23.rs b/examples/day23.rs index 4e2d04b..90606de 100644 --- a/examples/day23.rs +++ b/examples/day23.rs @@ -1,4 +1,5 @@ use itertools::Itertools; +use std::collections::{HashMap, VecDeque}; const INPUT: &str = include_str!("inputs/day23.txt"); const _TEST_INPUT: &str = include_str!("inputs/day23_test.txt"); @@ -39,18 +40,41 @@ impl Dir { type Co = (usize, usize); +/*fn dfs_longest_path_part2(path: Vec, end: Co, grid: &[Vec]) -> Option { + let start = path.last().unwrap(); + + if start == &end { + return Some(path.len() - 1); + } + + let rows = grid.len(); + let cols = grid[0].len(); + [(-1isize, 0isize), (1, 0), (0, -1), (0, 1)] + .into_iter() + .filter_map(|ofs| try_add(start, ofs, rows, cols)) + .filter(|co| grid[co.0][co.1] != '#') + .filter(|co| !path.contains(co)) + .filter_map(|co| { + let mut npath = path.clone(); + npath.push(co); + dfs_longest_path_part2(npath, end, grid) + }) + .max() +} +*/ + fn dfs_longest_path( path: Vec, - end: Co, + ends: &[Co], grid: &[Vec], compelled_step: Option<(isize, isize)>, -) -> Option { +) -> Option> { //println!("{:?}", path); let start = path.last().unwrap(); - if start == &end { - return Some(path.len() - 1); + if ends.contains(start) { + return Some(path); } let offsets = if let Some(ofs) = compelled_step { @@ -71,9 +95,191 @@ fn dfs_longest_path( Dir::try_from_char(grid[co.0][co.1]).and_then(|d| Some(d.as_tuple())); let mut npath = path.clone(); npath.push(co); - dfs_longest_path(npath, end, grid, compelled_step) + dfs_longest_path(npath, ends, grid, compelled_step) }) - .max() + .max_by(|path1, path2| path1.len().cmp(&path2.len())) +} + +fn find_longest_path(start: Co, ends: &[Co], grid: &[Vec]) -> Vec<((usize, usize), usize)> { + let rows = grid.len(); + let cols = grid[0].len(); + + let mut q = VecDeque::new(); + q.push_back(vec![start]); + + let mut nodes = vec![(start, 0)]; + + while let Some(path) = q.pop_front() { + let here = path.last().unwrap(); + let ncoords = [(-1isize, 0isize), (1, 0), (0, -1), (0, 1)] + .into_iter() + .filter_map(|ofs| try_add(&here, ofs, rows, cols)) + .filter(|co| grid[co.0][co.1] != '#') + .filter(|co| !path.contains(co)) + .collect_vec(); + + // Have we arrived at a crossing? + if ncoords.len() > 1 || ends.contains(&here) { + // Resolve the longest path from previous node to this point and record it at the node + let (pstart, plen) = nodes.last().unwrap(); + println!("Crossing: {:?}", here); + println!("DFS from {:?} to {:?}", pstart, here); + // TODO: compelled step from path.first to path.second OR NOT + let longest_path_len = dfs_longest_path(vec![*pstart], &[*here], grid, None) + .unwrap() + .len() + - 1; + nodes.push((*here, longest_path_len + plen)); + + if ends.contains(here) { + return nodes; + } + + // Collapse the queue + q.clear(); + } + + let npaths = ncoords + .into_iter() + .map(|co| { + let mut npath = path.clone(); + npath.push(co); + npath + }) + .collect_vec(); + q.extend(npaths); + } + + nodes +} + +fn find_crossings(grid: &[Vec]) -> Vec { + let rows = grid.len(); + let cols = grid[0].len(); + + let mut crossings = vec![]; + for (row, line) in grid.iter().enumerate() { + for (col, c) in line.iter().enumerate() { + if c != &'#' + && [(-1isize, 0isize), (1, 0), (0, -1), (0, 1)] + .into_iter() + .filter_map(|ofs| try_add(&(row, col), ofs, rows, cols)) + .filter(|co| grid[co.0][co.1] != '#') + .count() + > 2 + { + crossings.push((row, col)); + } + } + } + + crossings +} + +#[derive(Debug, Clone)] +struct Edge(Co, usize); + +fn find_edges(node: Co, nodes: &[Co], grid: &[Vec]) -> Vec { + let rows = grid.len(); + let cols = grid[0].len(); + + let mut q = VecDeque::new(); + q.push_back(vec![node]); + + let mut edges = vec![]; + + while let Some(path) = q.pop_front() { + let start = path.last().unwrap(); + + // If we hit an edge, store this path as an edge, otherwise keep looking + if *start != node && nodes.contains(start) { + edges.push(Edge(*start, path.len() - 1)); + } else { + let cos = [(-1isize, 0isize), (1, 0), (0, -1), (0, 1)] + .into_iter() + .filter_map(|ofs| try_add(start, ofs, rows, cols)) + .filter(|co| grid[co.0][co.1] != '#') + .filter(|co| !path.contains(co)) + .map(|co| { + let mut npath = path.clone(); + npath.push(co); + npath + }) + .collect_vec(); + q.extend(cos); + } + } + + edges +} + +fn find_all_edges(nodes: &[Co], grid: &[Vec]) -> HashMap> { + let mut all_edges = HashMap::new(); + + for node in nodes { + let edges = find_edges(*node, nodes, grid); + all_edges.insert(*node, edges); + } + + all_edges +} + +fn make_graph(start: Co, end: Co, grid: &[Vec]) -> HashMap> { + let mut crossings = find_crossings(grid); + crossings.push(start); + crossings.push(end); + + let edges = find_all_edges(&crossings, grid); + + edges +} + +fn find_longest(start: Co, end: Co, src_graph: HashMap>) -> usize { + use petgraph::{algo, prelude::*}; + + let mut graph = DiGraph::::new(); + + for (node, _) in src_graph.iter() { + graph.add_node(*node); + } + for (node, edges) in src_graph.iter() { + let node = graph.node_indices().find(|i| graph[*i] == *node).unwrap(); + for Edge(dest, wgt) in edges { + graph.add_edge( + node, + graph.node_indices().find(|i| graph[*i] == *dest).unwrap(), + *wgt, + ); + } + } + + let start = graph.node_indices().find(|i| graph[*i] == start).unwrap(); + let end = graph.node_indices().find(|i| graph[*i] == end).unwrap(); + let paths = + algo::all_simple_paths::, _>(&graph, start, end, 0, None).collect::>(); + let paths = paths + .into_iter() + .map(|path| path.into_iter().map(|idx| graph[idx]).collect_vec()) + .collect_vec(); + + let path_lens = paths.into_iter().map(|path| { + let len = path + .windows(2) + .map(|win| { + let (src, dest) = (win[0], win[1]); + src_graph + .get(&src) + .unwrap() + .iter() + .find_map(|edge| (edge.0 == dest).then_some(edge.1)) + .unwrap() + }) + .sum::(); + len + }); + let longest_path: usize = path_lens.max().unwrap(); + + longest_path } fn main() -> anyhow::Result<()> { @@ -81,11 +287,18 @@ fn main() -> anyhow::Result<()> { let grid = lines.map(|line| line.chars().collect_vec()).collect_vec(); let start = (0, 1); + let end = (grid.len() - 1, grid.len() - 2); + + let longest = dfs_longest_path(vec![start], &[end], &grid, None) + .unwrap() + .len() + - 1; - let longest = - dfs_longest_path(vec![start], (grid.len() - 1, grid.len() - 2), &grid, None).unwrap(); + println!("Part 1: {longest}"); - println!("{longest}"); + let graph = make_graph(start, end, &grid); + let longest = find_longest(start, end, graph); + println!("Part 2: {longest}"); Ok(()) } diff --git a/examples/inputs/day23.txt b/examples/inputs/day23.txt new file mode 100644 index 0000000..0009c20 --- /dev/null +++ b/examples/inputs/day23.txt @@ -0,0 +1,141 @@ +#.########################################################################################################################################### +#...#...#...###...###...#...#...#...#...###...#...#####.....#.............#.....#...#...###.......#...#.....#####...#...#####...#...###...### +###.#.#.#.#.###.#.###.#.#.#.#.#.#.#.#.#.###.#.#.#.#####.###.#.###########.#.###.#.#.#.#.###.#####.#.#.#.###.#####.#.#.#.#####.#.#.#.###.#.### +###.#.#.#.#...#.#...#.#.#.#.#.#.#.#.#.#.#...#...#.###...#...#.....#.......#...#...#.#.#.#...#.....#.#.#...#.#.....#...#.......#...#.#...#...# +###.#.#v#.###.#.###.#.#.#.#.#.#.#.#.#.#.#.#######.###.###.#######.#.#########.#####.#.#.#.###.#####.#.###.#.#.#####################.#.#####.# +###...#.>.#...#.#...#.#.#.#.#.#.#.#.#.#.#.......#...#...#.>.>.###.#.#...#...#.#.....#.#.#...#.#####.#.#...#.#...#...#...#.........#.#.#.....# +#######v###.###.#.###.#.#.#.#.#.#.#.#.#.#######.###.###.###v#.###.#.#.#.#.#.#.#.#####.#.###.#.#####.#.#.###.###.#.#.#.#.#.#######.#.#.#.##### +#...#...###.....#...#.#.#.#.#.#.#.#.#.#.#.....#...#.#...#...#.....#...#.#.#.#.#.#.....#.>.>.#...#...#.#...#.....#.#...#...#.....#...#.#.#...# +#.#.#.#############.#.#.#.#.#.#.#.#.#.#.#.###.###.#.#.###.#############.#.#.#.#.#.#######v#####.#.###.###.#######.#########.###.#####.#.#.#.# +#.#...#...###.......#.#.#.#.#.#.#.#.#.#.#...#.#...#...###...#...#...#...#.#...#...###...#.###...#...#.###.......#.#...#...#.#...#...#.#.#.#.# +#.#####.#.###.#######.#.#.#.#.#.#.#.#.#.###.#.#.###########.#.#.#.#.#.###.###########.#.#.###.#####.#.#########.#.#.#.#.#.#.#.###.#.#.#.#.#.# +#...#...#...#.#.....#.#.#.#.#.#.#.#.#.#.#...#.#...........#.#.#...#.#...#.#.........#.#.#...#.#...#.#...#...>.>.#...#...#.#.#...#.#.#.#.#.#.# +###.#.#####.#.#.###.#.#.#.#.#.#.#.#.#.#.#.###.###########.#.#.#####.###.#.#.#######.#.#.###.#.#.#.#.###.#.###v###########.#.###.#.#.#.#.#.#.# +###.#.#.....#.#.#...#.#.#.#.#.#.#.#.#.#.#...#.#...#.....#.#.#.#.....###...#.......#.#.#.#...#.#.#.#...#...#...#.........#.#.#...#.#.#.#.#.#.# +###.#.#.#####.#.#.###.#.#.#.#.#.#.#.#.#.###.#.#.#.#.###.#.#.#.#.#################.#.#.#.#.###.#.#.###.#####.###.#######.#.#.#.###.#.#.#.#.#.# +###...#.....#.#.#...#.#...#.#.#.#.#.#.#.>.>.#.#.#.#...#...#...#...........#.......#...#...#...#.#.#...#...#...#...#...#...#.#.#...#.#.#.#.#.# +###########.#.#.###.#.#####.#.#.#.#.#.###v###.#.#.###.###################.#.###############.###.#.#.###.#.###.###.#.#.#####.#.#.###.#.#.#.#.# +#...........#...#...#.....#.#.#...#...#...###.#.#.#...#...................#.............#...#...#.#...#.#.....###.#.#.....#.#.#.#...#.#...#.# +#.###############.#######.#.#.#########.#####.#.#.#.###.###############################.#.###.###.###.#.#########.#.#####.#.#.#.#.###.#####.# +#...............#...#...#.#...###...#...#...#...#...###...................#.............#.....###.....#.........#.#...#...#.#.#.#...#.#.....# +###############.###.#.#.#.#######.#.#.###.#.#############################.#.###################################.#.###.#.###.#.#.###.#.#.##### +#...............#...#.#...###.....#...###.#.###...#####...#...........#...#.#.......#...#.......###...#...#...#.#.#...#...#.#.#.#...#.#.....# +#.###############.###.#######.###########.#.###.#.#####.#.#.#########.#.###.#.#####.#.#.#.#####.###.#.#.#.#.#.#.#.#.#####.#.#.#.#.###.#####.# +#.......#.......#...#...#.....#.......###.#.#...#...#...#.#.........#...###...#.....#.#.#.....#.#...#.#.#...#...#...#.....#.#.#.#...#.#.....# +#######.#.#####.###.###.#.#####.#####.###.#.#.#####.#.###.#########.###########.#####.#.#####.#.#.###.#.#############.#####.#.#.###.#.#.##### +#.......#.#.....###.#...#...#...#.....#...#.#.....#.#.#...#####...#.......#...#.....#.#.#...#.#.#.#...#.........#...#...#...#...###...#.....# +#.#######.#.#######.#.#####.#.###.#####.###.#####.#.#.#.#######.#.#######.#.#.#####.#.#.#.#.#.#.#.#.###########.#.#.###.#.#################.# +#.#...#...#...#...#...#...#...#...###...#...#.....#.#.#.....#...#.........#.#.###...#.#.#.#.#.#.#.#.#...###.....#.#.###...###.........###...# +#.#.#.#.#####v#.#.#####.#.#####.#####.###.###.#####.#.#####.#.#############.#.###.###.#.#.#.#.#.#.#.#.#.###v#####.#.#########.#######.###.### +#...#.#.#...#.>.#...#...#.#...#.....#.#...###.....#...#.....#...#.........#.#.#...###.#.#.#.#.#.#.#...#...>.>.###.#.#...#...#.......#.....### +#####.#.#.#.#v#####.#.###.#.#.#####.#.#.#########.#####.#######.#.#######.#.#.#.#####.#.#.#.#.#.#.#########v#.###.#.#.#.#.#.#######.######### +#...#...#.#...#.....#...#.#.#.......#.#.#...#...#...#...###...#.#.#.......#.#.#...#...#...#.#.#...#.........#...#.#.#.#.#.#.#...###.........# +#.#.#####.#####.#######.#.#.#########.#.#.#.#.#.###.#.#####.#.#v#.#.#######.#.###.#.#######.#.#####.###########.#.#.#.#.#.#.#.#.###########.# +#.#.......#...#...#####.#.#.......#...#.#.#.#.#...#.#...#...#.>.>.#...#...#.#.###.#.......#.#...###...#.......#.#.#.#.#.#.#...#...#.........# +#.#########.#.###.#####.#.#######v#.###.#.#.#.###.#.###.#.#####v#####.#.#.#.#.###v#######.#.###.#####.#.#####.#.#.#.#.#.#.#######.#.######### +#.#.......#.#...#...#...#.......>.>.###...#...#...#...#...###...#...#...#.#.#...>.>.......#...#.#...#...#...#.#.#.#.#.#...#.......#.........# +#.#.#####.#.###.###.#.###########v#############.#####.#######.###.#.#####.#.#####v###########.#.#.#.#####.#.#.#.#.#.#.#####.###############.# +#...#...#.#.#...###...#...........###.......###.#.....#.......###.#.......#...###.........###...#.#.......#.#.#.#.#...#.....#...#...........# +#####.#.#.#.#.#########.#############.#####.###.#.#####.#########.###########.###########.#######.#########.#.#.#.#####.#####.#.#.########### +#...#.#.#...#.......###...............#.....#...#.#...#.........#.....#...#...#...........#...###.......###...#...#.....#...#.#.#.........### +#.#.#.#.###########.###################.#####.###.#.#.#########.#####.#.#.#.###.###########.#.#########.###########.#####.#.#.#.#########v### +#.#...#.............#...#...#.....#...#...###...#.#.#...........#...#...#...###.........#...#.#.......#.......#.....#...#.#.#.#...#.....>.### +#.###################.#.#.#.#.###.#.#.###.#####.#.#.#############.#.###################.#.###.#.#####.#######.#.#####.#.#.#.#.###.#.#####v### +#.#.....#...#...#.....#...#.#...#...#...#.....#.#.#...#...#.......#...#.....###...#...#.#...#.#.#...#.........#.....#.#.#.#.#.#...#.#.....### +#.#.###.#.#.#.#.#.#########.###.#######.#####.#.#.###.#.#.#.#########.#.###.###.#.#.#.#.###.#.#.#.#.###############.#.#.#.#.#.#.###.#.####### +#.#.#...#.#...#...#.........###.......#...#...#...###...#...#...#...#.#...#.....#...#...#...#.#...#.#.......#.......#.#.#.#...#...#.#.......# +#.#.#.###.#########.#################.###.#.#################.#.#.#.#.###.###############.###.#####.#.#####.#.#######.#.#.#######.#.#######.# +#.#.#...#.#.........#...#...#.........###...#...###...###.....#...#...#...#...........###...#.#.....#.#.....#.......#.#...###...#.#.#.......# +#.#.###.#.#.#########.#.#.#.#.###############.#.###.#.###.#############.###.#########.#####.#.#.#####.#.###########.#.#######.#.#.#.#.####### +#.#...#...#...........#...#.#.........#.....#.#.#...#.....###...#...###.....#...#.....#...#.#.#...#...#.#...#.....#.#.#.....#.#.#...#.......# +#.###.#####################.#########.#.###.#.#.#.###########.#.#.#.#########.#.#.#####.#.#.#.###.#.###.#.#.#.###.#.#.#.###.#.#.###########.# +#.....###...................#.........#...#...#.#.........#...#...#...#...#...#...#...#.#...#.###...###...#...#...#...#...#.#.#.###...#.....# +#########.###################.###########.#####.#########.#.#########.#.#.#.#######.#.#.#####.#################.#########.#.#.#.###.#.#.##### +#.....#...#...#.....#...#...#...#...#...#.....#.#...#...#.#.#...#.....#.#.#...###...#.#...#...#...#...#.........#...#.....#.#.#.#...#.#.....# +#.###.#.###.#.#.###.#.#.#.#.###.#.#.#.#.#####.#.#.#.#.#.#v#.#.#.#.#####.#.###.###.###.###.#.###.#.#.#.#v#########.#.#.#####.#.#.#.###.#####.# +#...#.#.....#...#...#.#.#.#.....#.#.#.#.#...#.#.#.#...#.>.>.#.#...#.....#.###...#...#...#.#...#.#.#.#.>.>...#...#.#.#.....#.#.#.#...#.###...# +###.#.###########v###.#.#.#######.#.#.#.#.#.#.#.#.#######v###.#####.#####.#####.###.###.#.###.#.#.#.###v###.#.#.#.#.#####.#.#.#.###.#.###v### +#...#...........#.>.#.#.#.......#.#.#.#.#.#...#.#.....#...###...###.....#.#.....###...#...#...#.#.#.###...#.#.#.#.#...#...#.#.#.#...#.#.>.### +#.#############.#v#.#.#.#######v#.#.#.#.#.#####.#####.#.#######.#######.#.#v#########.#####.###.#.#.#####.#.#.#.#.###.#.###.#.#.#.###.#.#v### +#.............#.#.#.#.#.#...#.>.>.#...#.#.###...#.....#.....###...#...#.#.>.>.#...#...#.....#...#.#.#.....#...#.#.#...#.#...#.#.#.###.#.#...# +#############.#.#.#.#.#.#.#.#.#v#######.#.###.###.#########.#####.#.#.#.###v#.#.#.#.###.#####.###.#.#.#########.#.#.###.#.###.#.#.###.#.###.# +###...#.....#.#...#.#.#.#.#.#.#.###.....#...#...#...#.......#.....#.#.#.#...#...#...###.....#...#...#.....#...#...#.#...#...#.#.#...#...#...# +###.#.#.###.#.#####.#.#.#.#.#.#.###.#######.###.###.#.#######.#####.#.#.#.#################.###.#########.#.#.#####.#.#####.#.#.###.#####.### +#...#...#...#.....#...#...#.#.#...#.........###.....#.......#.#...#.#.#.#.#...#####...#...#.....###...###...#.....#...#...#.#.#.#...###...### +#.#######.#######.#########.#.###.#########################.#.#.#.#.#.#.#.#.#.#####.#.#.#.#########.#.###########.#####.#.#.#.#.#.#####.##### +#.......#.#.....#.....#.....#...#...###.....#.....#.........#...#.#.#.#.#.#.#...###.#...#.....#.....#.............#.....#.#...#...#...#.....# +#######.#.#.###.#####.#.#######.###.###.###.#.###.#.#############.#.#.#.#.#.###.###.#########.#.###################.#####.#########.#.#####.# +#.......#.#...#.#...#.#.....#...###...#.#...#.#...#...........#...#.#...#...###.....#...#.....#.....#.....###.......#...#...#...#...#.......# +#.#######.###.#.#.#.#.#####.#.#######.#.#.###.#.#############.#.###.#################.#.#.#########.#.###.###.#######.#.###.#.#.#.########### +#.......#.....#...#...#.....#.#...#...#.#.....#...#...........#.....###...#...........#...#.....###...###...#.#.......#.....#.#.#...........# +#######.###############.#####.#.#.#.###.#########.#.###################.#.#.###############.###.###########.#.#.#############.#.###########.# +###...#...............#.#...#...#.#...#.#.........#.....................#.#.....#.........#...#.......#...#...#...#.........#.#.....#.......# +###.#.###############.#.#.#.#####.###.#.#.###############################.#####.#.#######.###.#######.#.#.#######.#.#######.#.#####.#.####### +#...#.................#...#...#...###...#.......#...#.................#...#...#.#.#.......#...#.......#.#.#.......#...#.....#.....#...#...### +#.###########################.#.###############.#.#.#.###############.#.###.#.#.#.#.#######.###.#######.#.#.#########.#.#########.#####.#.### +#.......................###...#.#.....#...#...#.#.#.#.......#...#...#...###.#.#...#.#.....#...#.#...#...#.#.......#...#...#.....#.......#...# +#######################.###.###.#.###.#.#.#.#.#.#.#.#######.#.#.#.#.#######.#.#####.#.###.###.#.#.#.#.###.#######.#.#####.#.###.###########.# +#.......................#...#...#...#...#...#.#...#.#.......#.#.#.#...#...#.#.#...#.#.#...###.#.#.#.#...#.###.....#.#.....#.#...#...#...#...# +#.#######################.###.#####.#########.#####.#.#######.#.#.###.#.#.#.#.#.#.#.#.#.#####.#.#.#.###.#.###v#####.#.#####.#.###.#.#.#.#v### +#...............#.....###.....#...#.........#.......#.......#.#.#...#...#.#.#.#.#.#...#.###...#.#.#.#...#...>.>.#...#...#...#.#...#.#.#.>.### +###############.#.###.#########.#.#########.###############.#.#.###.#####.#.#.#.#.#####.###.###.#.#.#.#######v#.#.#####.#.###.#.###.#.###v### +###...#...#.....#.#...#...#.....#.#.....#...###...###...#...#.#.###.#.....#.#.#.#.#...#.#...#...#.#.#...#.....#.#.#.....#...#...###...###...# +###.#.#.#.#.#####.#.###.#.#.#####.#.###.#.#####.#.###.#.#v###.#.###.#.#####.#.#.#.#.#.#v#.###.###.#.###.#.#####.#.#.#######.###############.# +#...#...#...#.....#...#.#...#.....#...#.#...#...#.#...#.>.>...#.#...#.#...#.#.#.#.#.#.>.>.###.....#.....#.....#.#.#.........#...#...#.....#.# +#.###########.#######.#.#####.#######.#.###.#.###.#.#####v#####.#.###.#.#.#.#.#.#.#.###v#####################.#.#.###########.#.#.#.#.###.#.# +#...#...#...#.#.......#.....#.#.....#.#.###...#...#...#...#...#...#...#.#...#.#.#.#...#.......###...#.....#...#.#.#.........#.#...#.#...#.#.# +###.#.#.#.#v#.#.###########.#.#.###.#.#.#######.#####.#.###.#.#####.###.#####.#.#.###.#######.###.#.#.###.#.###.#.#.#######.#.#####.###.#.#.# +#...#.#...#.>.#.#...###...#.#.#...#.#.#.###.....#.....#.....#.....#.....#...#.#.#.....#...#...#...#...###...###...#...#...#...#...#.#...#.#.# +#.###.#####v###.#.#.###.#.#.#.###.#.#.#.###v#####.###############.#######.#.#.#.#######.#.#.###.#####################.#.#.#####.#.#.#.###.#.# +#.....#...#.#...#.#...#.#.#.#.#...#.#.#...>.>...#...###...#...#...#.......#...#.###...#.#...###...................###...#.#.....#.#...###.#.# +#######.#.#.#.###.###.#.#.#.#.#.###.#.#####v###.###.###.#.#.#.#.###.###########.###.#.#.#########################.#######.#.#####.#######.#.# +#.......#...#.....###.#.#.#.#.#...#.#.#.....###.....#...#...#...###.......#...#.#...#...#...###...................#...###...#...#.......#.#.# +#.###################.#.#.#.#.###.#.#.#.#############.###################.#.#.#.#.#######.#.###.###################.#.#######.#.#######.#.#.# +#...........#...#...#.#.#...#.#...#...#.........#...#.........#...###...#...#...#...#.....#...#...........#.....#...#...#...#.#.....#...#.#.# +###########.#.#.#.#.#.#.#####.#.###############.#.#.#########.#.#.###.#.###########.#.#######.###########.#.###.#.#####.#.#.#.#####.#.###.#.# +#...........#.#...#.#.#...#...#...#...#.........#.#.#.......#.#.#.#...#.###.....###...#.....#.#...........#.#...#.....#...#.#.....#...###...# +#.###########.#####.#.###.#.#####.#.#.#.#########.#.#.#####.#.#.#.#.###.###.###.#######.###.#.#.###########.#.#######.#####.#####.########### +#.#.........#.###...#.....#.......#.#.#.......#...#...#...#...#.#.#...#.#...#...#.......###...#.#.....#.....#.#...###...#...#.....#.....#...# +#.#.#######.#.###.#################.#.#######.#.#######.#.#####.#.###.#.#.###.###.#############.#.###.#.#####.#.#.#####.#.###.#####.###.#.#.# +#.#.#.......#.#...#.....#...#.....#.#.###.....#...#.....#...###.#.#...#.#...#.###.........#...#.#.#...#.#.....#.#.#...#.#.###.....#...#.#.#.# +#.#.#.#######.#.###.###.#.#.#.###.#.#.###v#######.#.#######.###.#.#.###.###.#.###########.#.#.#.#.#.###.#.#####.#.#.#.#.#.#######.###.#.#.#.# +#...#.......#.#.....#...#.#.#...#...#...>.>.#...#...#.......#...#.#.#...#...#.#.....#.....#.#.#.#.#...#.#.#...#.#.#.#.#.#.#...#...#...#.#.#.# +###########.#.#######.###.#.###.#########v#.#.#.#####.#######.###.#.#.###.###.#.###.#.#####.#.#.#.###.#.#.#.#.#.#.#.#.#.#.#.#.#v###.###.#.#.# +#...###...#...###...#...#.#...#...###.....#.#.#...#...###...#...#.#.#.###...#.#...#.#...###.#.#...#...#.#.#.#.#.#.#.#.#.#.#.#.>.###...#.#.#.# +#.#.###.#.#######.#.###.#.###.###.###.#####.#.###.#.#####.#.###.#.#.#.#####.#.###.#.###v###.#.#####v###.#.#.#.#.#.#.#.#.#.#.###v#####.#.#.#.# +#.#.....#.........#...#.#...#.....#...#...#...#...#...#...#...#.#.#.#...#...#...#.#...>.>...#.#...>.>...#...#...#.#.#.#.#.#.#...###...#...#.# +#.###################.#.###.#######.###.#.#####.#####v#.#####.#.#.#.###.#.#####.#.#####v#####.#.###v#############.#.#.#.#.#.#.#####.#######.# +#.....#.....#.......#...###.......#.....#.....#...#.>.>.#####...#...#...#...#...#.#.....#.....#...#...###.......#...#...#.#.#.....#.#.......# +#####.#.###.#.#####.#############.###########.###.#.#v###############.#####.#.###.#.#####.#######.###.###.#####.#########.#.#####.#.#.####### +#...#...###.#.###...###...#.......#...........###.#.#.#...###...#...#.......#.#...#.....#.#.....#...#...#.#.....#.........#.#...#.#.#...#...# +#.#.#######.#.###v#####.#.#.#######.#############.#.#.#.#.###.#.#.#.#########.#.#######.#.#.###.###.###.#.#.#####.#########.#.#.#.#.###.#.#.# +#.#...#...#...###.>...#.#.#...#...#.........#.....#.#.#.#.....#...#.........#.#.#...#...#...###...#.#...#.#.....#.........#.#.#...#.#...#.#.# +#.###.#.#.#######v###.#.#.###.#.#.#########.#.#####.#.#.###################.#.#.#.#.#.###########.#.#.###.#####.#########.#.#.#####.#.###.#.# +#.#...#.#.#...###...#.#.#.#...#.#.....#...#.#...#...#...#...............#...#...#.#.#.....#...###...#...#.#.....#.....#...#.#.....#.#.....#.# +#.#.###.#.#.#.#####.#.#.#.#.###.#####.#.#.#.###.#.#######.#############.#.#######.#.#####.#.#.#########.#.#.#####.###.#.###.#####.#.#######.# +#.#.....#.#.#.#.....#...#.#.###.#...#...#...###...#...###.............#...#...#...#...#...#.#.#.....###...#...#...#...#...#.#...#.#.#.......# +#.#######.#.#.#.#########.#.###.#.#.###############.#.###############.#####.#.#.#####.#.###.#.#.###.#########.#.###.#####.#.#.#.#.#.#.####### +#...#...#.#.#.#.......###...###...#.......###...#...#.#.....###.......###...#.#.#...#.#.###.#...#...#...#...#...#...#####...#.#.#...#.....### +###.#.#.#.#.#.#######.###################.###.#.#.###.#.###.###.#########.###.#.#.#.#.#.###.#####.###.#.#.#.#####.###########.#.#########.### +#...#.#.#...#.......#.....#...............#...#...#...#...#.#...#...#...#.#...#...#.#...#...#.....#...#.#.#.......#...#...#...#...#.....#...# +#.###.#.###########.#####.#.###############.#######.#####.#.#.###.#.#.#.#.#.#######.#####.###.#####.###.#.#########.#.#.#.#.#####.#.###.###.# +#.#...#...........#.......#...............#.......#.....#.#.#.....#.#.#.#.#.#.....#.#...#.#...#...#...#.#.........#.#.#.#.#...#...#...#.....# +#.#.#############.#######################.#######.#####.#.#.#######.#.#.#.#.#.###.#.#.#.#.#.###.#.###.#.#########v#.#.#.#.###.#.#####.####### +#.#.#...........#...#.....#...............#.....#.#.....#.#.###.....#.#.#.#.#.#...#.#.#.#.#.#...#.#...#...#...#.>.>.#.#.#.#...#.....#.......# +#.#.#.#########.###.#.###.#.###############.###.#.#.#####.#.###v#####.#.#.#.#.#.###v#.#.#.#.#.###.#.#####.#.#.#.#####.#.#.#.#######.#######.# +#.#.#.........#.....#.#...#...............#...#.#.#.#.....#.#.>.>.#...#.#.#...#.#.>.>.#.#.#.#.#...#.#.....#.#.#.#####.#.#.#...#.....#.......# +#.#.#########.#######.#.#################.###.#.#.#.#.#####.#.###.#.###.#.#####.#.#####.#.#.#.#.###.#.#####.#.#.#####.#.#.###.#.#####.####### +#...#.........#.......#...#...###...###...#...#...#.#.....#.#.#...#...#.#.#.....#.#...#...#...#...#.#.....#.#...#.....#.#.....#...###.......# +#####.#########.#########.#.#.###.#.###.###.#######.#####.#.#.#.#####.#.#.#.#####.#.#.###########.#.#####.#.#####.#####.#########.#########.# +#.....#.........###.......#.#.....#.....###.......#...#...#.#.#...#...#...#.....#...#...#...###...#.....#.#.....#.....#.###...###...#...#...# +#.#####.###########.#######.#####################.###.#.###.#.###.#.###########.#######.#.#.###.#######.#.#####.#####.#.###.#.#####.#.#.#v### +#.......#.........#.#...###.............###...#...#...#...#...#...#.......#.....#.....#...#...#.....#...#.......#.....#...#.#.......#.#.>.### +#########.#######.#.#.#.###############v###.#.#.###.#####.#####.#########.#.#####.###.#######.#####.#.###########.#######.#.#########.###v### +#.......#...#...#...#.#...#.....#...#.>.>.#.#.#...#.#...#.....#...#...#...#...#...###.#...#...###...#.#...........#...#...#...#...#...#...### +#.#####.###.#.#.#####.###.#.###.#.#.#.###.#.#.###.#.#.#.#####.###.#.#.#.#####.#.#####.#.#.#.#####.###.#.###########.#.#.#####.#.#.#.###.##### +#.....#.....#.#.#...#.###.#...#.#.#.#.###.#.#.#...#.#.#...#...#...#.#.#.###...#.....#.#.#.#.....#.#...#.#.....#...#.#.#.#.....#.#.#.###.....# +#####.#######.#.#.#.#.###.###.#.#.#.#.###.#.#.#.###.#.###.#.###.###.#.#.###.#######.#.#.#.#####.#.#.###.#.###.#.#.#.#.#.#.#####.#.#.#######.# +#.....#.....#.#.#.#.#.#...#...#.#.#.#...#.#.#.#.#...#...#.#...#...#.#.#.#...#...#...#.#.#.#...#.#.#...#.#.#...#.#.#.#.#.#...#...#.#.#.......# +#.#####.###.#.#.#.#.#.#.###.###.#.#.###.#.#.#.#.#.#####.#.###.###.#.#.#.#.###.#.#.###.#.#.#.#.#.#.###.#.#.#.###.#.#.#.#.###.#.###.#.#.####### +#.......###...#...#...#.....###...#.....#...#...#.......#.....###...#...#.....#...###...#...#...#.....#...#.....#...#...###...###...#.......# +###########################################################################################################################################.# diff --git a/examples/inputs/day23_test.txt b/examples/inputs/day23_test.txt new file mode 100644 index 0000000..65c7c3d --- /dev/null +++ b/examples/inputs/day23_test.txt @@ -0,0 +1,23 @@ +#.##################### +#.......#########...### +#######.#########.#.### +###.....#.>.>.###.#.### +###v#####.#v#.###.#.### +###.>...#.#.#.....#...# +###v###.#.#.#########.# +###...#.#.#.......#...# +#####.#.#.#######.#.### +#.....#.#.#.......#...# +#.#####.#.#.#########v# +#.#...#...#...###...>.# +#.#.#v#######v###.###v# +#...#.>.#...>.>.#.###.# +#####v#.#.###v#.#.###.# +#.....#...#...#.#.#...# +#.#########.###.#.#.### +#...###...#...#...#.### +###.###.#.###v#####v### +#...#...#.#.>.>.#.>.### +#.###.###.#.###.#.#v### +#.....###...###...#...# +#####################.# \ No newline at end of file