-
-
Notifications
You must be signed in to change notification settings - Fork 18
/
main.rs
73 lines (67 loc) · 1.87 KB
/
main.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
/// Snailfish sequence: `[(depth, n)]`
type Num = Vec<(u8, u8)>;
pub fn main() {
let mut nums = include_str!("../input.txt")
.trim()
.as_bytes()
.split(|&b| b == b'\n')
.map(|b| {
b.iter()
.fold((0, Vec::with_capacity(b.len() / 2)), |(mut d, mut n), b| {
match b {
b'[' => d += 1,
b']' => d -= 1,
b'0'..=b'9' => n.push((d, b - b'0')),
_ => {}
}
(d, n)
})
.1
})
.collect::<Vec<_>>();
while nums.len() > 1 {
let mut other = nums.remove(1);
let sf = &mut nums[0];
add(sf, &mut other);
reduce(sf, 0);
}
println!("{}", mag(&mut 0, 1, &nums[0]));
}
fn add(nums: &mut Num, other: &mut Num) {
nums.append(other);
nums.iter_mut().for_each(|(d, _)| *d += 1);
}
fn reduce(nums: &mut Num, i: usize) {
for i in i..nums.len() - 1 {
if nums[i].0 == 5 {
let (l, r) = (nums[i].1, nums[i + 1].1);
nums[i] = (4, 0);
nums.remove(i + 1);
let _ = nums.get_mut(i.overflowing_sub(1).0).map(|n| n.1 += l);
let _ = nums.get_mut(i + 1).map(|n| n.1 += r);
return reduce(nums, i);
}
}
for i in 0..nums.len() {
let (d, n) = nums[i];
if n >= 10 {
nums[i] = (d + 1, n / 2);
nums.insert(i + 1, (d + 1, (n + 1) / 2));
return reduce(nums, i);
}
}
}
#[inline]
fn mag(i: &mut usize, depth: u8, sf: &Num) -> u16 {
3 * if sf[*i].0 == depth {
*i += 1;
sf[*i - 1].1 as u16
} else {
mag(i, depth + 1, sf)
} + 2 * if sf[*i].0 == depth {
*i += 1;
sf[*i - 1].1 as u16
} else {
mag(i, depth + 1, sf)
}
}