aboutsummaryrefslogtreecommitdiff
path: root/2022/23/common.rs
diff options
context:
space:
mode:
authorSebastiano Tronto <sebastiano@tronto.net>2025-07-09 10:23:07 +0200
committerSebastiano Tronto <sebastiano@tronto.net>2025-07-09 10:23:07 +0200
commit9637b5a1f8d10e3003651c5d9006f0e102f74f18 (patch)
treeb9b532c6744f1dd1c4359783ab41f37768c81269 /2022/23/common.rs
parentdbb5a4e5711fba371fbb011356bcd8a28cc963e4 (diff)
downloadaoc-9637b5a1f8d10e3003651c5d9006f0e102f74f18.tar.gz
aoc-9637b5a1f8d10e3003651c5d9006f0e102f74f18.zip
Day 23 2022
Diffstat (limited to '2022/23/common.rs')
-rw-r--r--2022/23/common.rs83
1 files changed, 83 insertions, 0 deletions
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 @@
1use std::collections::{HashMap, HashSet};
2
3const DIRECTIONS: [[(i64, i64); 3]; 4] = [
4 [(-1, 0), (-1, 1), (-1, -1)],
5 [(1, 0), (1, 1), (1, -1)],
6 [(0, -1), (1, -1), (-1, -1)],
7 [(0, 1), (1, 1), (-1, 1)]
8];
9
10pub fn read_from_stdin() -> (Vec<(i64, i64)>, HashMap<(i64, i64), usize>) {
11 let mut v = vec![];
12 let mut lookup = HashMap::new();
13 let mut line = String::new();
14 let mut i = 0;
15 while std::io::stdin().read_line(&mut line).unwrap() > 0 {
16 let bytes = line.as_bytes();
17 for j in 0..bytes.len() {
18 if bytes[j] == b'#' {
19 lookup.insert((i, j as i64), v.len());
20 v.push((i, j as i64));
21 }
22 }
23 i += 1;
24 line.clear();
25 }
26 (v, lookup)
27}
28
29pub fn free_around(e: (i64, i64), m: &HashMap<(i64, i64), usize>) -> bool {
30 for d in [
31 (-1, -1), (-1, 0), (-1, 1),
32 ( 0, -1), ( 0, 1),
33 ( 1, -1), ( 1, 0), ( 1, 1)
34 ] {
35 if m.contains_key(&(e.0 + d.0, e.1 + d.1)) { return false; }
36 }
37 true
38}
39
40pub fn play(
41 elves: &mut Vec<(i64, i64)>,
42 lookup: &mut HashMap<(i64, i64), usize>,
43 nturns: usize
44) -> Option<usize> {
45 let mut claimed = HashMap::<(i64, i64), usize>::new();
46 let mut stopped = HashSet::<(i64, i64)>::new();
47 for t in 0..nturns {
48 // First half
49 for i in 0..elves.len() {
50 let e = elves[i];
51 if free_around(e, &lookup) { continue; }
52 for j in 0..4 {
53 let d = DIRECTIONS[(t+j)%4].iter()
54 .map(|x| (e.0+x.0, e.1+x.1))
55 .collect::<Vec<_>>();
56 if !lookup.contains_key(&d[0]) &&
57 !lookup.contains_key(&d[1]) &&
58 !lookup.contains_key(&d[2])
59 {
60 if claimed.contains_key(&d[0]) { stopped.insert(d[0]); }
61 claimed.insert(d[0], i);
62 break;
63 }
64 }
65 }
66
67 // Second half
68 let mut any_moved = false;
69 for (moveto, i) in &claimed {
70 if stopped.contains(&moveto) { continue; }
71 any_moved = true;
72 lookup.remove(&elves[*i]);
73 elves[*i] = *moveto;
74 lookup.insert(elves[*i], *i);
75 }
76 if !any_moved { return Some(t); }
77
78 // Cleanup
79 claimed.clear();
80 stopped.clear();
81 }
82 None
83}

Generated with cgit - Back to sebastiano.tronto.net