From 3a419be8836ae6e51adc20ba484b6c091ce696ec Mon Sep 17 00:00:00 2001 From: Justin Wernick Date: Sun, 25 Dec 2022 14:08:37 +0200 Subject: Day 25 --- 2022/inputs/day_25.txt | 129 +++++++++++++++++++++++++++++++++++++++++++++++++ 2022/src/bin/day_25.rs | 111 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 240 insertions(+) create mode 100644 2022/inputs/day_25.txt create mode 100644 2022/src/bin/day_25.rs 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> { + 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); + +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]); + } +} -- cgit v1.2.3