Solve 05
This commit is contained in:
parent
57b0474d09
commit
ab29172d43
1 changed files with 90 additions and 0 deletions
90
src/bin/05.rs
Normal file
90
src/bin/05.rs
Normal file
|
|
@ -0,0 +1,90 @@
|
|||
use aoc::*;
|
||||
use itertools::Itertools;
|
||||
|
||||
const INPUT: &str = include_str!("../../input/05");
|
||||
|
||||
fn main() {
|
||||
println!("Part 1: {}", part1(INPUT));
|
||||
println!("Part 2: {}", part2(INPUT));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn example() {
|
||||
assert_example!(part1, "05-test", 3);
|
||||
assert_example!(part2, "05-test", 14);
|
||||
assert_eq!(part2("1-10\n5-6\n\n"), 10);
|
||||
assert_eq!(part2("1-10\n8-20\n\n"), 20);
|
||||
assert_eq!(part2("1-1\n2-2\n3-3\n\n"), 3);
|
||||
assert_eq!(part2("4-4\n\n"), 1);
|
||||
}
|
||||
|
||||
fn part1(input: &str) -> usize {
|
||||
let (ranges, ingredients) = parse_input(input);
|
||||
ingredients
|
||||
.into_iter()
|
||||
.filter(|&i| ranges.contains(i))
|
||||
.count()
|
||||
}
|
||||
|
||||
fn part2(input: &str) -> i64 {
|
||||
let (ranges, _) = parse_input(input);
|
||||
|
||||
let mut sum = 0;
|
||||
let mut lower_bound = ranges.ranges.first().unwrap().from;
|
||||
|
||||
for range in ranges.ranges {
|
||||
let from = range.from.max(lower_bound);
|
||||
if range.to < from {
|
||||
continue;
|
||||
}
|
||||
|
||||
let count = range.to - from + 1;
|
||||
sum += count;
|
||||
|
||||
lower_bound = range.to + 1;
|
||||
}
|
||||
|
||||
sum
|
||||
}
|
||||
|
||||
fn parse_input(input: &str) -> (Ranges, Vec<i64>) {
|
||||
let (ranges, ingredients) = input.split_once("\n\n").unwrap();
|
||||
|
||||
let ranges = Ranges::parse(ranges);
|
||||
let ingredients = ingredients.lines().map(|l| l.parse().unwrap()).collect();
|
||||
(ranges, ingredients)
|
||||
}
|
||||
|
||||
struct Ranges {
|
||||
ranges: Vec<Range>,
|
||||
}
|
||||
|
||||
impl Ranges {
|
||||
fn parse(input: &str) -> Self {
|
||||
let mut ranges = input.lines().map(Range::parse).collect_vec();
|
||||
ranges.sort_by_key(|r| r.from);
|
||||
Self { ranges }
|
||||
}
|
||||
|
||||
fn contains(&self, ingredient: i64) -> bool {
|
||||
self.ranges.iter().any(|r| r.contains(ingredient))
|
||||
}
|
||||
}
|
||||
|
||||
struct Range {
|
||||
from: i64,
|
||||
to: i64,
|
||||
}
|
||||
|
||||
impl Range {
|
||||
fn parse(line: &str) -> Self {
|
||||
let (from, to) = line.split_once('-').unwrap();
|
||||
let from = from.parse().unwrap();
|
||||
let to = to.parse().unwrap();
|
||||
Self { from, to }
|
||||
}
|
||||
|
||||
fn contains(&self, ingredient: i64) -> bool {
|
||||
ingredient >= self.from && ingredient <= self.to
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue