Skip to content

Commit

Permalink
Implement day09.
Browse files Browse the repository at this point in the history
  • Loading branch information
Oberacda committed Dec 11, 2023
1 parent 63b6e8c commit 1f6b901
Show file tree
Hide file tree
Showing 11 changed files with 361 additions and 12 deletions.
10 changes: 9 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,13 +1,21 @@
[workspace]
resolver = "2"
members = ["day01", "day02", "day03", "day04", "day05", "day06", "day07", "day08"]
members = ["day01", "day02", "day03", "day04", "day05", "day06", "day07", "day08", "day09"]

[workspace.package]
authors = ["David Oberacker <[email protected]>"]
edition = "2021"
description = "Solution for this days Advent of Code exercise"
publish = false

[workspace.dependencies ]
regex = "1.10.2"
anyhow = "1.0.75"
rayon = "1.8.0"
num = "0.4"
itertools = "0.12.0"
ranges = "0.3.3"

[profile.release]
incremental = true
debug = true
Expand Down
2 changes: 1 addition & 1 deletion day02/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,4 @@ name = "day02_part1"
name = "day02_part2"

[dependencies]
regex = "1.10.2"
regex.workspace = true
8 changes: 4 additions & 4 deletions day05/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ name = "day05_part1"
name = "day05_part2"

[dependencies]
regex = "1.10.2"
itertools = "0.12.0"
rayon = "1.7"
ranges = "0.3.3"
regex.workspace = true
rayon.workspace = true
ranges.workspace = true
itertools.workspace = true
2 changes: 1 addition & 1 deletion day06/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,4 @@ name = "day06_part1"
name = "day06_part2"

[dependencies]
rayon = "1.8.0"
rayon.workspace = true
8 changes: 4 additions & 4 deletions day08/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ name = "day08_part1"
name = "day08_part2"

[dependencies]
regex = "1.10.2"
anyhow = "1.0.75"
rayon = "1.8.0"
num = "0.4"
regex.workspace = true
anyhow.workspace = true
rayon.workspace = true
num.workspace = true
2 changes: 1 addition & 1 deletion day08/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,6 @@ fn get_moves_from_location(map: &Map, start_location: &str) -> Option<u64> {

pub fn get_moves_to_solve_ghost(map: &Map) -> Result<u64> {
let moves_to_z_location: Vec<u64> = map.locations.par_iter().filter(|(id, _)| id.ends_with('A')).map(| (x, _)| *x).filter_map(|x| get_moves_from_location(&map, x)).collect();
let moves_count: u64 = moves_to_z_location.par_iter().cloned().reduce(|| 1_u64, |x, y| num::integer::lcm(x, y));
let moves_count: u64 = moves_to_z_location.par_iter().cloned().reduce(|| 1_u64, num::integer::lcm);
Ok(moves_count)
}
200 changes: 200 additions & 0 deletions day09/resources/input.txt

Large diffs are not rendered by default.

3 changes: 3 additions & 0 deletions day09/resources/test_input.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
0 3 6 9 12 15
1 3 6 10 15 21
10 13 16 21 30 45
27 changes: 27 additions & 0 deletions day09/src/bin/day09_part1.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
use std::time::Instant;
use anyhow::Result;
use day09::{get_result_path1, parse_input};

fn main() -> Result<()> {
let input = include_str!("../../resources/input.txt");
let now = Instant::now();
let data = parse_input(input);
let result = get_result_path1(&data)?;
let elapsed = now.elapsed();
println!("Result: {}, Elapsed: {:?}", result, elapsed);
Ok(())
}

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

#[test]
fn run_test_input() -> Result<()>{
let input = include_str!("../../resources/test_input.txt");
let data = parse_input(input);
let result = get_result_path1(&data)?;
assert_eq!(114, result);
Ok(())
}
}
27 changes: 27 additions & 0 deletions day09/src/bin/day09_part2.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
use std::time::Instant;
use anyhow::Result;
use day09::{get_result_path2, parse_input};

fn main() -> Result<()> {
let input = include_str!("../../resources/input.txt");
let now = Instant::now();
let data = parse_input(input);
let result = get_result_path2(&data)?;
let elapsed = now.elapsed();
println!("Result: {}, Elapsed: {:?}", result, elapsed);
Ok(())
}

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

#[test]
fn run_test_input() -> Result<()>{
let input = include_str!("../../resources/test_input.txt");
let data = parse_input(input);
let result = get_result_path2(&data)?;
assert_eq!(2, result);
Ok(())
}
}
84 changes: 84 additions & 0 deletions day09/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
use std::error::Error;
use std::fmt::{Display, Formatter};
use std::str::FromStr;
use anyhow::Result;

#[derive(Debug, Copy, Clone, Eq, PartialEq)]
enum PuzzleError <'a> {
LogicError {
msg: & 'a str
}
}

impl <'a> Display for PuzzleError<'a> {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
write!(f, "Failed to solve puzzle: ").ok();
match self {
PuzzleError::LogicError { msg } => {
write!(f, "{}", msg)
}
}
}
}

impl <'a> Error for PuzzleError <'a> {}

pub fn parse_input(input: &str) -> Vec<Vec<i64>> {
input.lines().map(|x| x.split_whitespace().filter_map(|x| i64::from_str(x).ok()).collect()).collect()
}

pub fn get_result_path1(data: &Vec<Vec<i64>>) -> Result<i64> {
let mut results = Vec::new();
for start_data_sequence in data {
let mut data_sequences = Vec::new();
data_sequences.push(Box::new(start_data_sequence.clone()));
for i in 0..start_data_sequence.len() {
let current_data_sequence = data_sequences.get(i).ok_or(PuzzleError::LogicError { msg: "Could not find data sequence!"})?;
let next_data_sequence: Box<Vec<i64>> = Box::new(current_data_sequence.iter().zip(&current_data_sequence[1..]).map(|(x, y)| y - x).collect());
let result = next_data_sequence.iter().all(|x| x.eq(&0_i64));

data_sequences.push(next_data_sequence);
if result {
break;
}
}

let mut prediction= 0_i64;

for sequence in data_sequences.iter().rev() {
let mut sequence_iter = sequence.iter();
let last = sequence_iter.next_back().ok_or(PuzzleError::LogicError {msg: "Last sequence element missing!"})?;
prediction += last;
}
results.push(prediction);
}
Ok(results.iter().sum::<i64>())
}

pub fn get_result_path2(data: &Vec<Vec<i64>>) -> Result<i64> {
let mut results = Vec::new();
for start_data_sequence in data {
let mut data_sequences = Vec::new();
data_sequences.push(Box::new(start_data_sequence.clone()));
for i in 0..start_data_sequence.len() {
let current_data_sequence = data_sequences.get(i).ok_or(PuzzleError::LogicError { msg: "Could not find data sequence!"})?;
let next_data_sequence: Box<Vec<i64>> = Box::new(current_data_sequence.iter().zip(&current_data_sequence[1..]).map(|(x, y)| y - x).collect());
let result = next_data_sequence.iter().all(|x| x.eq(&0_i64));

data_sequences.push(next_data_sequence);
if result {
break;
}
}

let mut prediction= 0_i64;

for sequence in data_sequences.iter().rev() {
let mut sequence_iter = sequence.iter();
let last = sequence_iter.next().ok_or(PuzzleError::LogicError {msg: "First sequence element missing!"})?;
prediction = last - prediction;
}
results.push(prediction);
}
Ok(results.iter().sum::<i64>())
}

0 comments on commit 1f6b901

Please sign in to comment.