days 5 and 6
This commit is contained in:
parent
33b031c8da
commit
054ea0a2e3
@ -48,7 +48,8 @@ fn main() {
|
|||||||
.filter(|p| pages.contains(p))
|
.filter(|p| pages.contains(p))
|
||||||
.collect();
|
.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) {
|
if iter::zip(pages.iter(), true_pages.iter()).all(|(a, b)| a==b) {
|
||||||
// it's good!
|
// it's good!
|
||||||
@ -63,8 +64,3 @@ fn main() {
|
|||||||
println!("the sum of middle pages of good updates is {good_sum}");
|
println!("the sum of middle pages of good updates is {good_sum}");
|
||||||
println!("and the bad updates is {bad_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() {
|
use std::collections::HashSet;
|
||||||
println!("Hello, world!");
|
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