Skip to content

Commit

Permalink
Initial implementation - failing
Browse files Browse the repository at this point in the history
  • Loading branch information
madser123 committed Jul 16, 2024
1 parent 2872869 commit c7afb01
Show file tree
Hide file tree
Showing 4 changed files with 149 additions and 1 deletion.
5 changes: 5 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion bin/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,5 @@ scratchcard = { path = "../lib/scratchcard" }
almanac = { path = "../lib/almanac" }
boat_race = { path = "../lib/boat_race" }
camel_cards = { path = "../lib/camel_cards" }
network_nodes = { path = "../lib/network_nodes" }
network_nodes = { path = "../lib/network_nodes" }
oasis = { path = "../lib/oasis" }
6 changes: 6 additions & 0 deletions lib/oasis/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
[package]
name = "oasis"
version = "0.1.0"
edition = "2021"

[dependencies]
136 changes: 136 additions & 0 deletions lib/oasis/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
use std::{num::ParseIntError, str::FromStr};

#[derive(Debug)]
pub enum OasisError {
ParseHistory(ParseIntError),
}

impl From<ParseIntError> for OasisError {
fn from(value: ParseIntError) -> Self {
Self::ParseHistory(value)
}
}

pub type Value = u32;

#[derive(Debug, Clone)]
pub struct Layer(Vec<Value>);

impl Layer {
#[inline(always)]
fn is_all_zero(&self) -> bool {
println!("Is zero? {self:?}");
let sum = self.0.iter().sum::<Value>();
println!("Sum: {sum}");
sum == 0
}

#[inline(always)]
pub fn get_next_layer(&self) -> Option<Self> {
let next = Self(
self.0
.windows(2)
.map(|a| {
let (a, b) = (a[0], a[1]);
let diff = a.abs_diff(b);
println!("Diff {a} | {b} = {diff}");
diff
})
.collect(),
);

if next.is_all_zero() {
return None;
}

Some(next)
}

#[inline(always)]
pub fn last_value(&self) -> Option<&Value> {
self.0.last()
}
}

#[derive(Debug)]
pub struct History(Layer);

impl FromStr for History {
type Err = OasisError;

fn from_str(s: &str) -> Result<Self, Self::Err> {
Ok(Self(Layer(
s.split(' ').map(|x| x.parse::<Value>()).collect::<Result<_, _>>()?,
)))
}
}

impl History {
pub fn calculate_next_value(&self) -> Value {
let mut layers = vec![self.0.clone()];
println!("Calculating layer: {layers:?}");

loop {
let Some(current) = layers.last() else {
unreachable!("Always at least one layer!")
};

if let Some(next) = current.get_next_layer() {
println!("Pushing next layer: {next:?}");
layers.push(next);
} else {
break;
}
}

let mut current = 0u32;

(layers.len()..0).for_each(|index| {
let above_value = index.checked_sub(1).map_or_else(
|| layers.first().expect("No layers").last_value().unwrap_or(&0),
|under| layers[under].last_value().unwrap_or(&0),
);

current = dbg!(current.abs_diff(*above_value));

println!("New current: {current}");
});

current
}
}

#[derive(Debug)]
pub struct Report(Vec<History>);

impl Report {
pub fn get_next_values_sum(&self) -> Value {
self.0.iter().map(|history| history.calculate_next_value()).sum()
}
}

impl FromStr for Report {
type Err = OasisError;

fn from_str(s: &str) -> Result<Self, Self::Err> {
Ok(Self(s.lines().map(History::from_str).collect::<Result<_, _>>()?))
}
}

#[cfg(test)]
mod tests {
use super::*;

const EXAMPLE: &str = "0 3 6 9 12 15
1 3 6 10 15 21
10 13 16 21 30 45";

#[test]
fn solution_1() {
let report = Report::from_str(EXAMPLE).expect("Failed to parse");

println!("Parsed! {report:?}");

assert_eq!(report.get_next_values_sum(), 114);
}
}

0 comments on commit c7afb01

Please sign in to comment.