diff --git a/src/days/d13.rs b/src/days/d13.rs index bfe58a0..2967d84 100644 --- a/src/days/d13.rs +++ b/src/days/d13.rs @@ -6,6 +6,7 @@ pub fn solve() { let contents = fs::read_to_string(path).expect("I/O error, wrong path?"); + // Task 1 let pairs: Vec<(&str, &str)> = contents .split("\n\n") .map(|pair| pair.split_at(pair.find("\n").unwrap())) @@ -16,10 +17,10 @@ pub fn solve() { let json1: Value = serde_json::from_str(pair.0).unwrap(); let json2: Value = serde_json::from_str(pair.1).unwrap(); - println!("== Pair {} ==", i+1); + // println!("== Pair {} ==", i+1); let res = is_right_order((&json1, &json2)); - println!("Pair {}: {res:?}\n", i+1); + // println!("Pair {}: {res:?}\n", i+1); if res != Ordered::No { right_order_indices.push((i+1) as u32); @@ -29,7 +30,46 @@ pub fn solve() { let res: u32 = right_order_indices.iter().sum(); println!("Result 1: {res}"); + // Task 2 + let mut packets: Vec = contents + .lines() + .filter(|line| *line != "") + .map(|line| serde_json::from_str(line).unwrap()) + .collect(); + // add [[2]] and [[6]] as divider packets + packets.push(serde_json::from_str("[[6]]").unwrap()); + packets.push(serde_json::from_str("[[2]]").unwrap()); + + // sort by compare function using is_right_order + packets.sort_by(|a, b| + match is_right_order((a, b)) { + Ordered::Yes => Ordering::Less, + Ordered::Maybe => Ordering::Equal, + Ordered::No => Ordering::Greater + }); + + // find [[2]] and [[6]] indices + let mut i2 = 0; + let mut i6 = 0; + packets.iter().enumerate().for_each(|(i, v)| { + if v.is_array() && v.as_array().unwrap().len() == 1 { + let v = v.as_array().unwrap(); + if v[0].is_array() && v[0].as_array().unwrap().len() == 1 { + let v = v[0].as_array().unwrap(); + if v[0].is_number() && v[0].as_u64().unwrap() == 2 { + i2 = i+1 + } + else if v[0].is_number() && v[0].as_u64().unwrap() == 6 { + i6 = i+1 + } + } + } + }); + + let res = i2*i6; + + println!("Result 2: {res}"); } #[derive(PartialEq, Debug)] @@ -39,8 +79,10 @@ enum Ordered { No } +// returns whether the passed Values are in the right order +// with Ordered enum option fn is_right_order(values: (&Value, &Value)) -> Ordered { - println!("Compare {} vs {}", values.0, values.1); + //println!("Compare {} vs {}", values.0, values.1); // both values numbers if values.0.is_number() && values.1.is_number() { @@ -79,14 +121,17 @@ fn is_right_order(values: (&Value, &Value)) -> Ordered { let left = a0iter.next(); let right = a1iter.next(); + // left smaller, counts as ordered if left.is_none() && right.is_some() { return Ordered::Yes } + // right smaller, counts as unordered if left.is_some() && right.is_none() { return Ordered::No } + // both have same length, doesn't say anything about ordering if left.is_none() && right.is_none() { return Ordered::Maybe } @@ -94,6 +139,7 @@ fn is_right_order(values: (&Value, &Value)) -> Ordered { let left = left.unwrap(); let right = right.unwrap(); + // only go into next iteration if not definitely yes or no let res = is_right_order((&left, &right)); if res != Ordered::Maybe { return res