This commit is contained in:
Spectre 2024-12-07 02:21:54 +01:00
parent da9781026a
commit 290d9a5cb0

View file

@ -1,13 +1,95 @@
use std::{collections::HashSet, isize};
use itertools::Itertools;
use shared::{Solution, Answer};
pub struct Day06;
impl Solution for Day06 {
fn part_1(&self, input: &str) -> Answer {
Answer::Unimplemented
let line = input.find("\n").unwrap() as isize;
let (map, mut guard) = parse(input);
let mut facings = [-line, 1, line, -1].into_iter().cycle().peekable();
let mut seen = HashSet::new();
while let Some(&obstacle) = map.get((guard + facings.peek().unwrap()) as usize) {
seen.insert(guard);
if obstacle { facings.next(); }
else { guard += facings.peek().unwrap(); }
};
seen.insert(guard);
Answer::Number(seen.len() as u64)
}
fn part_2(&self, input: &str) -> Answer {
Answer::Unimplemented
let line = input.find("\n").unwrap() as isize;
let (map, mut guard) = parse(input);
let start = guard;
let mut facings = [-line, 1, line, -1].into_iter().cycle().peekable();
let mut seen: HashSet<isize> = HashSet::new();
while let Some(&obstacle) = map.get((guard + facings.peek().unwrap()) as usize) {
seen.insert(guard);
if obstacle { facings.next(); }
else { guard += facings.peek().unwrap(); }
};
seen.insert(guard);
let mut loops = 0;
for i in seen.iter() {
let mut new_map = map.clone();
if new_map[*i as usize] {break;} else {new_map[*i as usize] = true;}
let mut new_guard = start;
let mut new_facings = [-line, 1, line, -1].into_iter().cycle().peekable();
let mut new_seen: HashSet<(isize, isize)> = HashSet::new();
while let Some(&obstacle) = new_map.get((new_guard + new_facings.peek().unwrap()) as usize) {
// wraparound protection
if new_facings.peek().unwrap().abs() == 1 && new_guard / line != (new_guard + new_facings.peek().unwrap()) / line { break; }
if new_seen.contains(&(new_guard, *new_facings.peek().unwrap())) {
// debug_print(&new_map, &new_seen, line, Some(*i));
loops += 1;
println!("{loops}");
break
}
new_seen.insert((new_guard, *new_facings.peek().unwrap()));
if obstacle { new_facings.next(); }
else { new_guard += new_facings.peek().unwrap(); }
};
}
Answer::Number(loops)
}
}
fn debug_print(map: &[bool], seen: &HashSet<(isize, isize)>, line: isize, new: Option<isize>) {
let path = seen.iter().collect_vec();
let mut out = map.iter().map(|&x| if x {"#"} else {"."}).join("");
for &(i, c) in path {
if out[i as usize..=i as usize] == *"." {
out.replace_range(i as usize..=i as usize, if c.abs() == 1 {"-"} else {"|"});
} else {
out.replace_range(i as usize..=i as usize, "+");
}
}
if let Some(x) = new { out.replace_range(x as usize..=x as usize, "O"); }
for mut chunk in out.chars().chunks(line as usize).into_iter() {
println!("{}", chunk.join(""))
}
}
fn parse(input: &str) -> (Vec<bool>, isize) {
let flat = input.trim().replace("\n", "");
let guard = flat.find("^").unwrap();
let map = flat.chars().map(|c| c == '#').collect_vec();
(map, guard as isize)
}