summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJustin Worthe <justin@worthe-it.co.za>2019-12-01 09:24:11 +0200
committerJustin Worthe <justin@worthe-it.co.za>2019-12-01 09:24:11 +0200
commit34bffc49705fb31f947ad0f2f45494dc9472e81b (patch)
treec9c9d4c374786cc1e89eff6a07ffcbd6ba65ee99 /src
parentc98244df602a3f3d745f5971e22b1031c3e55770 (diff)
Day 1
Diffstat (limited to 'src')
-rw-r--r--src/bin/day_1.rs97
-rw-r--r--src/main.rs11
2 files changed, 107 insertions, 1 deletions
diff --git a/src/bin/day_1.rs b/src/bin/day_1.rs
new file mode 100644
index 0000000..7c8f104
--- /dev/null
+++ b/src/bin/day_1.rs
@@ -0,0 +1,97 @@
+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;
+
+fn main() {
+ let stdin = io::stdin();
+
+ let input = stdin
+ .lock()
+ .lines()
+ .map(|l| l.unwrap().parse::<Module>().unwrap());
+
+ dbg!(fuel_required(input));
+}
+
+// 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)
+ })
+}
+
+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 {
+ self.weight.required_fuel()
+ }
+
+ fn fuel_including_fuel_weight(&self) -> Fuel {
+ iter::successors(Some(self.weight.required_fuel()), |fuel| {
+ if fuel.weight().is_zero() {
+ None
+ } else {
+ Some(fuel.weight().required_fuel())
+ }
+ })
+ .sum()
+ }
+}
+
+struct Weight(u32);
+
+impl Weight {
+ fn is_zero(&self) -> bool {
+ self.0 == 0
+ }
+
+ fn required_fuel(&self) -> Fuel {
+ Fuel((self.0 / 3).saturating_sub(2))
+ }
+}
+
+#[derive(Debug)]
+struct Fuel(u32);
+
+impl Fuel {
+ 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)
+ }
+}
diff --git a/src/main.rs b/src/main.rs
index e7a11a9..0c24a73 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -1,3 +1,12 @@
+use std::io;
+use std::io::prelude::*;
+
fn main() {
- println!("Hello, world!");
+ let stdin = io::stdin();
+ let answer = string_length_sum(stdin.lock().lines().map(|l| l.unwrap()));
+ dbg!(answer);
+}
+
+fn string_length_sum(it: impl Iterator<Item = String>) -> usize {
+ it.map(|l| l.len()).sum()
}