-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy path25.rs
81 lines (71 loc) · 1.62 KB
/
25.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
#![feature(test)]
type Input = Vec<String>;
fn setup(input: &str) -> Input {
input.lines().map(Into::into).collect()
}
fn part1(input: &Input) -> String {
to_snafu(input.iter().map(|snafu| from_snafu(snafu)).sum())
}
fn from_snafu(snafu: &str) -> u64 {
snafu.bytes().fold(0, |acc, c| {
let digit = match c {
b'=' => 0,
b'-' => 1,
b'0' => 2,
b'1' => 3,
b'2' => 4,
_ => panic!("invalid snafu number"),
};
acc * 5 + digit - 2
})
}
fn to_snafu(mut num: u64) -> String {
let mut out = Vec::with_capacity(32);
while num > 0 {
num += 2;
out.push(match num % 5 {
0 => '=',
1 => '-',
2 => '0',
3 => '1',
4 => '2',
_ => unreachable!(),
});
num /= 5;
}
out.into_iter().rev().collect()
}
#[cfg(test)]
mod tests {
use super::*;
macro_rules! tests {
($($dec:literal, $snafu:literal,)*) => {
#[test]
fn test_from_snafu() {
$(assert_eq!(from_snafu($snafu), $dec);)*
}
#[test]
fn test_to_snafu() {
$(assert_eq!(to_snafu($dec), $snafu, concat!($dec));)*
}
};
}
tests! {
1, "1",
2, "2",
3, "1=",
4, "1-",
5, "10",
6, "11",
7, "12",
8, "2=",
9, "2-",
10, "20",
15, "1=0",
20, "1-0",
2022, "1=11-2",
12345, "1-0---0",
314159265, "1121-1110-1=0",
}
}
aoc::main!(2022, 25, ex: 1);