1use utils::parser::{ParseError, ParseResult};
2use utils::prelude::*;
3
4#[derive(Clone, Debug)]
6pub struct Day12 {
7 part1: i32,
8 part2: i32,
9}
10
11impl Day12 {
12 pub fn new(input: &str, _: InputType) -> Result<Self, InputError> {
13 let (part1, part2) = Self::parse.parse_complete(input)?;
14 Ok(Self { part1, part2 })
15 }
16
17 #[must_use]
18 pub fn part1(&self) -> i32 {
19 self.part1
20 }
21
22 #[must_use]
23 pub fn part2(&self) -> i32 {
24 self.part2
25 }
26
27 fn parse(input: &[u8]) -> ParseResult<(i32, i32)> {
28 match input {
29 [b'{', ..] => Self::parse_object(&input[1..]),
30 [b'[', ..] => Self::parse_array(&input[1..]),
31 _ => Err((ParseError::Expected("'{' or '['"), input)),
32 }
33 }
34
35 fn parse_object(mut input: &[u8]) -> ParseResult<(i32, i32)> {
36 let (mut part1, mut part2) = (0, 0);
37 let mut red = false;
38 loop {
39 match input {
40 [b'1'..=b'9', ..] | [b'-', b'1'..=b'9', ..] => {
41 let (num, remaining) = parser::i32().parse(input)?;
42 input = remaining;
43 part1 += num;
44 part2 += num;
45 }
46 [b'"', b'r', b'e', b'd', b'"', ..] => {
47 input = &input[5..];
48 red = true;
49 }
50 [b'{', ..] => {
51 let (result, remaining) = Self::parse_object(&input[1..])?;
52 input = remaining;
53 part1 += result.0;
54 part2 += result.1;
55 }
56 [b'[', ..] => {
57 let (result, remaining) = Self::parse_array(&input[1..])?;
58 input = remaining;
59 part1 += result.0;
60 part2 += result.1;
61 }
62 [b'}', ..] => return Ok(((part1, if red { 0 } else { part2 }), &input[1..])),
63 [] => return Err((ParseError::ExpectedByte(b']'), input)),
64 _ => input = &input[1..],
65 }
66 }
67 }
68
69 fn parse_array(mut input: &[u8]) -> ParseResult<(i32, i32)> {
70 let (mut part1, mut part2) = (0, 0);
71 loop {
72 match input {
73 [b'1'..=b'9', ..] | [b'-', b'1'..=b'9', ..] => {
74 let (num, remaining) = parser::i32().parse(input)?;
75 input = remaining;
76 part1 += num;
77 part2 += num;
78 }
79 [b'{', ..] => {
80 let (result, remaining) = Self::parse_object(&input[1..])?;
81 input = remaining;
82 part1 += result.0;
83 part2 += result.1;
84 }
85 [b'[', ..] => {
86 let (result, remaining) = Self::parse_array(&input[1..])?;
87 input = remaining;
88 part1 += result.0;
89 part2 += result.1;
90 }
91 [b']', ..] => return Ok(((part1, part2), &input[1..])),
92 [] => return Err((ParseError::ExpectedByte(b']'), input)),
93 _ => input = &input[1..],
94 }
95 }
96 }
97}
98
99examples!(Day12 -> (i32, i32) [
100 {input: r#"[1,2,3]"#, part1: 6, part2: 6},
101 {input: r#"{"a":2,"b":4}"#, part1: 6},
102 {input: r#"[[[3]]]"#, part1: 3},
103 {input: r#"{"a":{"b":4},"c":-1}"#, part1: 3},
104 {input: r#"{"a":[-1,1]}"#, part1: 0},
105 {input: r#"[-1,{"a":1}]"#, part1: 0},
106 {input: r#"[]"#, part1: 0},
107 {input: r#"{}"#, part1: 0},
108 {input: r#"[1,{"c":"red","b":2},3]"#, part2: 4},
109 {input: r#"{"d":"red","e":[1,2,3,4],"f":5}"#, part2: 0},
110 {input: r#"[1,"red",5]"#, part2: 6},
111]);