Skip to content

Commit 24d9c46

Browse files
committed
Day 25. I'm a happy elf now.
1 parent 7d0de0d commit 24d9c46

File tree

2 files changed

+332
-0
lines changed

2 files changed

+332
-0
lines changed

input/day25.txt

+124
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
21-0==1=-0
2+
102211-220011-----
3+
1=2=111=10=-
4+
12-2=022=2
5+
1=--=11
6+
12-2211000=0011-0-
7+
1=1-
8+
2=0-10-=21-2
9+
1210-
10+
2=1-=
11+
1=0=12=2112--11=
12+
2--211=200
13+
20-02-20
14+
12=12=0=0=1
15+
22===21=-0102-012=
16+
1--=-121
17+
1=02=2-=
18+
12-0-20
19+
2=---=0102--00=22
20+
1=2==0=2=
21+
11-1112
22+
2--012
23+
12=12=--212-0-==-02
24+
1=220
25+
20===1
26+
2210-02=12-022-=1-
27+
22--1-==1
28+
211-1=1=0-==1
29+
10
30+
1-1-02
31+
1=-2==-0=21
32+
1=102
33+
20121021
34+
1=2=22=001200-==1020
35+
10211-1-20--10-1=
36+
1222==1--=1--11-=
37+
11211211
38+
1=101-20=
39+
1=1-11=0=000
40+
1=-=101
41+
2
42+
1000-2
43+
1==0=210=1=21222-=2
44+
1=1==2-
45+
2--020=2=2===-
46+
2-
47+
2=0
48+
222101=22=-21=11
49+
2=
50+
121201-0-20-2-=11=
51+
10=
52+
1212=20=2=-=-1--1
53+
2-20-=212=01
54+
1=1--00--0=12=-00
55+
22--
56+
22
57+
22===1=-0-22-
58+
111-=
59+
2-111=0021=2
60+
200=22-=12-2=
61+
1==-=1=0
62+
1--=02-0002=
63+
1=-=2-2=2-
64+
2=2222220=2==001
65+
1=00==11=-20-=2-2
66+
1---0=-=
67+
1-0==10-=22001
68+
1=02=02-1=0111
69+
1-=010-21-=21==02
70+
10200-2=-=20120-2
71+
1=-
72+
10=122-
73+
210-1=-=2011-0--1
74+
2==-1=20
75+
1=-=101-20=221-1
76+
210
77+
1-=-==-0-=02=---
78+
1-=1=-=12=0
79+
1-=0---12-0=
80+
210-==1021=010=1
81+
1=-212
82+
11=1=-=2211=101222-
83+
2=-==--=2
84+
1=11-200--=
85+
1120-
86+
11=-0=221=0101=
87+
11-1=-
88+
1-12-2=0
89+
1012-22=1-
90+
20-122=-1=
91+
1-100=0=101-0
92+
20-1=1=0
93+
1102=
94+
21
95+
10=20=11
96+
1-=2001
97+
1-20=12-0221102-==
98+
1-1--010100=-1=
99+
221002==2102-2=1
100+
2012=121-22
101+
110222002=01
102+
212102-1=1=-211
103+
210-=12
104+
1=-1-0101=1-12
105+
12--21=1
106+
10=-12
107+
100-122211=--2=
108+
101102001
109+
11011=-
110+
211-0=-=0
111+
1-2=01-1=
112+
1-022-=00000
113+
2==-0==2=--00=
114+
10=--2000==
115+
1---=--1-110-02
116+
11-012
117+
2==-2210-0
118+
212
119+
22-=-12111
120+
2--=
121+
2=2=12-100
122+
10-12===0-
123+
1==0=0=22012201
124+
211-1--22

src/bin/day25.rs

