Created
December 9, 2023 11:26
-
-
Save PrakharSrivastav/ef4bbe3786c9545272c14f44e048f202 to your computer and use it in GitHub Desktop.
2023 day 9 (part1 and 2)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#![allow(dead_code)] | |
#[derive(Debug, PartialEq)] | |
struct Input { | |
histories: Vec<History>, | |
} | |
#[derive(Debug, PartialEq)] | |
struct History { | |
seq: Vec<i32>, | |
} | |
impl History { | |
fn add_next(&mut self) { | |
let item = self.seq.last().unwrap() + History::next_item(&self.seq); | |
self.seq.push(item); | |
} | |
fn add_prev(&mut self) { | |
let item = self.seq.first().unwrap() - History::prev_item(&self.seq); | |
self.seq.splice(0..0, vec![item]); | |
} | |
fn next_item(hist: &Vec<i32>) -> i32 { | |
let mut gaps: Vec<i32> = Vec::new(); | |
for i in 0..hist.len() - 1 { | |
gaps.push(hist[i + 1] - hist[i]) | |
} | |
if gaps.iter().all(|el| *el == 0) { | |
return 0; | |
} else if gaps.len() == 1 { | |
return gaps[0]; | |
} | |
gaps[gaps.len() - 1] + History::next_item(&gaps) | |
} | |
fn prev_item(hist: &Vec<i32>) -> i32 { | |
let mut gaps: Vec<i32> = Vec::new(); | |
for i in 0..hist.len() - 1 { | |
gaps.push(hist[i + 1] - hist[i]) | |
} | |
if gaps.len() == 1 { | |
return gaps[0]; | |
} else if gaps.iter().all(|el| *el == 0) { | |
return 0; | |
} | |
gaps[0] - History::prev_item(&gaps) | |
} | |
} | |
impl TryFrom<&str> for History { | |
type Error = &'static str; | |
fn try_from(input: &str) -> Result<Self, Self::Error> { | |
if input.is_empty() { return Err("empty.history.input"); } | |
Ok(History { | |
seq: input.split(' ') | |
.map(|ch| ch.parse::<i32>().unwrap()) | |
.collect() | |
}) | |
} | |
} | |
impl TryFrom<&str> for Input { | |
type Error = &'static str; | |
fn try_from(input: &str) -> Result<Self, Self::Error> { | |
if input.is_empty() { return Err("input.value.empty"); } | |
Ok(Input { | |
histories: input.lines() | |
.map(|line| TryInto::<History>::try_into(line).unwrap()) | |
.collect() | |
}) | |
} | |
} | |
impl Input { | |
fn sum_of_new_next_elements(&mut self) -> i32 { | |
self.histories | |
.iter_mut() | |
.map(|hist| { | |
hist.add_next(); | |
hist | |
}) | |
.map(|hist| *hist.seq.last().unwrap()) | |
.sum() | |
} | |
fn sum_of_new_prev_elements(&mut self) -> i32 { | |
self.histories | |
.iter_mut() | |
.map(|hist| { | |
hist.add_prev(); | |
hist | |
}) | |
.map(|hist| *hist.seq.first().unwrap()) | |
.sum() | |
} | |
} | |
#[cfg(test)] | |
mod tests { | |
use crate::advent_2023::day_09::{History, Input}; | |
#[test] | |
fn test_parse_sample_input() { | |
let input: Input = sample_input().try_into().unwrap(); | |
println!("sample input is {:?}", input); | |
assert_eq!(input, Input { | |
histories: vec![ | |
History { seq: vec![0, 3, 6, 9, 12, 15] }, | |
History { seq: vec![1, 3, 6, 10, 15, 21] }, | |
History { seq: vec![10, 13, 16, 21, 30, 45] }, | |
] | |
}) | |
} | |
#[test] | |
fn test_next_item() { | |
let mut h = History { seq: vec![0, 3, 6, 9, 12, 15] }; | |
h.add_next(); | |
let last = *h.seq.last().unwrap(); | |
println!("next el is {:?}", last); | |
assert_eq!(last, 18); | |
let mut h = History { seq: vec![1, 3, 6, 10, 15, 21] }; | |
h.add_next(); | |
let last = *h.seq.last().unwrap(); | |
println!("next el is {:?}", last); | |
assert_eq!(last, 28); | |
let mut h = History { seq: vec![10, 13, 16, 21, 30, 45] }; | |
h.add_next(); | |
let last = *h.seq.last().unwrap(); | |
println!("next el is {:?}", last); | |
assert_eq!(last, 68); | |
} | |
#[test] | |
fn test_sample_input_part_1() { | |
let mut input: Input = sample_input().try_into().unwrap(); | |
let sum: i32 = input.sum_of_new_next_elements(); | |
println!("sum is {:?}", sum); | |
assert_eq!(sum, 114); | |
} | |
#[test] | |
fn test_prev_item() { | |
let mut h = History { seq: vec![0, 3, 6, 9, 12, 15] }; | |
h.add_prev(); | |
let first = *h.seq.first().unwrap(); | |
println!("first el is {:?}", first); | |
assert_eq!(first, -3); | |
let mut h = History { seq: vec![1, 3, 6, 10, 15, 21] }; | |
h.add_prev(); | |
let first = *h.seq.first().unwrap(); | |
println!("first el is {:?}", first); | |
assert_eq!(first, 0); | |
let mut h = History { seq: vec![10, 13, 16, 21, 30, 45] }; | |
h.add_prev(); | |
let first = *h.seq.first().unwrap(); | |
println!("first el is {:?}", first); | |
assert_eq!(first, 5); | |
} | |
#[test] | |
fn test_sample_input_part_2() { | |
let mut input: Input = sample_input().try_into().unwrap(); | |
let sum: i32 = input.sum_of_new_prev_elements(); | |
println!("sum is {:?}", sum); | |
assert_eq!(sum, 2); | |
} | |
fn sample_input() -> &'static str { | |
"0 3 6 9 12 15 | |
1 3 6 10 15 21 | |
10 13 16 21 30 45" | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment