aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--2022/25/a.rs13
-rw-r--r--2022/25/common.rs72
2 files changed, 85 insertions, 0 deletions
diff --git a/2022/25/a.rs b/2022/25/a.rs
new file mode 100644
index 0000000..1d7e62b
--- /dev/null
+++ b/2022/25/a.rs
@@ -0,0 +1,13 @@
1mod common;
2use common::*;
3
4fn main() {
5 let mut line = String::new();
6 let mut sum = Snafu::zero();
7 while std::io::stdin().read_line(&mut line).unwrap() > 0 {
8 let s = Snafu::from_str(&line[..line.len()-1]);
9 sum += &s;
10 line.clear();
11 }
12 println!("{sum}");
13}
diff --git a/2022/25/common.rs b/2022/25/common.rs
new file mode 100644
index 0000000..de86470
--- /dev/null
+++ b/2022/25/common.rs
@@ -0,0 +1,72 @@
1use std::fmt;
2use std::ops;
3use std::cmp;
4
5pub struct Snafu {
6 d: Vec<i8>
7}
8
9impl Snafu {
10 const DIGITS: [char; 5] = ['=', '-', '0', '1', '2'];
11
12 fn digit_to_i8(c: char) -> i8 {
13 for i in 0..5 {
14 if c == Snafu::DIGITS[i] { return i as i8 - 2; }
15 }
16 panic!("Invalid Snafu digit '{}'", c);
17 }
18
19 fn i8_to_digit(i: i8) -> char {
20 if i < -2 || i > 2 {
21 panic!("Invalid Snafu digit value {}", i);
22 }
23 Snafu::DIGITS[(i + 2) as usize]
24 }
25
26 pub fn ndigits(&self) -> usize {
27 self.d.len()
28 }
29
30 pub fn zero() -> Snafu {
31 Snafu { d: vec![0] }
32 }
33
34 pub fn from_str(s: &str) -> Snafu {
35 let mut d = vec![];
36 for c in s.chars() { d.push(Self::digit_to_i8(c)); }
37 d.reverse();
38 Snafu { d }
39 }
40}
41
42impl fmt::Display for Snafu {
43 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
44 // Strip leading zeros
45 let mut n = self.ndigits()-1;
46 while self.d[n] == 0 { n -= 1; }
47
48 for i in (0..=n).rev() {
49 write!(f, "{}", Self::i8_to_digit(self.d[i]))?;
50 }
51 Ok(())
52 }
53}
54
55impl ops::AddAssign<&Snafu> for Snafu {
56 fn add_assign(&mut self, other: &Snafu) {
57 for i in 0..cmp::max(self.ndigits(), other.ndigits()) {
58 if i < other.ndigits() {
59 self.d[i] += other.d[i];
60 }
61
62 // Carry over, both ways
63 if i == self.ndigits()-1 { self.d.push(0); }
64 while self.d[i] > 2 { self.d[i+1] += 1; self.d[i] -= 5; }
65 while self.d[i] < -2 { self.d[i+1] -= 1; self.d[i] += 5; }
66 }
67
68 for i in 0..self.ndigits() {
69 if self.d[i] == 0 { self.d.pop(); } else { break; }
70 }
71 }
72}

Generated with cgit - Back to sebastiano.tronto.net