Add solution for 2022 day 13 part 2
This commit is contained in:
parent
1b28bf1848
commit
2896afdb8c
@ -16,7 +16,7 @@
|
||||
| [10] | ✓ | ✓ | [Rust] |
|
||||
| [11] | ✓ | | [Rust] |
|
||||
| [12] | ✓ | ✓ | [Rust] |
|
||||
| [13] | ✓ | | [Rust] |
|
||||
| [13] | ✓ | ✓ | [Rust] |
|
||||
| [14] | | | |
|
||||
| [15] | | | |
|
||||
| [16] | | | |
|
||||
|
@ -1,6 +1,6 @@
|
||||
use std::{env, io};
|
||||
|
||||
use aoc_2022_13::{parse_input, Pair, Segment};
|
||||
use aoc_2022_13::parse_input;
|
||||
|
||||
fn main() -> io::Result<()> {
|
||||
let infile_path = env::args().nth(1).expect("input file");
|
||||
@ -17,62 +17,12 @@ fn solve(path: &str) -> io::Result<u32> {
|
||||
let result = pairs
|
||||
.iter()
|
||||
.enumerate()
|
||||
.filter_map(|(i, pair)| match is_in_right_order(&pair) {
|
||||
Ordered::Yes => Some(i + 1),
|
||||
_ => None,
|
||||
})
|
||||
.filter_map(|(i, (a, b))| if a < b { Some(i + 1) } else { None })
|
||||
.sum::<usize>();
|
||||
|
||||
Ok(result as u32)
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
enum Ordered {
|
||||
Undecided,
|
||||
Yes,
|
||||
No,
|
||||
}
|
||||
|
||||
fn is_in_right_order((left, right): &Pair) -> Ordered {
|
||||
test_segment(left, right)
|
||||
}
|
||||
|
||||
fn test_segment(left: &Segment, right: &Segment) -> Ordered {
|
||||
match (left, right) {
|
||||
(Segment::Num(lval), Segment::Num(rval)) => test_segment_num(*lval, *rval),
|
||||
(Segment::List(lval), Segment::List(rval)) => test_segment_list(lval, rval),
|
||||
(Segment::List(lval), rval @ Segment::Num(_)) => test_segment_list(lval, &[rval.clone()]),
|
||||
(lval @ Segment::Num(_), Segment::List(rval)) => test_segment_list(&[lval.clone()], rval),
|
||||
}
|
||||
}
|
||||
|
||||
fn test_segment_list(left: &[Segment], right: &[Segment]) -> Ordered {
|
||||
let mut left = left.iter();
|
||||
let mut right = right.iter();
|
||||
|
||||
loop {
|
||||
match (left.next(), right.next()) {
|
||||
(Some(lval), Some(rval)) => match test_segment(lval, rval) {
|
||||
Ordered::Undecided => (),
|
||||
ord => return ord,
|
||||
},
|
||||
(None, Some(_)) => return Ordered::Yes,
|
||||
(Some(_), None) => return Ordered::No,
|
||||
(None, None) => return Ordered::Undecided,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn test_segment_num(left: u32, right: u32) -> Ordered {
|
||||
if left < right {
|
||||
Ordered::Yes
|
||||
} else if left == right {
|
||||
Ordered::Undecided
|
||||
} else {
|
||||
Ordered::No
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use super::*;
|
||||
|
58
2022/day-13/src/bin/part_two.rs
Normal file
58
2022/day-13/src/bin/part_two.rs
Normal file
@ -0,0 +1,58 @@
|
||||
use std::{env, io};
|
||||
|
||||
use aoc_2022_13::{parse_input, Segment};
|
||||
|
||||
fn main() -> io::Result<()> {
|
||||
let infile_path = env::args().nth(1).expect("input file");
|
||||
|
||||
let result = solve(&infile_path)?;
|
||||
|
||||
println!("{result}");
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn solve(path: &str) -> io::Result<u32> {
|
||||
let pairs = parse_input(path)?;
|
||||
let mut packets = pairs.iter().fold(vec![], |mut acc, (a, b)| {
|
||||
acc.extend([a, b]);
|
||||
acc
|
||||
});
|
||||
let divider_a = Segment::List(vec![Segment::List(vec![Segment::Num(2)])]);
|
||||
let divider_b = Segment::List(vec![Segment::List(vec![Segment::Num(6)])]);
|
||||
packets.push(÷r_a);
|
||||
packets.push(÷r_b);
|
||||
|
||||
packets.sort();
|
||||
|
||||
let result = packets
|
||||
.iter()
|
||||
.enumerate()
|
||||
.filter_map(|(idx, &val)| {
|
||||
if val == ÷r_a || val == ÷r_b {
|
||||
Some(idx + 1)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
.product::<usize>();
|
||||
|
||||
Ok(result as u32)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn sample() {
|
||||
let result = solve("inputs/test.txt").unwrap();
|
||||
assert_eq!(140, result);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn puzzle() {
|
||||
let result = solve("inputs/puzzle.txt").unwrap();
|
||||
assert_eq!(29025, result);
|
||||
}
|
||||
}
|
@ -1,4 +1,5 @@
|
||||
use std::{
|
||||
cmp::Ordering,
|
||||
fmt,
|
||||
fs::File,
|
||||
io::{self, Read},
|
||||
@ -7,12 +8,33 @@ use std::{
|
||||
|
||||
pub type Pair = (Segment, Segment);
|
||||
|
||||
#[derive(Clone)]
|
||||
#[derive(Clone, PartialEq, Eq)]
|
||||
pub enum Segment {
|
||||
Num(u32),
|
||||
List(Vec<Segment>),
|
||||
}
|
||||
|
||||
impl Ord for Segment {
|
||||
fn cmp(&self, other: &Self) -> Ordering {
|
||||
match (self, other) {
|
||||
(Segment::Num(lval), Segment::Num(rval)) => lval.cmp(rval),
|
||||
(Segment::List(lval), Segment::List(rval)) => test_segment_list(lval, rval),
|
||||
(Segment::List(lval), rval @ Segment::Num(_)) => {
|
||||
test_segment_list(lval, &[rval.clone()])
|
||||
}
|
||||
(lval @ Segment::Num(_), Segment::List(rval)) => {
|
||||
test_segment_list(&[lval.clone()], rval)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl PartialOrd for Segment {
|
||||
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
|
||||
Some(self.cmp(&other))
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Debug for Segment {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
match self {
|
||||
@ -22,6 +44,23 @@ impl fmt::Debug for Segment {
|
||||
}
|
||||
}
|
||||
|
||||
fn test_segment_list(left: &[Segment], right: &[Segment]) -> Ordering {
|
||||
let mut left = left.iter();
|
||||
let mut right = right.iter();
|
||||
|
||||
loop {
|
||||
match (left.next(), right.next()) {
|
||||
(Some(lval), Some(rval)) => match lval.cmp(rval) {
|
||||
Ordering::Equal => (),
|
||||
ord => return ord,
|
||||
},
|
||||
(None, Some(_)) => return Ordering::Less,
|
||||
(Some(_), None) => return Ordering::Greater,
|
||||
(None, None) => return Ordering::Equal,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn parse_input<P>(path: P) -> io::Result<Vec<Pair>>
|
||||
where
|
||||
P: AsRef<Path>,
|
||||
|
Loading…
Reference in New Issue
Block a user