Skip to content

Commit

Permalink
finish day 12
Browse files Browse the repository at this point in the history
  • Loading branch information
mflinn-broad committed Dec 12, 2021
1 parent 94d8d1d commit 8a68bb1
Show file tree
Hide file tree
Showing 6 changed files with 210 additions and 18 deletions.
39 changes: 39 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,4 @@ edition = "2021"

[dependencies]
itertools = "0.10.3"
petgraph = "0.6.0"
36 changes: 18 additions & 18 deletions src/days/day11.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ struct Octopus {

struct Position {
row: usize,
col: usize
col: usize,
}

impl Octopus {
Expand All @@ -36,28 +36,28 @@ fn get_adjacent_octopi(pos: Position, grid: &Vec<Vec<Octopus>>) -> Vec<Position>
if pos.row != 0 {
let position = Position {
row: pos.row - 1,
col: pos.col
col: pos.col,
};
adjacents.push(position);
}
if pos.col != 0 {
let position = Position {
row: pos.row,
col: pos.col - 1
col: pos.col - 1,
};
adjacents.push(position);
}
if pos.row != (grid.len() - 1) {
let position = Position {
row: pos.row + 1,
col: pos.col
col: pos.col,
};
adjacents.push(position);
}
if pos.col != (grid[0].len() - 1) {
let position = Position {
row: pos.row,
col: pos.col + 1
col: pos.col + 1,
};
adjacents.push(position);
}
Expand Down Expand Up @@ -100,19 +100,18 @@ fn propagate_flash(pos: Position, grid: &mut Vec<Vec<Octopus>>) {
let mut flash_stack: Vec<Position> = vec![pos];
while let Some(flash_pos) = flash_stack.pop() {
let adjacents = get_adjacent_octopi(flash_pos, &grid);
adjacents.iter()
.for_each(|adjacent| {
if !grid[adjacent.row][adjacent.col].flashed_on_step {
grid[adjacent.row][adjacent.col].increase();
if grid[adjacent.row][adjacent.col].e_level > 9 {
grid[adjacent.row][adjacent.col].flashed_on_step = true;
flash_stack.push(Position {
row: adjacent.row,
col: adjacent.col,
});
}
adjacents.iter().for_each(|adjacent| {
if !grid[adjacent.row][adjacent.col].flashed_on_step {
grid[adjacent.row][adjacent.col].increase();
if grid[adjacent.row][adjacent.col].e_level > 9 {
grid[adjacent.row][adjacent.col].flashed_on_step = true;
flash_stack.push(Position {
row: adjacent.row,
col: adjacent.col,
});
}
})
}
})
}
}

Expand Down Expand Up @@ -182,7 +181,8 @@ fn part_2(input: Vec<Vec<Octopus>>) -> usize {
}

fn process(input: &str) -> Vec<Vec<Octopus>> {
input.lines()
input
.lines()
.map(|line| {
line.chars()
.map(|ch| {
Expand Down
144 changes: 144 additions & 0 deletions src/days/day12.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
use crate::util;
use petgraph::graphmap::UnGraphMap;
use std::collections::HashSet;

pub fn run() {
let raw_input = util::read_input("inputs/day12.txt").unwrap();
let input = process(&raw_input);

println!("Part 1: {}", part_1(&input));
println!("Part 2: {}", part_2(&input));
}

fn process(input: &str) -> Vec<(&str, &str)> {
input
.lines()
.map(|line| line.trim().split_once("-").unwrap())
.collect()
}

fn part_1(input: &Vec<(&str, &str)>) -> usize {
let cave_map = UnGraphMap::<&str, ()>::from_edges(input);
let mut visit_tracker: HashSet<&str> = HashSet::new();
visit_tracker.insert("start");

count_simple_paths(&cave_map, "start", &mut visit_tracker)
}

fn part_2(input: &Vec<(&str, &str)>) -> usize {
let cave_map = UnGraphMap::<&str, ()>::from_edges(input);
let mut visit_tracker: HashSet<&str> = HashSet::new();
visit_tracker.insert("start");

count_paths_v2(&cave_map, "start", &mut visit_tracker, &mut None)
}

fn is_small_cave(cave: &str) -> bool {
cave.chars().all(|c| c.is_lowercase())
}

fn is_start(cave: &str) -> bool {
cave == "start"
}

fn is_end(cave: &str) -> bool {
cave == "end"
}

fn count_simple_paths<'a>(
cave_system: &UnGraphMap<&'a str, ()>,
curr_node: &'a str,
visited_small_caves: &mut HashSet<&'a str>,
) -> usize {
if curr_node == "end" {
visited_small_caves.remove(curr_node);
return 1;
}

let mut count = 0;

for connected_cave in cave_system.neighbors(curr_node) {
if is_small_cave(connected_cave) {
if visited_small_caves.contains(connected_cave) {
continue;
} else {
visited_small_caves.insert(connected_cave);
}
}
count += count_simple_paths(&cave_system, connected_cave, visited_small_caves);
visited_small_caves.remove(connected_cave);
}
count
}

fn count_paths_v2<'a>(
cave_system: &UnGraphMap<&'a str, ()>,
curr_node: &'a str,
visited_small_caves: &mut HashSet<&'a str>,
twive_visited_cave: &mut Option<&'a str>,
) -> usize {
if is_end(curr_node) {
visited_small_caves.remove(curr_node);
return 1;
}

let mut count = 0;
for connected_cave in cave_system.neighbors(curr_node) {
if is_small_cave(connected_cave) {
if !visited_small_caves.contains(connected_cave) {
visited_small_caves.insert(connected_cave);
} else if twive_visited_cave.is_none()
&& !is_start(connected_cave)
&& !is_end(connected_cave)
{
*twive_visited_cave = Some(connected_cave);
} else {
continue;
}
}

if let Some(_) = twive_visited_cave {
count += count_simple_paths(cave_system, connected_cave, visited_small_caves);
} else {
count += count_paths_v2(
cave_system,
connected_cave,
visited_small_caves,
twive_visited_cave,
);
}

if *twive_visited_cave == Some(connected_cave) {
*twive_visited_cave = None;
} else {
visited_small_caves.remove(connected_cave);
}
}

count
}

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

#[bench]
fn bench_part_1(b: &mut Bencher) {
let raw_input = util::read_input("inputs/day12.txt").unwrap();
b.iter(|| {
let input = process(&raw_input);
part_1(&input);
});
}

#[bench]
fn bench_part_2(b: &mut Bencher) {
let raw_input = util::read_input("inputs/day12.txt").unwrap();
b.iter(|| {
let input = process(&raw_input);
part_2(&input);
});
}
}
1 change: 1 addition & 0 deletions src/days/mod.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
pub mod day1;
pub mod day10;
pub mod day11;
pub mod day12;
pub mod day2;
pub mod day3;
pub mod day4;
Expand Down
7 changes: 7 additions & 0 deletions src/main.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
use advent_2021::days::*;
use std::time::{Duration, Instant};

fn main() {
let start = Instant::now();
println!("Day 1 --------");
day1::run();
println!("Day 2 --------");
Expand All @@ -23,4 +25,9 @@ fn main() {
day10::run();
println!("Day 11 ---------");
day11::run();
println!("Day 12 ---------");
day12::run();
let duration = start.elapsed();

println!("Total time to run all solutions: {:?}", duration);
}

0 comments on commit 8a68bb1

Please sign in to comment.