diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/day13.rs | 115 | ||||
-rw-r--r-- | src/main.rs | 2 |
2 files changed, 117 insertions, 0 deletions
diff --git a/src/day13.rs b/src/day13.rs new file mode 100644 index 0000000..d2bd050 --- /dev/null +++ b/src/day13.rs @@ -0,0 +1,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); +}
\ No newline at end of file diff --git a/src/main.rs b/src/main.rs index 885a516..0b427f1 100644 --- a/src/main.rs +++ b/src/main.rs @@ -14,6 +14,7 @@ mod day9; mod day10; mod day11; mod day12; +mod day13; fn main() { day1::run(fs::read_to_string("input/day1.txt").expect("Failed to read input file!")); @@ -28,4 +29,5 @@ fn main() { day10::run(fs::read_to_string("input/day10.txt").expect("Failed to read input file!")); day11::run(fs::read_to_string("input/day11.txt").expect("Failed to read input file!")); day12::run(fs::read_to_string("input/day12.txt").expect("Failed to read input file!")); + day13::run(fs::read_to_string("input/day13.txt").expect("Failed to read input file!")); } |