day06
This commit is contained in:
parent
da9781026a
commit
290d9a5cb0
1 changed files with 84 additions and 2 deletions
|
|
@ -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)
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue