From 9637b5a1f8d10e3003651c5d9006f0e102f74f18 Mon Sep 17 00:00:00 2001 From: Sebastiano Tronto Date: Wed, 9 Jul 2025 10:23:07 +0200 Subject: Day 23 2022 --- 2022/23/common.rs | 83 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 83 insertions(+) create mode 100644 2022/23/common.rs (limited to '2022/23/common.rs') diff --git a/2022/23/common.rs b/2022/23/common.rs new file mode 100644 index 0000000..3cf974b --- /dev/null +++ b/2022/23/common.rs @@ -0,0 +1,83 @@ +use std::collections::{HashMap, HashSet}; + +const DIRECTIONS: [[(i64, i64); 3]; 4] = [ + [(-1, 0), (-1, 1), (-1, -1)], + [(1, 0), (1, 1), (1, -1)], + [(0, -1), (1, -1), (-1, -1)], + [(0, 1), (1, 1), (-1, 1)] +]; + +pub fn read_from_stdin() -> (Vec<(i64, i64)>, HashMap<(i64, i64), usize>) { + let mut v = vec![]; + let mut lookup = HashMap::new(); + let mut line = String::new(); + let mut i = 0; + while std::io::stdin().read_line(&mut line).unwrap() > 0 { + let bytes = line.as_bytes(); + for j in 0..bytes.len() { + if bytes[j] == b'#' { + lookup.insert((i, j as i64), v.len()); + v.push((i, j as i64)); + } + } + i += 1; + line.clear(); + } + (v, lookup) +} + +pub fn free_around(e: (i64, i64), m: &HashMap<(i64, i64), usize>) -> bool { + for d in [ + (-1, -1), (-1, 0), (-1, 1), + ( 0, -1), ( 0, 1), + ( 1, -1), ( 1, 0), ( 1, 1) + ] { + if m.contains_key(&(e.0 + d.0, e.1 + d.1)) { return false; } + } + true +} + +pub fn play( + elves: &mut Vec<(i64, i64)>, + lookup: &mut HashMap<(i64, i64), usize>, + nturns: usize +) -> Option { + let mut claimed = HashMap::<(i64, i64), usize>::new(); + let mut stopped = HashSet::<(i64, i64)>::new(); + for t in 0..nturns { + // First half + for i in 0..elves.len() { + let e = elves[i]; + if free_around(e, &lookup) { continue; } + for j in 0..4 { + let d = DIRECTIONS[(t+j)%4].iter() + .map(|x| (e.0+x.0, e.1+x.1)) + .collect::>(); + if !lookup.contains_key(&d[0]) && + !lookup.contains_key(&d[1]) && + !lookup.contains_key(&d[2]) + { + if claimed.contains_key(&d[0]) { stopped.insert(d[0]); } + claimed.insert(d[0], i); + break; + } + } + } + + // Second half + let mut any_moved = false; + for (moveto, i) in &claimed { + if stopped.contains(&moveto) { continue; } + any_moved = true; + lookup.remove(&elves[*i]); + elves[*i] = *moveto; + lookup.insert(elves[*i], *i); + } + if !any_moved { return Some(t); } + + // Cleanup + claimed.clear(); + stopped.clear(); + } + None +} -- cgit v1.3