#![feature(binary_heap_into_iter_sorted)] /// --- Day 1: Calorie Counting --- /// /// Santa's reindeer typically eat regular reindeer food, but they need a lot of magical energy to /// deliver presents on Christmas. For that, their favourite snack is a special type of star fruit /// that only grows deep in the jungle. The Elves have brought you on their annual expedition to /// the grove where the fruit grows. /// /// To supply enough magical energy, the expedition needs to retrieve a minimum of fifty stars by /// December 25th. Although the Elves assure you that the grove has plenty of fruit, you decide to /// grab any fruit you see along the way, just in case. /// /// Collect stars by solving puzzles. Two puzzles will be made available on each day in the Advent /// calendar; the second puzzle is unlocked when you complete the first. Each puzzle grants one /// star. Good luck! /// /// The jungle must be too overgrown and difficult to navigate in vehicles or access from the air; /// the Elves' expedition traditionally goes on foot. As your boats approach land, the Elves begin /// taking inventory of their supplies. One important consideration is food - in particular, the /// number of Calories each Elf is carrying (your puzzle input). /// /// The Elves take turns writing down the number of Calories contained by the various meals, /// snacks, rations, etc. that they've brought with them, one item per line. Each Elf separates /// their own inventory from the previous Elf's inventory (if any) by a blank line. /// /// For example, suppose the Elves finish writing their items' Calories and end up with the /// following list: /// /// ``` /// 1000 /// 2000 /// 3000 /// /// 4000 /// /// 5000 /// 6000 /// /// 7000 /// 8000 /// 9000 /// /// 10000 /// ``` /// /// This list represents the Calories of the food carried by five Elves: /// /// The first Elf is carrying food with 1000, 2000, and 3000 Calories, a total of 6000 Calories. /// The second Elf is carrying one food item with 4000 Calories. /// The third Elf is carrying food with 5000 and 6000 Calories, a total of 11000 Calories. /// The fourth Elf is carrying food with 7000, 8000, and 9000 Calories, a total of 24000 Calories. /// The fifth Elf is carrying one food item with 10000 Calories. /// /// In case the Elves get hungry and need extra snacks, they need to know which Elf to ask: they'd /// like to know how many Calories are being carried by the Elf carrying the most Calories. In the /// example above, this is 24000 (carried by the fourth Elf). /// /// Find the Elf carrying the most Calories. How many total Calories is that Elf carrying? 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 { 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::().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.peek().unwrap(); println!( "The most amount of calories carried by an elf is {} and is carried by elf {}", res.calories, res.elf ); let _ = heap .into_iter_sorted() .inspect(|x| println!("calories={:6} elf={}", x.calories, x.elf)) .take(10) .last(); println!( "{}", include_str!("../examples/input.txt") .split("\n\n") .map(|e| e.lines().map(|c| c.parse::().unwrap()).sum::()) .max() .unwrap() ); }