main.rs (1794B)
1 fn main() {
2 let input = std::fs::read_to_string("input.txt")
3 .unwrap()
4 .trim()
5 .split('\n')
6 .map(|s| s.to_string())
7 .collect::<Vec<String>>();
8 // 2==0=0===02--210---1
9 println!("Part 1: {}", part_1(&input));
10 }
11
12 fn snafu_to_decimal(s: &str) -> i64 {
13 let mut res = 0;
14 let mut pow = 1;
15 for c in s.chars().rev() {
16 res += pow
17 * match c {
18 '2' => 2,
19 '1' => 1,
20 '0' => 0,
21 '-' => -1,
22 '=' => -2,
23 _ => unreachable!(),
24 };
25 pow *= 5;
26 }
27 res
28 }
29
30 fn decimal_to_snafu(x: i64) -> String {
31 // assume positive number
32 let mut pow = 1;
33 while pow * 5 < x {
34 pow *= 5;
35 }
36 let mut res = x;
37 let mut digits_5 = Vec::new();
38 while pow > 0 {
39 let d = res / pow;
40 digits_5.push(d);
41 res -= d * pow;
42 pow /= 5;
43 }
44
45 let mut digits_snafu = Vec::new();
46 let mut carry = 0;
47 for mut d in digits_5.into_iter().rev() {
48 d += carry;
49 match d {
50 0 | 1 | 2 => {
51 carry = 0;
52 }
53 3 | 4 | 5 => {
54 d = d - 5;
55 carry = 1;
56 }
57 _ => unreachable!(),
58 }
59 digits_snafu.insert(0, d);
60 }
61 if carry != 0 {
62 digits_snafu.insert(0, carry);
63 }
64 digits_snafu
65 .into_iter()
66 .map(|d| match d {
67 2 => '2',
68 1 => '1',
69 0 => '0',
70 -1 => '-',
71 -2 => '=',
72 _ => unreachable!(),
73 })
74 .collect()
75 }
76
77 fn part_1(input: &Vec<String>) -> String {
78 let sum = input.iter().map(|s| snafu_to_decimal(s)).sum::<i64>();
79 decimal_to_snafu(sum)
80 }