days 5 and 6

This commit is contained in:
Shoofle 2024-12-06 09:15:52 -05:00
parent 33b031c8da
commit 054ea0a2e3
2 changed files with 162 additions and 8 deletions

View File

@ -48,7 +48,8 @@ fn main() {
.filter(|p| pages.contains(p))
.collect();
let middle: i32 = *halfway(&true_pages).expect("error finding the halfway point");
let middle: i32 = true_pages.get((true_pages.len() - 1) / 2)
.expect("error finding the halfway point");
if iter::zip(pages.iter(), true_pages.iter()).all(|(a, b)| a==b) {
// it's good!
@ -62,9 +63,4 @@ fn main() {
println!("the sum of middle pages of good updates is {good_sum}");
println!("and the bad updates is {bad_sum}");
}
fn halfway<T>(v: &[T]) -> Option<&T> {
if v.len() == 0 { return None; }
return v.get((v.len() - 1) / 2)
}

View File

@ -1,3 +1,161 @@
fn main() {
println!("Hello, world!");
use std::collections::HashSet;
use std::collections::HashMap;
use std::fs;
use std::env;
use crate::Dir::{North, South, East, West};
// nodes are (coord, direction) pairs.
// neighbors are step1+turnleft, step2+turnleft, step3+turnleft, step1+turnright, etc
#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
enum Dir { North, South, East, West }
fn step(start: &Coord, d: Dir, steps: i32) -> Coord {
match d {
North => (start.0, start.1 - steps),
South => (start.0, start.1 + steps),
East => (start.0 + steps, start.1),
West => (start.0 - steps, start.1)
}
}
fn rotate_right(direction: Dir) -> Dir {
match direction {
North => East,
East => South,
South => West,
West => North
}
}
type Coord = (i32, i32);
fn main() {
println!("Hello, AoC day 06!");
let args: Vec<String> = env::args().collect();
if args.len() != 2 {
println!("wrong number of arguments!");
std::process::exit(1);
}
let file_path = &args[1];
let contents = fs::read_to_string(file_path).expect("Should have been able to read the file");
let mut grid: HashMap<Coord, char> = HashMap::new();
let mut guard_position = (0,0);
let mut x;
let mut y = 0;
// build our grid!
for line in contents.lines() {
x = 0;
for c in line.chars() {
if c == '^' {
guard_position = (x,y);
grid.insert((x,y), '.');
x += 1;
} else {
grid.insert((x,y), c);
x += 1;
}
}
y += 1;
}
if let Ok(count) = patrol(guard_position, &grid) {
println!("visited {count} locations!");
} else {
println!("found a loop!");
}
if let Ok(potential_loops) = patrol_and_count_potential_loops(guard_position, &grid) {
println!("there were {potential_loops} locations where we could make a loop.")
}
}
struct Looped;
fn patrol(start: Coord, lab: &HashMap<Coord, char>) -> Result<usize, Looped> {
let mut guard_position = start;
let mut guard_facing = North;
let mut visited: HashSet<Coord> = HashSet::new();
let mut conditions: HashSet<(Coord, Dir)> = HashSet::new();
loop {
visited.insert(guard_position);
if conditions.contains(&(guard_position, guard_facing)) {
return Err(Looped);
}
conditions.insert((guard_position, guard_facing));
let next = step(&guard_position, guard_facing, 1);
match lab.get(&next) {
Some('.') => guard_position = next,
Some('#') => guard_facing = rotate_right(guard_facing),
Some(_) => panic!("encountered an unexpected character!"),
None => break,
}
}
return Ok(visited.len());
}
fn patrol_and_count_potential_loops(start: Coord, lab: &HashMap<Coord, char>) -> Result<usize, Looped> {
let mut guard_position = start;
let mut guard_facing = North;
let mut candidates: HashSet<Coord> = HashSet::new();
let mut conditions: HashSet<(Coord, Dir)> = HashSet::new();
loop {
if conditions.contains(&(guard_position, guard_facing)) {
return Err(Looped);
}
conditions.insert((guard_position, guard_facing));
let next = step(&guard_position, guard_facing, 1);
if obstacle_to_the_right(guard_position, guard_facing, lab) {
candidates.insert(next);
}
match lab.get(&next) {
Some('.') => guard_position = next,
Some('#') => guard_facing = rotate_right(guard_facing),
Some(_) => panic!("encountered an unexpected character!"),
None => break,
}
}
let mut loop_spots: HashSet<Coord> = HashSet::new();
for candidate_location in candidates {
let mut dream_lab = lab.clone();
if dream_lab.get(&candidate_location) != Some(&'.') {
continue;
}
dream_lab.insert(candidate_location, '#');
if let Ok(_) = patrol(start, &dream_lab){
continue;
}
loop_spots.insert(candidate_location);
}
return Ok(loop_spots.len());
}
fn obstacle_to_the_right(start: Coord, facing: Dir, lab: &HashMap<Coord, char>) -> bool {
let direction = rotate_right(facing);
let mut position = start;
while let Some(next) = lab.get(&position) {
if *next == '.' {
position = step(&position, direction, 1);
} else if *next == '#' {
return true;
}
}
return false;
}