diff options
| author | Shivesh Mandalia <mail@shivesh.org> | 2022-12-20 14:08:29 +0000 |
|---|---|---|
| committer | Shivesh Mandalia <mail@shivesh.org> | 2022-12-20 14:08:29 +0000 |
| commit | cc5b39318201ffbea172195cbd2ac28cb48f6042 (patch) | |
| tree | 9ea07ae0754133b4f31160181aa343097d221e03 /day01b/src | |
| download | advent_of_code_2022-cc5b39318201ffbea172195cbd2ac28cb48f6042.tar.gz advent_of_code_2022-cc5b39318201ffbea172195cbd2ac28cb48f6042.zip | |
Initial commit
Diffstat (limited to 'day01b/src')
| -rw-r--r-- | day01b/src/main.rs | 106 |
1 files changed, 106 insertions, 0 deletions
diff --git a/day01b/src/main.rs b/day01b/src/main.rs new file mode 100644 index 0000000..4c880c4 --- /dev/null +++ b/day01b/src/main.rs @@ -0,0 +1,106 @@ +#![feature(binary_heap_into_iter_sorted)] + +/// --- Part Two --- +/// +/// By the time you calculate the answer to the Elves' question, they've already realized that the +/// Elf carrying the most Calories of food might eventually run out of snacks. +/// +/// To avoid this unacceptable situation, the Elves would instead like to know the total Calories +/// carried by the top three Elves carrying the most Calories. That way, even if one of those Elves +/// runs out of snacks, they still have two backups. +/// +/// In the example above, the top three Elves are the fourth Elf (with 24000 Calories), then the +/// third Elf (with 11000 Calories), then the fifth Elf (with 10000 Calories). The sum of the +/// Calories carried by these three elves is 45000. +/// +/// Find the top three Elves carrying the most Calories. How many Calories are those Elves carrying +/// in total? +use clap::Parser; + +use std::collections::BinaryHeap; +use std::fs::File; +use std::io::prelude::*; +use std::io::BufReader; +use std::path::PathBuf; + +const FILEPATH: &'static str = "examples/input.txt"; + +#[derive(Parser, Debug)] +#[clap(author, version, about, long_about = None)] +struct Cli { + #[clap(short, long, default_value = FILEPATH)] + file: PathBuf, +} + +#[derive(Copy, Clone, Debug, Eq, Hash, PartialEq)] +struct CalorieCount { + elf: usize, + calories: usize, +} + +impl PartialOrd for CalorieCount { + fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> { + Some(self.cmp(other)) + } +} + +impl Ord for CalorieCount { + fn cmp(&self, other: &Self) -> std::cmp::Ordering { + self.calories.cmp(&other.calories) + } +} + +fn main() { + let args = Cli::parse(); + + let file = File::open(&args.file).unwrap(); + let mut reader = BufReader::new(file); + + let mut heap = BinaryHeap::new(); + let mut line = String::new(); + let mut calorie_count = CalorieCount { + elf: 1, + calories: 0, + }; + while let Ok(bytes) = reader.read_line(&mut line) { + // EOF + if bytes == 0 { + heap.push(calorie_count); + break; + } + + // Newlines + let tline = line.trim(); + if tline.is_empty() { + // Push onto the binary heap + heap.push(calorie_count); + calorie_count.calories = 0; + calorie_count.elf += 1; + continue; + } + + // Parse the calories + let calories = tline.parse::<usize>().unwrap(); + + // Accumulate the calorie count for this elf + calorie_count.calories += calories; + + // Clear the line for the next iteration + line.clear(); + } + + // Find the elf carrying the most calories + let res = heap + .into_iter_sorted() + .inspect(|x| println!("calories={:6} elf={}", x.calories, x.elf)) + .take(3) + .fold(0usize, |acc, x| acc + x.calories); + println!("The top 3 elves are carry {res} calories"); + + let mut cals = include_str!("../examples/input.txt") + .split("\n\n") + .map(|e| e.lines().map(|c| c.parse::<u32>().unwrap()).sum()) + .collect::<Vec<u32>>(); + cals.sort_unstable(); + println!("{}", cals.into_iter().rev().take(3).sum::<u32>()); +} |
