mirror of
https://github.com/mx42/aoc2024.rs.git
synced 2026-01-14 05:49:53 +01:00
chore: fmt + clippy + time on day 5
This commit is contained in:
@@ -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 --->
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|||||||
105
src/bin/05.rs
105
src/bin/05.rs
@@ -2,25 +2,23 @@ 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"))
|
.collect::<Vec<u32>>();
|
||||||
.collect::<Vec<u32>>();
|
match pages.as_slice() {
|
||||||
match pages.as_slice() {
|
[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,16 +82,16 @@ 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()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn is_valid(&self, rules: &Rules) -> bool {
|
fn is_valid(&self, rules: &Rules) -> bool {
|
||||||
let mut invalid_pages: Vec<u32> = Vec::new();
|
let mut invalid_pages: Vec<u32> = Vec::new();
|
||||||
for p in self.pages.clone() {
|
for p in 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()
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user