Skip to content

Instantly share code, notes, and snippets.

@PrakharSrivastav
Created December 9, 2023 11:26
Show Gist options
  • Save PrakharSrivastav/ef4bbe3786c9545272c14f44e048f202 to your computer and use it in GitHub Desktop.
Save PrakharSrivastav/ef4bbe3786c9545272c14f44e048f202 to your computer and use it in GitHub Desktop.
2023 day 9 (part1 and 2)
#![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