-
Notifications
You must be signed in to change notification settings - Fork 1
/
day15.rs
89 lines (79 loc) · 2.26 KB
/
day15.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
use std::mem;
fn hash(s: &str) -> u8 {
let mut acc: u8 = 0;
for b in s.bytes() {
acc = acc.wrapping_add(b);
acc = acc.wrapping_mul(17);
}
acc
}
fn part1(input: String) {
let hash_sum: u32 = input.split([',', '\n'])
.map(|s| hash(s) as u32).sum();
println!("{hash_sum}");
}
struct HashMap {
table: [Vec<HashEntry>; 256],
}
impl HashMap {
fn new() -> Self {
// Some dark magic shenanigans to initialize an array of empty Vec's
let mut table: [mem::MaybeUninit<Vec<HashEntry>>; 256] = unsafe {
mem::MaybeUninit::uninit().assume_init()
};
for b in &mut table[..] {
b.write(Vec::new());
}
let table = unsafe { mem::transmute::<_, [Vec<HashEntry>; 256]>(table) };
HashMap {
table,
}
}
fn insert(&mut self, key: String, val: u8) {
let h = hash(&key);
let bucket = &mut self.table[h as usize];
if let Some(entry) = bucket.iter_mut().find(|entry| entry.label == key) {
entry.num = val;
} else {
bucket.push(HashEntry {
label: key,
num: val,
});
}
}
fn remove(&mut self, key: &str) {
let h = hash(key);
let bucket = &mut self.table[h as usize];
if let Some(idx) = bucket.iter().position(|entry| entry.label == key) {
bucket.remove(idx);
}
}
fn power(&self) -> u32 {
self.table.iter().enumerate()
.map(|(i, bucket)|
bucket.iter().enumerate()
.map(|(j, entry)| (i + 1) * (j + 1) * entry.num as usize)
.sum::<usize>()
)
.sum::<usize>()
as u32
}
}
struct HashEntry {
label: String,
num: u8,
}
fn part2(input: String) {
let mut hashmap = HashMap::new();
for step in input.split([',', '\n']) {
if step.is_empty() { continue }
if let Some((label, num)) = step.split_once('=') {
hashmap.insert(label.to_string(), num.parse().unwrap());
} else {
assert!(step.ends_with('-'));
hashmap.remove(&step[..step.len() - 1]);
}
}
println!("{}", hashmap.power());
}
util::aoc_main!("day15.txt");