summaryrefslogtreecommitdiffstats
path: root/day01b/src/main.rs
diff options
context:
space:
mode:
authorShivesh Mandalia <mail@shivesh.org>2022-12-20 14:08:29 +0000
committerShivesh Mandalia <mail@shivesh.org>2022-12-20 14:08:29 +0000
commitcc5b39318201ffbea172195cbd2ac28cb48f6042 (patch)
tree9ea07ae0754133b4f31160181aa343097d221e03 /day01b/src/main.rs
downloadadvent_of_code_2022-cc5b39318201ffbea172195cbd2ac28cb48f6042.tar.gz
advent_of_code_2022-cc5b39318201ffbea172195cbd2ac28cb48f6042.zip
Initial commit
Diffstat (limited to 'day01b/src/main.rs')
-rw-r--r--day01b/src/main.rs106
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>());
+}