diff --git a/2022-aoc/src/d13.rs b/2022-aoc/src/d13.rs index 0d9f436..aff04fd 100644 --- a/2022-aoc/src/d13.rs +++ b/2022-aoc/src/d13.rs @@ -1,17 +1,19 @@ use aoc_runner_derive::{aoc as aoc_run, aoc_generator}; -use lyn::*; +use lyn::Scanner; /* +The following grammar can be used at https://bnfplayground.pauliankline.com/ to play with matching + ::= ? - ::= ( )* - ::= | * + ::= ( )* + ::= | * ::= "," | ", " ::= "[" ::= "]" ::= [0-9]+ */ -#[derive(PartialEq, Eq, PartialOrd, Ord, Debug)] +#[derive(PartialEq, Eq, PartialOrd, Ord, Debug, Clone)] struct Packet { elements: Vec, } @@ -44,6 +46,9 @@ impl Ord for Element { fn parse_input(input: &str) -> Vec { let mut out = Vec::new(); for line in input.lines() { + if line.trim().is_empty() { + continue; + } let mut scanner = Scanner::new(line); let packet = parse_packet(&mut scanner); out.push(packet); @@ -56,26 +61,78 @@ fn parse_packet(scanner: &mut Scanner) -> Packet { // we can pop the first character off, it's the opening brace scanner.pop(); let elements = parse_list(scanner); - // pop off the last character, the final closing brace - assert!(scanner.pop().is_some()); - assert!(scanner.is_done()); Packet { elements } } fn parse_list(scanner: &mut Scanner) -> Vec { - todo!() + let mut out = Vec::new(); + while !scanner.is_done() { + match scanner.peek().unwrap() { + '[' => { + scanner.pop(); + let v = parse_list(scanner); + out.push(Element::List(v)); + } + c if c.is_ascii_digit() => { + // + let mut s = String::new(); + while let Some(c) = scanner.peek() { + if c.is_ascii_digit() { + let c = scanner.pop().unwrap(); + s.push(*c); + } else { + break; + } + } + let num: u32 = s.parse().unwrap(); + out.push(Element::Plain(num)); + } + ']' => { + scanner.pop(); + break; + } + _ => { + scanner.pop(); + } + }; + } + + out } #[aoc_run(day13, part1)] fn part1(input: &[Packet]) -> u32 { - 0 + let mut out = 0; + for (i, packets) in input.chunks(2).enumerate() { + // + let (left, right) = (&packets[0], &packets[1]); + if left < right { + out += i + 1; + } + } + out as u32 } #[aoc_run(day13, part2)] fn part2(input: &[Packet]) -> u32 { - 0 + let d1 = &parse_packet(&mut Scanner::new("[[2]]")); + let d2 = &parse_packet(&mut Scanner::new("[[6]]")); + let mut input = input.to_vec(); + input.push(d1.clone()); + input.push(d2.clone()); + input.sort(); + let mut out = 1; + + for (i, p) in input.iter().enumerate() { + if p == d1 || p == d2 { + out *= i + 1; + } + } + + out as u32 } +/* #[cfg(test)] mod test { use super::*; @@ -107,12 +164,13 @@ mod test { fn part1_test() { let v = parse_input(INPUT); - assert_eq!(part1(&v), 1); + assert_eq!(part1(&v), 13); } #[test] fn part2_test() { let v = parse_input(INPUT); - assert_eq!(part2(&v), 1); + assert_eq!(part2(&v), 140); } } +*/