Skip to content

Instantly share code, notes, and snippets.

@udoprog
Created December 1, 2022 05:09
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save udoprog/eb96579ce13e6f91c450c0bcc0e17b48 to your computer and use it in GitHub Desktop.
Save udoprog/eb96579ce13e6f91c450c0bcc0e17b48 to your computer and use it in GitHub Desktop.
use std::path::Path;
use anyhow::{Context, Result};
use thiserror::Error;
#[derive(Debug, Error)]
enum Error {
#[error("{0}:{1}:{2}: expected more input")]
Expected(Box<Path>, usize, usize),
#[error("{0}:{1}:{2}: bad input")]
BadInput(Box<Path>, usize, usize),
#[error("missing top entry")]
MissingTop,
}
fn main() -> Result<()> {
let lines = parse("input.txt")?;
let mut totals = Vec::new();
for elf in lines {
totals.push(elf.calories.iter().sum());
}
totals.sort();
let top3: u32 = totals.iter().rev().take(3).sum();
let top1 = *totals.last().ok_or(Error::MissingTop)?;
Ok(())
}
struct Elf {
calories: Vec<u32>,
}
/// Parse input lines.
fn parse<P>(path: P) -> Result<Vec<Elf>> where P: AsRef<Path> {
let path = path.as_ref();
let string = std::fs::read_to_string(path)?;
let mut output = Vec::new();
let mut calories = Vec::new();
for (n, line) in string.lines().enumerate() {
if line.trim().is_empty() {
output.push(Elf { calories: std::mem::take(&mut calories) });
continue;
}
let mut cols = line.split(' ');
calories.push(cols.next().ok_or(Error::Expected(path.into(), n + 1, 0))?.parse().context(Error::BadInput(path.into(), n + 1, 0))?);
}
if !calories.is_empty() {
output.push(Elf { calories });
}
Ok(output)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment