92 lines
2.4 KiB
Rust
92 lines
2.4 KiB
Rust
|
#![feature(test)]
|
||
|
|
||
|
use std::{collections::BinaryHeap, fs::read_to_string};
|
||
|
|
||
|
fn main() {
|
||
|
let input = read_to_string("input.txt").expect("need input file");
|
||
|
let (max, top3) = initial(&input);
|
||
|
println!("{max}, {top3}");
|
||
|
let (max, top3) = idiomatic(&input);
|
||
|
println!("{max}, {top3}");
|
||
|
}
|
||
|
|
||
|
fn idiomatic(input: &str) -> (u32, u32) {
|
||
|
let mut sums: BinaryHeap<_> = input
|
||
|
.split_terminator("\n\n")
|
||
|
.map(|block| {
|
||
|
block
|
||
|
.split_terminator('\n')
|
||
|
.map(|line| line.parse::<u32>().unwrap_or_default())
|
||
|
.sum()
|
||
|
})
|
||
|
.collect();
|
||
|
let max = sums.pop().unwrap_or_default();
|
||
|
let top3 = max + sums.pop().unwrap_or_default() + sums.pop().unwrap_or_default();
|
||
|
(max, top3)
|
||
|
}
|
||
|
|
||
|
fn initial(input: &str) -> (u32, u32) {
|
||
|
let numbers = input.split_terminator('\n').map(|s| s.parse::<u32>().ok());
|
||
|
let mut elves = vec![0];
|
||
|
for number in numbers {
|
||
|
match number {
|
||
|
Some(ration) => {
|
||
|
*elves.last_mut().unwrap() += ration;
|
||
|
}
|
||
|
None => elves.push(0),
|
||
|
}
|
||
|
}
|
||
|
let (index, max) = elves.iter().enumerate().max_by_key(|(_, v)| **v).unwrap();
|
||
|
let mut elves = elves.clone();
|
||
|
elves.remove(index);
|
||
|
let (index, second) = elves.iter().enumerate().max_by_key(|(_, v)| **v).unwrap();
|
||
|
let mut elves = elves.clone();
|
||
|
elves.remove(index);
|
||
|
let third = elves.iter().max().unwrap();
|
||
|
let top3 = max + second + third;
|
||
|
(*max, top3)
|
||
|
}
|
||
|
|
||
|
#[cfg(test)]
|
||
|
mod tests {
|
||
|
use std::{
|
||
|
fs::File,
|
||
|
io::{BufRead, BufReader},
|
||
|
};
|
||
|
|
||
|
use super::*;
|
||
|
extern crate test;
|
||
|
use test::Bencher;
|
||
|
|
||
|
#[bench]
|
||
|
fn bench_initial(b: &mut Bencher) {
|
||
|
let input = read_to_string("input.txt").expect("need input file");
|
||
|
b.iter(|| initial(&input));
|
||
|
}
|
||
|
|
||
|
#[bench]
|
||
|
fn bench_idiomatic(b: &mut Bencher) {
|
||
|
let input = read_to_string("input.txt").expect("need input file");
|
||
|
b.iter(|| idiomatic(&input));
|
||
|
}
|
||
|
|
||
|
#[bench]
|
||
|
fn bench_read_string(b: &mut Bencher) {
|
||
|
b.iter(|| {
|
||
|
read_to_string("input.txt")
|
||
|
.unwrap()
|
||
|
.split_terminator('\n')
|
||
|
.for_each(drop);
|
||
|
});
|
||
|
}
|
||
|
|
||
|
#[bench]
|
||
|
fn bench_lines(b: &mut Bencher) {
|
||
|
b.iter(|| {
|
||
|
BufReader::new(File::open("input.txt").unwrap())
|
||
|
.lines()
|
||
|
.for_each(drop);
|
||
|
});
|
||
|
}
|
||
|
}
|