day25 finished

This commit is contained in:
Rüdiger Ludwig 2023-08-13 15:08:31 +02:00
parent abc1530bf3
commit 91b264ba69
4 changed files with 293 additions and 1 deletions

13
data/day25/example01.txt Normal file
View file

@ -0,0 +1,13 @@
1=-0-2
12111
2=0=
21
2=01
111
20012
112
1=-1=
1-12
12
1=
122

135
data/day25/input.txt Normal file
View file

@ -0,0 +1,135 @@
1--
1-
1--02
1122-=2-==0-0=1-2
2=1-==-1022=10
1==-02211022=000
101==210-21=2
11010==0==221=0=02
11=1101020=02-11
1===
10-2
10=02=-=02
1-1--112-202--0
11-=-0-002=0112-1
2--0-2=02=-22
1001-2
1=101=2=2102-201--1
1-2==1100--
2-01=--=1-11
101-=0010-210==
1=-21-022121110
1==21
22==1
2-0-=2=1
2--0=10-00--2-
1--1=011-2
1-100-2
11-1
112
222200110-11110-2=
1==2-210-1122=-2022
2==1-20-2-=-21
21=1-=0=-1-=-=-12
210---=-1===-===00
1--21=01-022=2-
11-=
21-2
2-22-0
1==-
1-----01
1-0-21-
211212-22-12--=2
1=220=10=20200-0
21-=11-==20=1
102-2==2-==-0
1=0=01-
22=1--0111
1-----=1==00===0-
20==-1-121-
1=--2--21-202=21
1-0122=--=
2==-2--===-=-1=-012
2220=-00-10-
1==0=---10212-1-
1221=-022120
100112
2-=0=220-=01-1=12-
1=00
2122121=2
2-==
12-21===10220
1=0
22-1=--01-==0
1-2-2202=1=02
11-===21-
1-22=0102-=-222-1
1021=0=21=0=11=2-2
1===2222=0-0=
20=2-=0=
1=2==02-1-100200
1=1211211----
12=1=1---=20
2--2=2=1100020200
1=0-002-11-10----
1=1=-1=-0
1-21=1=02=21=20
1-=0-002-0=--=0=
20-===-1=
220021012
12===1001=--=2=1-
1=-02
21
2=200222122
1-2=110111=012=1-
1=02=
101==1-=1=0001
1=22--1-021
120
201-0211
1-1012211--2=-1=
12=10202=20
11-22=2=2=-0==1=00
11=-
12-1--2222
22
1120--0==
10=-0=001-
1=00200200=
1-20
1-0-
10112-202=-011
11-2=
1-=10=1-0=-21==11200
11
12-0-=01--12
1-=1121-=0
120-21=-1=10121=
1102-22
21=
1==--1==---1-==
12=0--=2210-1==
22210=1-=0
1102-20-1
1=1=2102
11--=2==-0
2=0=1=
21-0-10=
12-212-2=-==102--
1==0100210-=
12210-0-1
1=0-2-0=
10-1=211=1-2=
201-0--
1--2=00=-1-211
121=-22100=210--
122-0-1-
2=211
2=1-=2-2-0001=-1
1102--11=0=1=10==2
1==01121-2--0=12
2=21-20=-0-0
2-212=21-02=1-2-02
2=1-0
10-0-=20
2=2=201

142
src/days/day25/mod.rs Normal file
View file

@ -0,0 +1,142 @@
use super::template::{DayTrait, ResultType};
use crate::common::file::split_lines;
use itertools::{unfold, Itertools};
use std::iter::Sum;
use std::ops::Add;
use std::str::FromStr;
use thiserror::Error;
const DAY_NUMBER: usize = 25;
pub struct Day;
impl DayTrait for Day {
fn get_day_number(&self) -> usize {
DAY_NUMBER
}
fn part1(&self, lines: &str) -> anyhow::Result<ResultType> {
let snafu: Snafu = split_lines(lines)
.map(|line| line.parse::<Snafu>())
.collect::<Result<Vec<_>, _>>()?
.into_iter()
.sum();
Ok(ResultType::String(snafu.as_str()))
}
fn part2(&self, _lines: &str) -> anyhow::Result<ResultType> {
Ok(ResultType::Nothing)
}
}
impl Snafu {
pub fn as_str(&self) -> String {
let value = self.0;
if value == 0 {
return String::from("0");
}
unfold(value, |value| {
if *value == 0 {
return None;
}
let m = (*value + 2) % 5;
*value = (*value + 2 - m) / 5;
Some(m)
})
.map(|digit| "=-012".chars().nth(digit).unwrap())
.collect_vec()
.iter()
.rev()
.join("")
}
fn new(value: i64) -> Result<Snafu, SnafuError> {
if value >= 0 {
Ok(Snafu(value as usize))
} else {
Err(SnafuError::OnlyNonNegativeSnafus(value))
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
struct Snafu(usize);
impl Add for Snafu {
type Output = Snafu;
fn add(self, rhs: Self) -> Self::Output {
Snafu(self.0 + rhs.0)
}
}
impl Sum for Snafu {
fn sum<I: Iterator<Item = Self>>(iter: I) -> Self {
iter.fold(Snafu(0), Add::add)
}
}
impl FromStr for Snafu {
type Err = SnafuError;
fn from_str(s: &str) -> Result<Self, Self::Err> {
Snafu::new(
s.chars()
.map(|c| {
"=-012"
.chars()
.position(|d| d == c)
.ok_or_else(|| SnafuError::IllegalChar(c))
})
.fold_ok(0, |acc, next| acc * 5 + (next as i64 - 2))?,
)
}
}
#[derive(Debug, Error)]
enum SnafuError {
#[error("Illegal Char: {0}")]
IllegalChar(char),
#[error("Only non negative Snafus exist. Got: {0}")]
OnlyNonNegativeSnafus(i64),
}
#[cfg(test)]
mod test {
use super::*;
use crate::common::file::read_string;
use anyhow::Result;
#[test]
fn test_part1() -> Result<()> {
let day = Day {};
let lines = read_string(day.get_day_number(), "example01.txt")?;
let expected = ResultType::String(String::from("2=-1=0"));
let result = day.part1(&lines)?;
assert_eq!(result, expected);
Ok(())
}
#[test]
fn test_part2() -> Result<()> {
let day = Day {};
let lines = read_string(day.get_day_number(), "example01.txt")?;
let expected = ResultType::Nothing;
let result = day.part2(&lines)?;
assert_eq!(result, expected);
Ok(())
}
#[test]
fn parse() -> Result<()> {
let input = String::from("1=-0-2");
let snafu: Snafu = input.parse()?;
assert_eq!(snafu, Snafu(1747));
assert_eq!(snafu.as_str(), input);
Ok(())
}
}

View file

@ -22,6 +22,7 @@ mod day21;
mod day22;
mod day23;
mod day24;
mod day25;
mod template;
pub use template::DayTrait;
@ -31,7 +32,7 @@ pub mod day_provider {
use super::*;
use thiserror::Error;
const MAX_DAY: usize = 24;
const MAX_DAY: usize = 25;
pub fn get_day(day_num: usize) -> Result<Box<dyn DayTrait>, ProviderError> {
match day_num {
@ -59,6 +60,7 @@ pub mod day_provider {
22 => Ok(Box::new(day22::Day)),
23 => Ok(Box::new(day23::Day)),
24 => Ok(Box::new(day24::Day)),
25 => Ok(Box::new(day25::Day)),
_ => Err(ProviderError::InvalidNumber(day_num)),
}
}