generated from janezicmatej/aoc-template
Compare commits
2 Commits
e045b51596
...
0000015049
Author | SHA1 | Date |
---|---|---|
Matej Janezic | 0000015049 | |
Matej Janezic | 00000140d3 |
|
@ -1,17 +1,32 @@
|
|||
use std::{
|
||||
cmp::{max, min},
|
||||
ops::Range,
|
||||
str::FromStr,
|
||||
};
|
||||
|
||||
use aoc::parsers::to_vec;
|
||||
|
||||
type PairRange = (u64, u64);
|
||||
trait RangeExt {
|
||||
fn overlaps(&self, other: &Self) -> bool;
|
||||
}
|
||||
|
||||
impl<T> RangeExt for Range<T>
|
||||
where
|
||||
T: PartialOrd,
|
||||
{
|
||||
fn overlaps(&self, other: &Self) -> bool {
|
||||
self.contains(&other.start) || self.contains(&other.end)
|
||||
}
|
||||
}
|
||||
|
||||
fn build_range(start: u64, range: u64) -> Range<u64> {
|
||||
start..(start + range)
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
struct Mapping {
|
||||
destination: u64,
|
||||
source: u64,
|
||||
range: u64,
|
||||
destination: Range<u64>,
|
||||
source: Range<u64>,
|
||||
}
|
||||
|
||||
struct ParseMappingError;
|
||||
|
@ -22,34 +37,26 @@ impl FromStr for Mapping {
|
|||
let nums: Vec<u64> = to_vec(s, ' ');
|
||||
|
||||
Ok(Self {
|
||||
destination: nums[0],
|
||||
source: nums[1],
|
||||
range: nums[2],
|
||||
destination: build_range(nums[2], nums[0]),
|
||||
source: build_range(nums[1], nums[0]),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl Mapping {
|
||||
fn contains(&self, n: u64) -> bool {
|
||||
n >= self.source && n < self.source + self.range
|
||||
}
|
||||
|
||||
fn contains_any(&self, (s, r): PairRange) -> bool {
|
||||
s < self.source + self.range && s + r > self.source
|
||||
}
|
||||
|
||||
fn map(&self, n: u64) -> u64 {
|
||||
let shift = n - self.source;
|
||||
self.destination + shift
|
||||
let shift = n - self.source.start;
|
||||
self.destination.start + shift
|
||||
}
|
||||
|
||||
fn split_range(&self, (s, r): PairRange) -> [Option<PairRange>; 3] {
|
||||
fn split_range(&self, r: Range<u64>) -> [Option<Range<u64>>; 3] {
|
||||
let mut fences = [
|
||||
s,
|
||||
s + r,
|
||||
max(self.source, s),
|
||||
min(self.source + self.range, s + r),
|
||||
r.start,
|
||||
r.end,
|
||||
max(self.source.start, r.start),
|
||||
min(self.source.end, r.end),
|
||||
];
|
||||
|
||||
fences.sort();
|
||||
|
||||
let mut v = Vec::new();
|
||||
|
@ -58,13 +65,13 @@ impl Mapping {
|
|||
let f = fences[i];
|
||||
let nf = fences[i + 1];
|
||||
if f != nf {
|
||||
v.push(Some((f, nf - f)))
|
||||
v.push(Some(f..(nf - f)))
|
||||
} else {
|
||||
v.push(None)
|
||||
}
|
||||
}
|
||||
|
||||
v[..3].try_into().unwrap()
|
||||
[v[0], v[1], v[2]]
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
use aoc::parsers::to_vec;
|
||||
|
||||
fn win_options((time, distance): (u64, u64)) -> u64 {
|
||||
let discriminant = ((time.pow(2) - 4 * distance) as f64).sqrt();
|
||||
|
||||
|
@ -14,28 +12,34 @@ fn win_options((time, distance): (u64, u64)) -> u64 {
|
|||
}
|
||||
|
||||
pub fn part_one(input: &str) -> Option<u64> {
|
||||
let (upt, upd) = input.split_once('\n')?;
|
||||
let time: Vec<u64> = to_vec(upt.strip_prefix("Time: ")?, ' ');
|
||||
let distance: Vec<u64> = to_vec(upd.strip_prefix("Distance: ")?, ' ');
|
||||
let [time, distance] = input
|
||||
.lines()
|
||||
.map(|l| {
|
||||
l.split_whitespace()
|
||||
.skip(1)
|
||||
.filter_map(|n| n.parse().ok())
|
||||
.collect::<Vec<u64>>()
|
||||
})
|
||||
.collect::<Vec<_>>()
|
||||
.try_into()
|
||||
.ok()?;
|
||||
|
||||
Some(time.into_iter().zip(distance).map(win_options).product())
|
||||
}
|
||||
|
||||
pub fn part_two(input: &str) -> Option<u64> {
|
||||
let (upt, upd) = input.split_once('\n')?;
|
||||
let time: u64 = upt
|
||||
.strip_prefix("Time: ")?
|
||||
.split(' ')
|
||||
.flat_map(|x| x.chars())
|
||||
.collect::<String>()
|
||||
.parse()
|
||||
.ok()?;
|
||||
let distance: u64 = upd
|
||||
.strip_prefix("Distance: ")?
|
||||
.split(' ')
|
||||
.flat_map(|x| x.chars())
|
||||
.collect::<String>()
|
||||
.parse()
|
||||
let [time, distance] = input
|
||||
.lines()
|
||||
.filter_map(|l| {
|
||||
l.split_whitespace()
|
||||
.skip(1)
|
||||
.flat_map(|x| x.chars())
|
||||
.collect::<String>()
|
||||
.parse()
|
||||
.ok()
|
||||
})
|
||||
.collect::<Vec<_>>()
|
||||
.try_into()
|
||||
.ok()?;
|
||||
|
||||
Some(win_options((time, distance)))
|
||||
|
|
Loading…
Reference in New Issue