aoc2022

Advent of Code 2022 solutions in Rust
git clone git://code.mfashby.net:/aoc2022
Log | Files | Refs

day13.rs (3828B)


      1 use std::cmp::Ordering;
      2 
      3 #[derive(Debug,Clone,PartialEq)]
      4 enum Packet {
      5     Num(i32),
      6     Lst(Vec<Packet>)
      7 }
      8 
      9 impl Packet {
     10     fn parse<T: Iterator<Item = char>>(chrs: &mut T) -> Packet {
     11         let mut numchrs = String::new();
     12         let mut children: Vec<Packet> = Vec::new();
     13         loop {
     14             match chrs.next() {
     15                 Some('[') => {
     16                     children.push(Packet::parse(chrs));
     17                 },
     18                 Some(']') | None => break,
     19                 Some(',') => {
     20                     if !numchrs.is_empty() {
     21                         children.push(Packet::Num(numchrs.parse().expect("chars wasn't a number!")));
     22                     }
     23                     numchrs.clear();
     24                 }, 
     25                 Some(x) => {
     26                     numchrs.push(x);
     27                 },
     28             }
     29         }
     30         if !numchrs.is_empty() {
     31             children.push(Packet::Num(numchrs.parse().expect("chars wasn't a number!")));
     32         }
     33         Packet::Lst(children)
     34     }
     35     fn coerce_to_lst(&self) -> Packet {
     36         match self {
     37             Self::Lst(x) => Packet::Lst(x.to_vec()),
     38             Self::Num(x) => Packet::Lst(vec![Packet::Num(*x)])
     39         }
     40     }
     41     fn rightorder(left: &Packet, right: &Self) -> Ordering {
     42         if let (Packet::Num(x), Packet::Num(y)) = (left, right) {
     43             if x < y {
     44                 Ordering::Less
     45             } else if x == y {
     46                 Ordering::Equal
     47             } else {
     48                 Ordering::Greater
     49             }
     50         } else if let (Packet::Lst(x), Packet::Lst(y)) = (left, right) {
     51             for ix in 0..(x.len().max(y.len())) {
     52                 let maybe_xx = x.get(ix);
     53                 if maybe_xx.is_none() {
     54                     return Ordering::Less;
     55                 }
     56                 let maybe_yy = y.get(ix);
     57                 if maybe_yy.is_none() {
     58                     return Ordering::Greater;
     59                 }
     60                 let rr = Packet::rightorder(maybe_xx.unwrap(), maybe_yy.unwrap());
     61                 match rr {
     62                     Ordering::Less | Ordering::Greater => return rr,
     63                     Ordering::Equal => {},
     64                 }
     65             }
     66             Ordering::Equal
     67         } else {
     68             Packet::rightorder(&left.coerce_to_lst(), &right.coerce_to_lst())
     69         }
     70     }
     71 }
     72 
     73 pub fn run(input: String) {
     74     // let x: i32 = input.lines().collect::<Vec<&str>>().split(|x| {x.is_empty()})
     75     //     .enumerate()
     76     //     .map(|(ix, ps)| {
     77     //         if ps.len() != 2 {
     78     //             panic!("Expected pairs of packets, got {:?}", ps);
     79     //         }
     80     //         let ps1 = ps[0];
     81     //         let ps2 = ps[1];
     82     //         let p1 = Packet::parse(&mut ps1.chars().into_iter());
     83     //         let p2 = Packet::parse(&mut ps2.chars().into_iter());
     84     //         //println!("ps1 {} ps2 {} p1 {:?} p2 {:?}", ps1, ps2, p1, p2);
     85     //         match Packet::rightorder(&p1, &p2) {
     86     //             Ordering::Less => (ix+1) as i32,
     87     //             Ordering::Greater => 0 as i32,
     88     //             Ordering::Equal => panic!("2 identical packets????")
     89     //         }
     90     //     })
     91     //     .sum();
     92 
     93     // println!("Day 13: {}", x);
     94     let mut zinput = String::from("
     95 [[2]]
     96 [[6]]
     97 ");
     98     zinput.push_str(&input);
     99     let mut packets = zinput.lines()
    100         .filter(|x| {!x.is_empty()})
    101         .map(|x| {Packet::parse(&mut x.chars().into_iter())})
    102         .enumerate()
    103         .collect::<Vec<(usize, Packet)>>();
    104     packets.sort_by(|(_, p1), (_, p2)| { Packet::rightorder(p1, p2)});
    105     let mut dp1: usize = 0;
    106     let mut dp2: usize = 0;
    107     for (nix, (oix, _)) in packets.into_iter().enumerate() {
    108         if oix == 0 {
    109             dp1 = nix+1;
    110         } else if oix == 1 {
    111             dp2 = nix+1;
    112         }
    113     }
    114     println!("Day 13: {}", dp1*dp2);
    115 }