Add Rust day 11

main
Bram 2024-12-16 16:37:05 +00:00
parent f78ab44ab2
commit 85d9d0c910
5 changed files with 104 additions and 3 deletions

1
inputs/11.txt Normal file
View File

@ -0,0 +1 @@
64599 31 674832 2659361 1 0 8867 321

91
src/day_11/mod.rs Normal file
View File

@ -0,0 +1,91 @@
use crate::utils;
use std::collections::HashMap;
type Collection = HashMap<Stone, Count>;
type Count = u64;
type Stone = u64;
pub fn answer(text : String) -> ( Count, Count ) {
let coll = stones_from_string(text);
let c_25 = blink_at_collection_times(coll, 25);
let p1 : Count = collection_size(&c_25);
let c_75 = blink_at_collection_times(c_25, 50);
let p2 : Count = collection_size(&c_75);
( p1, p2 )
}
fn blink_at_collection(coll : &Collection) -> Collection {
let mut newc : Collection = HashMap::new();
for (key, value) in coll.iter() {
let (stone1, mstone2) = blink_stone(*key);
newc.entry(stone1)
.and_modify(|counter| *counter += *value)
.or_insert(*value);
if let Some(stone2) = mstone2 {
newc.entry(stone2)
.and_modify(|counter| *counter += *value)
.or_insert(*value);
}
}
newc
}
fn blink_at_collection_times(start : Collection, n : u8) -> Collection {
let mut coll : Collection = start;
for _ in 0..n {
coll = blink_at_collection(&coll);
}
coll
}
fn blink_stone(stone : Stone) -> (Stone, Option<Stone>) {
if stone == 0 {
( 1, None )
} else if let Some(( s1, s2 )) = split_stone(&stone) {
( s1, Some(s2) )
} else {
( 2024 * stone, None )
}
}
fn collection_size(coll : &Collection) -> Count {
coll.iter().map(|(_, v)| v).sum()
}
fn split_stone(stone : &Stone) -> Option<(Stone, Stone)> {
let s : String = stone.to_string();
if s.len() % 2 == 0 {
let i = s.len() / 2;
let s1 = str_to_stone(&s[..i])?;
let s2 = str_to_stone(&s[i..])?;
Some(( s1, s2 ))
} else {
None
}
}
fn stones_from_string(s : String) -> Collection {
let mut collection = HashMap::new();
for stone in s.split(" ").filter_map(str_to_stone) {
collection.entry(stone)
.and_modify(|counter| *counter = *counter + 1)
.or_insert(1);
}
collection
}
fn str_to_stone(s : &str) -> Option<Stone> {
s.trim().to_string().parse::<Stone>().ok()
}

View File

@ -8,6 +8,7 @@ mod day_07;
mod day_08;
mod day_09;
mod day_10;
mod day_11;
mod utils;
use std::time::Duration;
@ -78,3 +79,10 @@ pub fn day_10() -> DailyOutput {
( p1 as u128, p2 as u128, d )
}
pub fn day_11() -> DailyOutput {
let s : String = read_from_file("inputs/11.txt");
let (p1, p2, d) = diagnostics::benchmark(s, day_11::answer);
( p1 as u128, p2 as u128, d )
}

View File

@ -13,6 +13,7 @@ fn main() {
aoc.insert(8, aoc_2024::day_08());
aoc.insert(9, aoc_2024::day_09());
aoc.insert(10, aoc_2024::day_10());
aoc.insert(11, aoc_2024::day_11());
aoc.show_diagnostics();
}

View File

@ -29,7 +29,7 @@ impl AdventOfCode {
}
pub fn show_diagnostics(&self) {
println!("| | {: ^14} | {: ^14} | Duration |",
println!("| | {: ^15} | {: ^15} | Duration |",
"Part 1", "Part 2"
);
@ -70,7 +70,7 @@ impl DayResults {
let r = horizontal_bar('#', ' ', 4.0 * BAR_WIDTH_UNIT * (fraction - 0.75), BAR_WIDTH_UNIT);
format!(
"| Day {: >2} | {: >14} | {: >14} | {: >6}ms | [{: <}{: <6}{: <6}",
"| Day {: >2} | {: >15} | {: >15} | {: >6}ms | [{: <}{: <6}{: <6}",
day, self.part_1, self.part_2, self.duration.as_millis(),
g.as_str().green(), o.as_str().yellow(), r.as_str().red()
)
@ -86,7 +86,7 @@ pub fn benchmark<A,B>(s : String, f : fn(String) -> ( A, B )) -> ( A, B, Duratio
}
fn empty_diagnostic(day : usize) -> String {
format!("| Day {: >2} | {:->14} | {:->14} | {:->8} | [", day, "", "", "")
format!("| Day {: >2} | {:->15} | {:->15} | {:->8} | [", day, "", "", "")
}
fn horizontal_bar(full : char, empty : char, width : f32, max_width : f32) -> String {