summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJustin Worthe <justin@worthe-it.co.za>2019-12-01 11:27:04 +0200
committerJustin Worthe <justin@worthe-it.co.za>2019-12-01 11:27:04 +0200
commitecfa5bb0f3caf66f05a7b99d204978496dae4bd7 (patch)
tree940f40121c33e2c42dee6c97acf364eadc85570f /src
parent34bffc49705fb31f947ad0f2f45494dc9472e81b (diff)
Dressed day 1 up as a cli app
Diffstat (limited to 'src')
-rw-r--r--src/bin/day_1.rs80
1 files changed, 33 insertions, 47 deletions
diff --git a/src/bin/day_1.rs b/src/bin/day_1.rs
index 7c8f104..b9a6c18 100644
--- a/src/bin/day_1.rs
+++ b/src/bin/day_1.rs
@@ -1,57 +1,56 @@
+use derive_more;
use std::io;
use std::io::prelude::*;
use std::iter;
-use std::iter::Sum;
-use std::num::ParseIntError;
-use std::ops::Add;
-use std::str::FromStr;
+
+use structopt::StructOpt;
+
+#[derive(Debug, StructOpt)]
+#[structopt(name = "Day 1: The Tyranny of the Rocket Equation")]
+/// Calculates the fuel needed for your rocket to save Santa.
+///
+/// The weight of each module is read from stdin, one module weight
+/// per line. See https://adventofcode.com/2019/day/1 for details.
+struct Opt {
+ /// Includes the weight of flue
+ #[structopt(short = "i", long = "include-fuel-weight")]
+ include_fuel_weight: bool,
+}
fn main() {
let stdin = io::stdin();
+ let opt = Opt::from_args();
let input = stdin
.lock()
.lines()
.map(|l| l.unwrap().parse::<Module>().unwrap());
- dbg!(fuel_required(input));
+ println!("{}", fuel_required(input, opt.include_fuel_weight))
}
-// TODO: If this were a nice CLI program, it would probably have a switch to choose between these two rather than doing both?
-fn fuel_required(it: impl Iterator<Item = Module>) -> (Fuel, Fuel) {
- it.map(|m| {
- (
- m.fuel_excluding_fuel_weight(),
- m.fuel_including_fuel_weight(),
- )
- })
- .fold((Fuel(0), Fuel(0)), |(sum_x, sum_y), (x, y)| {
- (sum_x + x, sum_y + y)
+fn fuel_required(it: impl Iterator<Item = Module>, include_fuel_weight: bool) -> Fuel {
+ it.map(if include_fuel_weight {
+ Module::fuel_including_fuel_weight
+ } else {
+ Module::fuel_excluding_fuel_weight
})
+ .sum()
}
+#[derive(Debug, derive_more::FromStr, Clone, Copy)]
struct Module {
weight: Weight,
}
-impl FromStr for Module {
- type Err = ParseIntError;
-
- fn from_str(s: &str) -> Result<Self, Self::Err> {
- Ok(Module {
- weight: Weight(s.parse()?),
- })
- }
-}
-
impl Module {
- fn fuel_excluding_fuel_weight(&self) -> Fuel {
+ fn fuel_excluding_fuel_weight(self) -> Fuel {
self.weight.required_fuel()
}
- fn fuel_including_fuel_weight(&self) -> Fuel {
+ fn fuel_including_fuel_weight(self) -> Fuel {
iter::successors(Some(self.weight.required_fuel()), |fuel| {
- if fuel.weight().is_zero() {
+ if fuel.is_zero() {
None
} else {
Some(fuel.weight().required_fuel())
@@ -61,37 +60,24 @@ impl Module {
}
}
+#[derive(Debug, derive_more::FromStr, Clone, Copy)]
struct Weight(u32);
impl Weight {
- fn is_zero(&self) -> bool {
- self.0 == 0
- }
-
- fn required_fuel(&self) -> Fuel {
+ fn required_fuel(self) -> Fuel {
Fuel((self.0 / 3).saturating_sub(2))
}
}
-#[derive(Debug)]
+#[derive(Debug, derive_more::Add, derive_more::Sum, Clone, Copy, derive_more::Display)]
struct Fuel(u32);
impl Fuel {
- fn weight(&self) -> Weight {
+ fn weight(self) -> Weight {
Weight(self.0)
}
-}
-
-impl Add for Fuel {
- type Output = Self;
-
- fn add(self, other: Self) -> Self {
- Fuel(self.0 + other.0)
- }
-}
-impl Sum for Fuel {
- fn sum<I: Iterator<Item = Self>>(iter: I) -> Self {
- iter.fold(Fuel(0), Add::add)
+ fn is_zero(self) -> bool {
+ self.0 == 0
}
}