Solve day 5 in Rust
This commit is contained in:
parent
bf1cac4e94
commit
88c138baf0
@ -5,10 +5,17 @@ use puzzles::day1;
|
|||||||
use puzzles::day2;
|
use puzzles::day2;
|
||||||
use puzzles::day3;
|
use puzzles::day3;
|
||||||
use puzzles::day4;
|
use puzzles::day4;
|
||||||
|
use puzzles::day5;
|
||||||
use std::fs;
|
use std::fs;
|
||||||
use std::time::{Duration, Instant};
|
use std::time::{Duration, Instant};
|
||||||
|
|
||||||
const PUZZLES: [&dyn SomePuzzle; 4] = [&day1::PUZZLE, &day2::PUZZLE, &day3::PUZZLE, &day4::PUZZLE];
|
const PUZZLES: [&dyn SomePuzzle; 5] = [
|
||||||
|
&day1::PUZZLE,
|
||||||
|
&day2::PUZZLE,
|
||||||
|
&day3::PUZZLE,
|
||||||
|
&day4::PUZZLE,
|
||||||
|
&day5::PUZZLE,
|
||||||
|
];
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
[false, true].iter().for_each(|is_real_data| {
|
[false, true].iter().for_each(|is_real_data| {
|
||||||
|
|||||||
82
rust/puzzles/day5.rs
Normal file
82
rust/puzzles/day5.rs
Normal file
@ -0,0 +1,82 @@
|
|||||||
|
use crate::puzzle::Puzzle;
|
||||||
|
use nom::{
|
||||||
|
Parser,
|
||||||
|
character::complete::{char, newline, usize},
|
||||||
|
combinator::eof,
|
||||||
|
error::Error,
|
||||||
|
multi::{separated_list0, separated_list1},
|
||||||
|
sequence::{separated_pair, terminated},
|
||||||
|
};
|
||||||
|
|
||||||
|
pub const PUZZLE: Puzzle<(Vec<Range>, Vec<usize>), 2> = Puzzle {
|
||||||
|
number: 5,
|
||||||
|
parser: |input| {
|
||||||
|
terminated::<_, _, Error<&str>, _, _>(
|
||||||
|
separated_pair(
|
||||||
|
separated_list1(
|
||||||
|
newline,
|
||||||
|
separated_pair(usize, char('-'), usize)
|
||||||
|
.map(|(lower, upper)| Range { lower, upper }),
|
||||||
|
),
|
||||||
|
(newline, newline),
|
||||||
|
separated_list0(newline, usize),
|
||||||
|
),
|
||||||
|
(newline, eof),
|
||||||
|
)
|
||||||
|
.parse(input)
|
||||||
|
.unwrap()
|
||||||
|
.1
|
||||||
|
},
|
||||||
|
parts: [
|
||||||
|
|(ranges, vals)| {
|
||||||
|
vals.iter()
|
||||||
|
.filter(|v| ranges.iter().any(|r| r.contains(**v)))
|
||||||
|
.count()
|
||||||
|
.to_string()
|
||||||
|
},
|
||||||
|
|(ranges, _)| {
|
||||||
|
let mut sorted_ranges = ranges.clone();
|
||||||
|
sorted_ranges.sort_by(|a, b| b.lower.cmp(&a.lower));
|
||||||
|
let merged: Vec<Range> = sorted_ranges
|
||||||
|
.into_iter()
|
||||||
|
.rfold(Vec::new(), |acc, new| add_interval(new, acc));
|
||||||
|
merged.iter().map(|r| r.length()).sum::<usize>().to_string()
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
|
|
||||||
|
#[derive(Clone, Debug)]
|
||||||
|
pub struct Range {
|
||||||
|
lower: usize,
|
||||||
|
upper: usize,
|
||||||
|
}
|
||||||
|
impl Range {
|
||||||
|
fn length(&self) -> usize {
|
||||||
|
self.upper - self.lower + 1
|
||||||
|
}
|
||||||
|
fn contains(&self, n: usize) -> bool {
|
||||||
|
n >= self.lower && n <= self.upper
|
||||||
|
}
|
||||||
|
fn extend(&self, upper: usize) -> Range {
|
||||||
|
Range {
|
||||||
|
lower: self.lower,
|
||||||
|
upper: self.upper.max(upper),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn add_interval(new: Range, mut ranges: Vec<Range>) -> Vec<Range> {
|
||||||
|
if ranges.is_empty() {
|
||||||
|
vec![new]
|
||||||
|
} else {
|
||||||
|
let first = &ranges[0];
|
||||||
|
if first.contains(new.lower) {
|
||||||
|
ranges[0] = first.extend(new.upper);
|
||||||
|
ranges
|
||||||
|
} else {
|
||||||
|
let mut result = vec![new];
|
||||||
|
result.append(&mut ranges);
|
||||||
|
result
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -2,3 +2,4 @@ pub(crate) mod day1;
|
|||||||
pub(crate) mod day2;
|
pub(crate) mod day2;
|
||||||
pub(crate) mod day3;
|
pub(crate) mod day3;
|
||||||
pub(crate) mod day4;
|
pub(crate) mod day4;
|
||||||
|
pub(crate) mod day5;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user