summaryrefslogtreecommitdiffstats
path: root/day01a/src/main.rs
diff options
context:
space:
mode:
Diffstat (limited to 'day01a/src/main.rs')
-rw-r--r--day01a/src/main.rs154
1 files changed, 154 insertions, 0 deletions
diff --git a/day01a/src/main.rs b/day01a/src/main.rs
new file mode 100644
index 0000000..64b1c7e
--- /dev/null
+++ b/day01a/src/main.rs
@@ -0,0 +1,154 @@
+#![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<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.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::<u32>().unwrap()).sum::<u32>())
+ .max()
+ .unwrap()
+ );
+}