diff options
| -rw-r--r-- | 09_mirage_maintenance/mirage_maintenance.rs | 67 |
1 files changed, 67 insertions, 0 deletions
diff --git a/09_mirage_maintenance/mirage_maintenance.rs b/09_mirage_maintenance/mirage_maintenance.rs new file mode 100644 index 0000000..204f157 --- /dev/null +++ b/09_mirage_maintenance/mirage_maintenance.rs @@ -0,0 +1,67 @@ +pub struct Measurement(Vec<i64>); + +impl From<&str> for Measurement { + fn from(value: &str) -> Self { + Self(value.split(' ').map(|x| x.parse::<i64>().unwrap()).collect()) + } +} + +impl Measurement { + fn differentiate(&self) -> Vec<Vec<i64>> { + let mut table = Vec::new(); + table.push(self.0.clone()); + + loop { + let last = table.last().unwrap(); + let mut new = Vec::new(); + for i in 1..last.len() { + new.push(last[i] - last[i-1]) + } + if new.iter().all(|x| x == &0) { break } + table.push(new); + } + + table + } + + pub fn predict(&self) -> i64 { + let table = self.differentiate(); + let mut last_delta = 0; + for layer in table.iter().rev() { + last_delta += *layer.last().unwrap(); + } + last_delta + } + + pub fn predict_back(&self) -> i64 { + let table = self.differentiate(); + let mut last_delta = 0; + for layer in table.iter().rev() { + last_delta = *layer.first().unwrap() - last_delta; + } + last_delta + } +} + + +fn main() { + let fname = match std::env::args().nth(1) { + None => return eprintln!("no input file given"), + Some(x) => x + }; + + let part_two = std::env::args().any(|x| x == "--part-two"); + + let content = std::fs::read_to_string(fname).unwrap(); + + let prediction_sum : i64 = content.lines() + .map(Measurement::from) + .map(|m| if part_two { m.predict_back() } else { m.predict() }) + .sum(); + + println!( + "{} predictions sum: {}", + if part_two { "backward" } else { "forward" }, + prediction_sum + ); +} |
