summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJustin Wernick <justin@worthe-it.co.za>2022-12-25 14:08:37 +0200
committerJustin Wernick <justin@worthe-it.co.za>2022-12-25 14:08:37 +0200
commit3a419be8836ae6e51adc20ba484b6c091ce696ec (patch)
tree16e15b703b9e72679bba13a92f9f5af98090389f
parent9c9e9cc0f1be749398d0be3549cb39ff98fdb287 (diff)
Day 25
-rw-r--r--2022/inputs/day_25.txt129
-rw-r--r--2022/src/bin/day_25.rs111
2 files changed, 240 insertions, 0 deletions
diff --git a/2022/inputs/day_25.txt b/2022/inputs/day_25.txt
new file mode 100644
index 0000000..db2a942
--- /dev/null
+++ b/2022/inputs/day_25.txt
@@ -0,0 +1,129 @@
+1-012=0=2=--12
+11=
+1=--000111=01-0
+201-12=0211--
+110-=010-01--02
+11021==---22-1
+122001
+1--0
+2-=2
+22=02==01=0-2-011
+12-2-00-11
+20=0-2102=-01
+1102=
+122--0-112221
+11=00-2=201-22=-=
+10-02==210--=0
+2=220-02=1202
+1=--0-
+2-122==
+10-=00
+1=001-22==1
+1=121022122-1--0
+11-
+2=0-1-0-1
+1=-0221-==
+1-==-0--1012
+1--02=-01=020110=
+2-0212==1--=2=
+112
+1=-=1=0012201
+1==-
+1=02-2=012-=2--=--
+1=220-1=0--=1
+10-=
+1-=22-111=211
+11--==21==202
+20-
+1=-1=02=0=1===0-210
+1==-0=010
+1=-2=-=2-01-102102=
+110-==0=2=-==-2-10
+12200=--21-
+21-=1-=1-2-
+111-==2=2
+210=-0-02=-0=11
+10-1
+1-0=011
+20=10=001-
+2-0=0-=1121=---2-0
+22-1=2=0202
+21=2201020211=2
+1-110=
+21=22=0-=1==121
+1==-=01
+1-1=1012==1
+1-01===1=--21
+1==
+2-=
+200=202121--0122
+1-02
+1=21=-12-0-
+2-=10
+121=-20=0200=02==1
+101=2-2102-0-02=
+1===11
+22==0
+22-21==-2-1220=10
+1==2120--1-=
+1=11-2=-110100002200
+2211=2=-=-=01-01
+1==-010==-=2-=
+2=0=2
+11-100-21=
+11=1=-1=0
+2=2--1=2
+1-0==1=2-211=1
+1-2=-202011211
+10=-==-00-1==01
+1-=2122==
+112=-012
+12==-0=
+1122-0=0
+1=2=0
+2===-0=-0-0
+1212
+202
+1==1
+2111=1=000221-=-2=-
+210111=2=0-1==-
+1===00=
+22=22=-1-==2-==
+102--1=-1=222
+2=--=--0-2
+11-02=201101=2
+1=
+12--112-=0=
+10====0=220
+100020002=-0=02-1-
+101
+1=1-112-=
+2022-02
+22201212
+21221201010210-1-
+1-=1=-121-0-221-10
+1=212=01--10-==
+12-0=2121=21-2
+111-2-00
+1=20=202--
+2-==2=--2-2101002
+111-12=00
+1=0===2=
+12=-2020=1=2012
+2=
+1-02---
+221---2122212
+10=-20002=20-22
+2010-220
+12
+2=0-=221
+10011=0
+1-20--=1=1-=1
+1=1
+1=0202-2-1=20-2-
+101=--0-=-010-=
+1=12=--
+2=2111=
+1=0-2=2120002=0
+10-1=0---10=-20=010
+20-121===--=2-=111
diff --git a/2022/src/bin/day_25.rs b/2022/src/bin/day_25.rs
new file mode 100644
index 0000000..d55f30a
--- /dev/null
+++ b/2022/src/bin/day_25.rs
@@ -0,0 +1,111 @@
+use nom::{
+ branch::alt,
+ bytes::complete::tag,
+ character::complete::line_ending,
+ combinator::{map, value},
+ multi::{many1, separated_list1},
+ IResult,
+};
+use std::fs;
+
+fn main() -> Result<(), Box<dyn std::error::Error>> {
+ let input = fs::read_to_string("inputs/day_25.txt")?;
+ let parsed = SnafuList::parser(&input).unwrap().1;
+ dbg!(to_snafu(parsed.sum()));
+
+ Ok(())
+}
+
+#[derive(Debug, Clone, PartialEq, Eq)]
+struct SnafuList(Vec<i64>);
+
+impl SnafuList {
+ fn parser(input: &str) -> IResult<&str, SnafuList> {
+ map(
+ separated_list1(
+ line_ending,
+ map(
+ many1(alt((
+ value(2, tag("2")),
+ value(1, tag("1")),
+ value(0, tag("0")),
+ value(-1, tag("-")),
+ value(-2, tag("=")),
+ ))),
+ |digits| {
+ let mut result: i64 = 0;
+ for digit in digits {
+ result *= 5;
+ result += digit;
+ }
+ result
+ },
+ ),
+ ),
+ SnafuList,
+ )(input)
+ }
+
+ fn sum(&self) -> i64 {
+ self.0.iter().sum()
+ }
+}
+
+fn to_snafu(mut remaining_value: i64) -> String {
+ let mut result = String::new();
+
+ let mut current_power = 5i64.pow(26);
+
+ while current_power > 0 {
+ let next_digit_range = {
+ let mut next_digit_power = current_power / 5;
+ let mut max_next_digit = 0;
+ while next_digit_power > 0 {
+ max_next_digit += 2 * next_digit_power;
+ next_digit_power /= 5;
+ }
+ -max_next_digit..=max_next_digit
+ };
+
+ let (digit, digit_value) = [('=', -2), ('-', -1), ('0', 0), ('1', 1), ('2', 2)]
+ .into_iter()
+ .filter_map(|(digit, digit_value)| {
+ let digit_value = digit_value * current_power;
+ let remaining_if_digit_set = remaining_value - digit_value;
+ if next_digit_range.contains(&remaining_if_digit_set) {
+ Some((digit, digit_value))
+ } else {
+ None
+ }
+ })
+ .next()
+ .expect("No digit found");
+
+ remaining_value -= digit_value;
+ result.push(digit);
+
+ current_power /= 5;
+ }
+
+ result.trim_start_matches("0").to_owned()
+}
+
+#[test]
+fn round_trip_works() {
+ let str_list = vec![
+ "1=-0-2", "12111", "2=0=", "21", "2=01", "111", "20012", "112", "1=-1=", "1-12", "12",
+ "1=", "122",
+ ];
+ let list = SnafuList::parser(&str_list.join("\n")).unwrap().1;
+
+ assert_eq!(
+ list,
+ SnafuList(vec![
+ 1747, 906, 198, 11, 201, 31, 1257, 32, 353, 107, 7, 3, 37
+ ])
+ );
+
+ for (i, num) in list.0.iter().enumerate() {
+ assert_eq!(to_snafu(*num), str_list[i]);
+ }
+}