AoC/aoc_2024/src/day1.rs

55 lines
1.4 KiB
Rust
Raw Normal View History

2024-12-03 15:45:33 +00:00
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
}