55 lines
1.4 KiB
Rust
55 lines
1.4 KiB
Rust
use aoc_runner_derive::{aoc, aoc_generator};
|
|
use nom::character::complete::multispace0;
|
|
use nom::multi::many1;
|
|
use nom::{character::complete::u64 as parse_u64, IResult};
|
|
|
|
#[aoc_generator(day1)]
|
|
pub fn generator(input: &str) -> Vec<(u64, u64)> {
|
|
many1(parse_line)(input).unwrap().1
|
|
}
|
|
|
|
fn parse_line(input: &str) -> IResult<&str, (u64, u64)> {
|
|
let (input, left) = parse_u64(input)?;
|
|
let (input, _) = multispace0(input)?;
|
|
let (input, right) = parse_u64(input)?;
|
|
let (input, _) = multispace0(input)?;
|
|
Ok((input, (left, right)))
|
|
}
|
|
|
|
#[aoc(day1, part1)]
|
|
pub fn part1(input: &[(u64, u64)]) -> u64 {
|
|
let (mut left, mut right): (Vec<u64>, Vec<u64>) = input.iter().copied().unzip();
|
|
left.sort();
|
|
right.sort();
|
|
left.iter()
|
|
.zip(right.iter())
|
|
.map(|(l, r)| (*l).abs_diff(*r))
|
|
.sum()
|
|
}
|
|
|
|
#[aoc(day1, part2)]
|
|
pub fn part2(input: &[(u64, u64)]) -> usize {
|
|
let (mut left, mut right): (Vec<u64>, Vec<u64>) = input.iter().copied().unzip();
|
|
left.sort();
|
|
right.sort();
|
|
|
|
let mut l;
|
|
let mut r = 0;
|
|
let mut score = 0usize;
|
|
for value in left {
|
|
l = r;
|
|
while l < right.len() && right[l] < value {
|
|
l += 1
|
|
}
|
|
r = l;
|
|
while r < right.len() && right[r] <= value {
|
|
r += 1
|
|
}
|
|
score += (value as usize) * (r - l);
|
|
if r == right.len() - 1 {
|
|
break;
|
|
};
|
|
}
|
|
score
|
|
}
|