Add solution for 2022 day 13 part 2
This commit is contained in:
parent
1b28bf1848
commit
2896afdb8c
@ -16,7 +16,7 @@
|
|||||||
| [10] | ✓ | ✓ | [Rust] |
|
| [10] | ✓ | ✓ | [Rust] |
|
||||||
| [11] | ✓ | | [Rust] |
|
| [11] | ✓ | | [Rust] |
|
||||||
| [12] | ✓ | ✓ | [Rust] |
|
| [12] | ✓ | ✓ | [Rust] |
|
||||||
| [13] | ✓ | | [Rust] |
|
| [13] | ✓ | ✓ | [Rust] |
|
||||||
| [14] | | | |
|
| [14] | | | |
|
||||||
| [15] | | | |
|
| [15] | | | |
|
||||||
| [16] | | | |
|
| [16] | | | |
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
use std::{env, io};
|
use std::{env, io};
|
||||||
|
|
||||||
use aoc_2022_13::{parse_input, Pair, Segment};
|
use aoc_2022_13::parse_input;
|
||||||
|
|
||||||
fn main() -> io::Result<()> {
|
fn main() -> io::Result<()> {
|
||||||
let infile_path = env::args().nth(1).expect("input file");
|
let infile_path = env::args().nth(1).expect("input file");
|
||||||
@ -17,62 +17,12 @@ fn solve(path: &str) -> io::Result<u32> {
|
|||||||
let result = pairs
|
let result = pairs
|
||||||
.iter()
|
.iter()
|
||||||
.enumerate()
|
.enumerate()
|
||||||
.filter_map(|(i, pair)| match is_in_right_order(&pair) {
|
.filter_map(|(i, (a, b))| if a < b { Some(i + 1) } else { None })
|
||||||
Ordered::Yes => Some(i + 1),
|
|
||||||
_ => None,
|
|
||||||
})
|
|
||||||
.sum::<usize>();
|
.sum::<usize>();
|
||||||
|
|
||||||
Ok(result as u32)
|
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)]
|
#[cfg(test)]
|
||||||
mod test {
|
mod test {
|
||||||
use super::*;
|
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::{
|
use std::{
|
||||||
|
cmp::Ordering,
|
||||||
fmt,
|
fmt,
|
||||||
fs::File,
|
fs::File,
|
||||||
io::{self, Read},
|
io::{self, Read},
|
||||||
@ -7,12 +8,33 @@ use std::{
|
|||||||
|
|
||||||
pub type Pair = (Segment, Segment);
|
pub type Pair = (Segment, Segment);
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone, PartialEq, Eq)]
|
||||||
pub enum Segment {
|
pub enum Segment {
|
||||||
Num(u32),
|
Num(u32),
|
||||||
List(Vec<Segment>),
|
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 {
|
impl fmt::Debug for Segment {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
match self {
|
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>>
|
pub fn parse_input<P>(path: P) -> io::Result<Vec<Pair>>
|
||||||
where
|
where
|
||||||
P: AsRef<Path>,
|
P: AsRef<Path>,
|
||||||
|
@ -9,4 +9,4 @@
|
|||||||
- [2019](2019/README.md) (0% completed)
|
- [2019](2019/README.md) (0% completed)
|
||||||
- [2020](2020/README.md) (20% completed)
|
- [2020](2020/README.md) (20% completed)
|
||||||
- [2021](2021/README.md) (68% completed)
|
- [2021](2021/README.md) (68% completed)
|
||||||
- [2022](2022/README.md) (48% completed)
|
- [2022](2022/README.md) (50% completed)
|
||||||
|
Loading…
Reference in New Issue
Block a user