use utils::prelude::*;
#[derive(Clone, Debug)]
pub struct Day10 {
part1: u32,
part2: u32,
}
const ATOMIC_ELEMENTS: [&str; 92] = [
"22",
"13112221133211322112211213322112",
"312211322212221121123222112",
"111312211312113221133211322112211213322112",
"1321132122211322212221121123222112",
"3113112211322112211213322112",
"111312212221121123222112",
"132112211213322112",
"31121123222112",
"111213322112",
"123222112",
"3113322112",
"1113222112",
"1322112",
"311311222112",
"1113122112",
"132112",
"3112",
"1112",
"12",
"3113112221133112",
"11131221131112",
"13211312",
"31132",
"111311222112",
"13122112",
"32112",
"11133112",
"131112",
"312",
"13221133122211332",
"31131122211311122113222",
"11131221131211322113322112",
"13211321222113222112",
"3113112211322112",
"11131221222112",
"1321122112",
"3112112",
"1112133",
"12322211331222113112211",
"1113122113322113111221131221",
"13211322211312113211",
"311322113212221",
"132211331222113112211",
"311311222113111221131221",
"111312211312113211",
"132113212221",
"3113112211",
"11131221",
"13211",
"3112221",
"1322113312211",
"311311222113111221",
"11131221131211",
"13211321",
"311311",
"11131",
"1321133112",
"31131112",
"111312",
"132",
"311332",
"1113222",
"13221133112",
"3113112221131112",
"111312211312",
"1321132",
"311311222",
"11131221133112",
"1321131112",
"311312",
"11132",
"13112221133211322112211213322113",
"312211322212221121123222113",
"111312211312113221133211322112211213322113",
"1321132122211322212221121123222113",
"3113112211322112211213322113",
"111312212221121123222113",
"132112211213322113",
"31121123222113",
"111213322113",
"123222113",
"3113322113",
"1113222113",
"1322113",
"311311222113",
"1113122113",
"132113",
"3113",
"1113",
"13",
"3",
];
impl Day10 {
pub fn new(input: &str, _: InputType) -> Result<Self, InputError> {
let index = ATOMIC_ELEMENTS
.iter()
.position(|&x| x == input)
.ok_or_else(|| InputError::new(input, 0, "expected atomic element"))?;
let mut decays = [0u32; 92];
decays[index] = 1;
for _ in 0..40 {
decays = Self::step(&decays);
}
let part1 = Self::length(&decays);
for _ in 0..10 {
decays = Self::step(&decays);
}
let part2 = Self::length(&decays);
Ok(Self { part1, part2 })
}
#[must_use]
pub fn part1(&self) -> u32 {
self.part1
}
#[must_use]
pub fn part2(&self) -> u32 {
self.part2
}
#[rustfmt::skip]
fn step(d: &[u32; 92]) -> [u32; 92] {
[
d[0] + d[1] + d[20] + d[30] + d[39] + d[57] + d[72],
d[2],
d[1] + d[3],
d[4],
d[5],
d[6],
d[7],
d[8],
d[9],
d[10],
d[11] + d[32],
d[12],
d[13],
d[14] + d[24],
d[15],
d[16],
d[17],
d[18],
d[19],
d[1] + d[3] + d[20] + d[30] + d[30] + d[39] + d[43] + d[51] + d[57] + d[61] + d[63] + d[68] + d[72] + d[74],
d[21],
d[22],
d[23],
d[24],
d[25],
d[26],
d[20] + d[27] + d[57] + d[63] + d[68],
d[28],
d[29],
d[27] + d[30] + d[61],
d[31],
d[3] + d[32] + d[74],
d[33],
d[34],
d[35],
d[36],
d[37],
d[38],
d[39],
d[40],
d[41],
d[42],
d[39] + d[43],
d[44],
d[45],
d[46],
d[47],
d[48],
d[49],
d[50],
d[51],
d[52],
d[53],
d[54],
d[55],
d[56],
d[57],
d[58],
d[59],
d[60],
d[11] + d[50] + d[61] + d[67] + d[82],
d[62],
d[30] + d[43] + d[51] + d[63],
d[64],
d[65],
d[66],
d[14] + d[20] + d[31] + d[44] + d[52] + d[64] + d[67] + d[85],
d[40] + d[68],
d[69],
d[70],
d[71],
d[1] + d[72],
d[73],
d[72] + d[74],
d[75],
d[76],
d[77],
d[78],
d[79],
d[80],
d[81],
d[82],
d[83],
d[84],
d[85],
d[86],
d[87],
d[88],
d[30] + d[89],
d[90],
d[1] + d[20] + d[72] + d[91],
d[38],
]
}
fn length(d: &[u32; 92]) -> u32 {
d.iter()
.zip(ATOMIC_ELEMENTS)
.map(|(&count, s)| count * s.len() as u32)
.sum()
}
}
examples!(Day10 -> (u32, u32) [
{input: "3", part1: 95798, part2: 1355550},
]);