use std::cmp::Ordering; #[derive(Debug,Clone,PartialEq)] enum Packet { Num(i32), Lst(Vec) } impl Packet { fn parse>(chrs: &mut T) -> Packet { let mut numchrs = String::new(); let mut children: Vec = Vec::new(); loop { match chrs.next() { Some('[') => { children.push(Packet::parse(chrs)); }, Some(']') | None => break, Some(',') => { if !numchrs.is_empty() { children.push(Packet::Num(numchrs.parse().expect("chars wasn't a number!"))); } numchrs.clear(); }, Some(x) => { numchrs.push(x); }, } } if !numchrs.is_empty() { children.push(Packet::Num(numchrs.parse().expect("chars wasn't a number!"))); } Packet::Lst(children) } fn coerce_to_lst(&self) -> Packet { match self { Self::Lst(x) => Packet::Lst(x.to_vec()), Self::Num(x) => Packet::Lst(vec![Packet::Num(*x)]) } } fn rightorder(left: &Packet, right: &Self) -> Ordering { if let (Packet::Num(x), Packet::Num(y)) = (left, right) { if x < y { Ordering::Less } else if x == y { Ordering::Equal } else { Ordering::Greater } } else if let (Packet::Lst(x), Packet::Lst(y)) = (left, right) { for ix in 0..(x.len().max(y.len())) { let maybe_xx = x.get(ix); if maybe_xx.is_none() { return Ordering::Less; } let maybe_yy = y.get(ix); if maybe_yy.is_none() { return Ordering::Greater; } let rr = Packet::rightorder(maybe_xx.unwrap(), maybe_yy.unwrap()); match rr { Ordering::Less | Ordering::Greater => return rr, Ordering::Equal => {}, } } Ordering::Equal } else { Packet::rightorder(&left.coerce_to_lst(), &right.coerce_to_lst()) } } } pub fn run(input: String) { // let x: i32 = input.lines().collect::>().split(|x| {x.is_empty()}) // .enumerate() // .map(|(ix, ps)| { // if ps.len() != 2 { // panic!("Expected pairs of packets, got {:?}", ps); // } // let ps1 = ps[0]; // let ps2 = ps[1]; // let p1 = Packet::parse(&mut ps1.chars().into_iter()); // let p2 = Packet::parse(&mut ps2.chars().into_iter()); // //println!("ps1 {} ps2 {} p1 {:?} p2 {:?}", ps1, ps2, p1, p2); // match Packet::rightorder(&p1, &p2) { // Ordering::Less => (ix+1) as i32, // Ordering::Greater => 0 as i32, // Ordering::Equal => panic!("2 identical packets????") // } // }) // .sum(); // println!("Day 13: {}", x); let mut zinput = String::from(" [[2]] [[6]] "); zinput.push_str(&input); let mut packets = zinput.lines() .filter(|x| {!x.is_empty()}) .map(|x| {Packet::parse(&mut x.chars().into_iter())}) .enumerate() .collect::>(); packets.sort_by(|(_, p1), (_, p2)| { Packet::rightorder(p1, p2)}); let mut dp1: usize = 0; let mut dp2: usize = 0; for (nix, (oix, _)) in packets.into_iter().enumerate() { if oix == 0 { dp1 = nix+1; } else if oix == 1 { dp2 = nix+1; } } println!("Day 13: {}", dp1*dp2); }