+208
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,208 @@
1+
use std::{
2+
fs::File,
3+
io::{BufReader, BufRead},
4+
ops::Add, fmt::Display,
5+
};
6+
7+
const SNAFU_BASE: isize = 5;
8+
9+
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Default, Clone, Copy)]
10+
enum SnafuDigit {
11+
DoubleMinus = -2,
12+
Minus = -1,
13+
#[default]
14+
Zero = 0,
15+
One = 1,
16+
Two = 2,
17+
}
18+
19+
impl Add<Self> for SnafuDigit {
20+
type Output = Snafu;
21+
fn add(self, rhs: Self) -> Self::Output {
22+
match (self, rhs) {
23+
(Self::DoubleMinus, Self::DoubleMinus) => Snafu::new(b"-1"),
24+
(Self::DoubleMinus, Self::Minus) => Snafu::new(b"-2"),
25+
(Self::DoubleMinus, Self::Zero) => Snafu::new(b"="),
26+
(Self::DoubleMinus, Self::One) => Snafu::new(b"-"),
27+
(Self::DoubleMinus, Self::Two) => Snafu::new(b"0"),
28+
//
29+
(Self::Minus, Self::Minus) => Snafu::new(b"="),
30+
(Self::Minus, Self::Zero) => Snafu::new(b"-"),
31+
(Self::Minus, Self::One) => Snafu::new(b"0"),
32+
(Self::Minus, Self::Two) => Snafu::new(b"1"),
33+
//
34+
(Self::Zero, Self::Zero) => Snafu::new(b"0"),
35+
(Self::Zero, Self::One) => Snafu::new(b"1"),
36+
(Self::Zero, Self::Two) => Snafu::new(b"2"),
37+
//
38+
(Self::One, Self::One) => Snafu::new(b"2"),
39+
(Self::One, Self::Two) => Snafu::new(b"1="),
40+
//
41+
(Self::Two, Self::Two) => Snafu::new(b"1-"),
42+
//
43+
(x, y) => Self::add(y,x),
44+
}
45+
}
46+
}
47+
48+
49+
impl From<&SnafuDigit> for isize {
50+
fn from(value: &SnafuDigit) -> Self {
51+
*value as isize
52+
}
53+
}
54+
55+
impl From<SnafuDigit> for isize {
56+
fn from(value: SnafuDigit) -> Self {
57+
value.into()
58+
}
59+
}
60+
61+
impl SnafuDigit {
62+
fn to_snafu(self) -> Snafu {
63+
Snafu(vec![self])
64+
}
65+
}
66+
67+
impl From<&u8> for SnafuDigit {
68+
fn from(digit: &u8) -> Self {
69+
match digit {
70+
b'2' => Self::Two,
71+
b'1' => Self::One,
72+
b'0' => Self::Zero,
73+
b'-' => Self::Minus,
74+
b'=' => Self::DoubleMinus,
75+
_ => panic!("unknown digit"),
76+
}
77+
}
78+
}
79+
80+
impl Display for SnafuDigit {
81+
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
82+
write!(f, "{}", match self {
83+
Self::DoubleMinus => '=',
84+
Self::Minus => '-',
85+
Self::Zero => '0',
86+
Self::One => '1',
87+
Self::Two => '2',
88+
})
89+
}
90+
}
91+
92+
// saved from LSD to MSD
93+
#[derive(Debug, PartialEq, Eq, Clone)]
94+
struct Snafu(Vec<SnafuDigit>);
95+
96+
impl Snafu {
97+
fn new(arr: &[u8]) -> Self {
98+
Self(arr.iter().rev().map(|digit| digit.into()).collect())
99+
}
100+
}
101+
102+
impl Display for Snafu {
103+
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
104+
for d in self.0.iter().rev() {
105+
write!(f, "{}", d)?;
106+
}
107+
Ok(())
108+
}
109+
}
110+
111+
impl Default for Snafu {
112+
fn default() -> Self {
113+
Snafu(vec![SnafuDigit::default()])
114+
}
115+
}
116+
117+
impl Add<Self> for Snafu {
118+
type Output = Snafu;
119+
fn add(self, rhs: Self) -> Self::Output {
120+
// longest number first
121+
let (x, y) = if self.0.len() > rhs.0.len() {(&self.0,&rhs.0)} else {(&rhs.0,&self.0)};
122+
let mut carry = Snafu(vec![]);
123+
let mut res = Snafu::new(b"");
124+
for i in 0.. {
125+
if i >= x.len() && carry.0.is_empty() {
126+
break;
127+
}
128+
129+
carry = match (x.get(i), y.get(i), carry) {
130+
(Some(l), Some(r), carry) if carry.0.is_empty() => {
131+
*l + *r
132+
}
133+
(Some(l), Some(r), carry) => {
134+
*l + *r + carry
135+
}
136+
(Some(_), None, carry) if carry.0.is_empty() => {
137+
res.0.extend_from_slice(&x[i..]);
138+
return res
139+
}
140+
(Some(l), None, carry) => {
141+
l.to_snafu() + carry
142+
}
143+
(None, Some(_), carry) if carry.0.is_empty() => {
144+
res.0.extend_from_slice(&y[i..]);
145+
return res
146+
}
147+
(None, Some(r), carry) => {
148+
r.to_snafu() + carry
149+
}
150+
(None, None, carry) => {
151+
res.0.extend(carry.0);
152+
return res;
153+
}
154+
};
155+
let digit = carry.0.remove(0);
156+
res.0.push(digit);
157+
}
158+
res
159+
}
160+
}
161+
162+
impl FromIterator<u8> for Snafu {
163+
fn from_iter<I: IntoIterator<Item = u8>>(iter: I) -> Self {
164+
let mut digits: Vec<SnafuDigit> = iter.into_iter().map(|b| (&b).into()).collect();
165+
digits.reverse();
166+
Self(digits)
167+
}
168+
}
169+
170+
impl From<&Snafu> for isize {
171+
fn from(value: &Snafu) -> Self {
172+
let mut res = 0;
173+
let mut weight: isize = 1;
174+
for digit in value.0.iter() {
175+
let v = weight * (*digit) as isize;
176+
res += v;
177+
weight *= SNAFU_BASE;
178+
}
179+
res
180+
}
181+
}
182+
183+
impl From<Snafu> for isize {
184+
fn from(value: Snafu) -> Self {
185+
(&value).into()
186+
}
187+
}
188+
189+
#[allow(unused)]
190+
fn test_conversion(dec: isize, snafu: Snafu) {
191+
let res: isize = snafu.into();
192+
assert_eq!(res, dec);
193+
}
194+
195+
fn main() {
196+
let f = File::open("input/day25.txt").unwrap();
197+
let read = BufReader::new(f);
198+
let lines = read.lines();
199+
200+
let mut acc = Snafu::default();
201+
for line in lines {
202+
let line = line.unwrap();
203+
let snafu: Snafu = line.bytes().collect();
204+
205+
acc = acc + snafu;
206+
}
207+
println!("{}", acc);
208+
}

0 commit comments

Comments
 (0)