chore: fmt + clippy + time on day 5

This commit is contained in:
Xavier Morel
2024-12-05 13:11:30 +01:00
parent f551c3cabe
commit e3135f492f
2 changed files with 58 additions and 50 deletions

View File

@@ -25,8 +25,9 @@ Solutions for [Advent of Code](https://adventofcode.com/) in [Rust](https://www.
| [Day 2](./src/bin/02.rs) | `215.6µs` | `371.6µs` | | [Day 2](./src/bin/02.rs) | `215.6µs` | `371.6µs` |
| [Day 3](./src/bin/03.rs) | `652.5µs` | `736.7µs` | | [Day 3](./src/bin/03.rs) | `652.5µs` | `736.7µs` |
| [Day 4](./src/bin/04.rs) | `5.6ms` | `2.4ms` | | [Day 4](./src/bin/04.rs) | `5.6ms` | `2.4ms` |
| [Day 5](./src/bin/05.rs) | `3.7ms` | `9.7ms` |
**Total: 10.13ms** **Total: 23.53ms**
<!--- benchmarking table ---> <!--- benchmarking table --->
--- ---

View File

@@ -2,15 +2,14 @@ advent_of_code::solution!(5);
#[derive(Debug)] #[derive(Debug)]
struct Rules { struct Rules {
rules: Vec<(u32, u32)> rules: Vec<(u32, u32)>,
} }
impl From<&[&str]> for Rules { impl From<&[&str]> for Rules {
fn from(lines: &[&str]) -> Self { fn from(lines: &[&str]) -> Self {
let mut rules: Vec<(u32, u32)> = lines let mut rules: Vec<(u32, u32)> = lines
.into_iter() .iter()
.map( .map(|line| {
|line| {
let pages = line let pages = line
.split("|") .split("|")
.map(|page| page.parse::<u32>().expect("invalid numeric in rules")) .map(|page| page.parse::<u32>().expect("invalid numeric in rules"))
@@ -19,8 +18,7 @@ impl From<&[&str]> for Rules {
[a, b] => (*a, *b), [a, b] => (*a, *b),
_ => panic!("invalid input: invalid rule"), _ => panic!("invalid input: invalid rule"),
} }
} })
)
.collect(); .collect();
rules.sort(); rules.sort();
Self { rules } Self { rules }
@@ -28,26 +26,24 @@ impl From<&[&str]> for Rules {
} }
impl Rules { impl Rules {
fn pages_after(&self, page: u32) -> Vec::<u32> { fn pages_after(&self, page: u32) -> Vec<u32> {
self self.rules
.rules
.clone() .clone()
.into_iter() .into_iter()
.filter_map(|r| match r { .filter_map(|r| match r {
(p1, p2) if p1 == page => Some(p2), (p1, p2) if p1 == page => Some(p2),
_ => None _ => None,
}) })
.collect() .collect()
} }
fn pages_before(&self, page: u32) -> Vec::<u32> { fn pages_before(&self, page: u32) -> Vec<u32> {
self self.rules
.rules
.clone() .clone()
.into_iter() .into_iter()
.filter_map(|r| match r { .filter_map(|r| match r {
(p1, p2) if p2 == page => Some(p1), (p1, p2) if p2 == page => Some(p1),
_ => None _ => None,
}) })
.collect() .collect()
} }
@@ -56,24 +52,28 @@ impl Rules {
let mut pages_with_order: Vec<(u32, Vec<u32>, Vec<u32>)> = pages let mut pages_with_order: Vec<(u32, Vec<u32>, Vec<u32>)> = pages
.clone() .clone()
.into_iter() .into_iter()
.map(|p| .map(|p| {
( (
p, p,
self.pages_before(p).into_iter().filter(|pp| pages.contains(pp)).collect(), self.pages_before(p)
self.pages_after(p).into_iter().filter(|pp| pages.contains(pp)).collect(), .into_iter()
) .filter(|pp| pages.contains(pp))
.collect(),
self.pages_after(p)
.into_iter()
.filter(|pp| pages.contains(pp))
.collect(),
) )
})
.collect(); .collect();
pages_with_order.sort_by_key( pages_with_order.sort_by_key(|(_, before, after)| (before.len(), after.len()));
|(p, before, after)| (before.len(), after.len())
);
pages_with_order.into_iter().map(|(p, _, _)| p).collect() pages_with_order.into_iter().map(|(p, _, _)| p).collect()
} }
} }
#[derive(Debug)] #[derive(Debug)]
struct ImpressionOrder { struct ImpressionOrder {
pages: Vec<u32> pages: Vec<u32>,
} }
impl ImpressionOrder { impl ImpressionOrder {
@@ -82,13 +82,13 @@ impl ImpressionOrder {
if length % 2 == 0 { if length % 2 == 0 {
None None
} else { } else {
Some(self.pages[ (length / 2) as usize ]) Some(self.pages[length / 2])
} }
} }
fn fix_order(&self, rules: &Rules) -> Self { fn fix_order(&self, rules: &Rules) -> Self {
Self { Self {
pages: rules.get_correct_pages_order(self.pages.clone()) pages: rules.get_correct_pages_order(self.pages.clone()),
} }
} }
@@ -107,41 +107,48 @@ impl ImpressionOrder {
impl TryFrom<&&str> for ImpressionOrder { impl TryFrom<&&str> for ImpressionOrder {
type Error = (); type Error = ();
fn try_from(line: &&str) -> Result<Self, Self::Error> { fn try_from(line: &&str) -> Result<Self, Self::Error> {
let pages = line.split(",").flat_map(|page| page.parse::<u32>()).collect::<Vec<u32>>(); let pages = line
.split(",")
.flat_map(|page| page.parse::<u32>())
.collect::<Vec<u32>>();
Ok(Self { pages }) Ok(Self { pages })
} }
} }
pub fn part_one(input: &str) -> Option<u32> { pub fn part_one(input: &str) -> Option<u32> {
let input = input let input = input.lines().collect::<Vec<&str>>();
.lines() let input = input.split(|s| s.is_empty()).collect::<Vec<&[&str]>>();
.collect::<Vec<&str>>();
let input = input
.split(|s|s.is_empty())
.collect::<Vec<&[&str]>>();
let rules: Rules = input[0].into(); let rules: Rules = input[0].into();
input[1] input[1]
.into_iter() .iter()
.flat_map(ImpressionOrder::try_from) .flat_map(ImpressionOrder::try_from)
.filter_map(|o| if o.is_valid(&rules) { o.middle_page() } else { None }) .filter_map(|o| {
if o.is_valid(&rules) {
o.middle_page()
} else {
None
}
})
.sum::<u32>() .sum::<u32>()
.into() .into()
} }
pub fn part_two(input: &str) -> Option<u32> { pub fn part_two(input: &str) -> Option<u32> {
let input = input let input = input.lines().collect::<Vec<&str>>();
.lines() let input = input.split(|s| s.is_empty()).collect::<Vec<&[&str]>>();
.collect::<Vec<&str>>();
let input = input
.split(|s|s.is_empty())
.collect::<Vec<&[&str]>>();
let rules: Rules = input[0].into(); let rules: Rules = input[0].into();
input[1] input[1]
.into_iter() .iter()
.flat_map(ImpressionOrder::try_from) .flat_map(ImpressionOrder::try_from)
.filter_map(|o| if !o.is_valid(&rules) { o.fix_order(&rules).middle_page() } else { None }) .filter_map(|o| {
if !o.is_valid(&rules) {
o.fix_order(&rules).middle_page()
} else {
None
}
})
.sum::<u32>() .sum::<u32>()
.into() .into()
} }