days 5 and 6
This commit is contained in:
parent
33b031c8da
commit
054ea0a2e3
@ -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!
|
||||
@ -63,8 +64,3 @@ 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)
|
||||
}
|
@ -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;
|
||||
}
|
Loading…
Reference in New Issue
Block a user