summaryrefslogtreecommitdiff
path: root/src/day13.rs
blob: d2bd050696b119ee466ac270fc71711f49bb3d60 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
use std::cmp::Ordering;

#[derive(Debug,Clone,PartialEq)]
enum Packet {
    Num(i32),
    Lst(Vec<Packet>)
}

impl Packet {
    fn parse<T: Iterator<Item = char>>(chrs: &mut T) -> Packet {
        let mut numchrs = String::new();
        let mut children: Vec<Packet> = 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::<Vec<&str>>().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::<Vec<(usize, Packet)>>();
    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);
}