Add Rust day 11
parent
f78ab44ab2
commit
85d9d0c910
|
@ -0,0 +1 @@
|
||||||
|
64599 31 674832 2659361 1 0 8867 321
|
|
@ -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()
|
||||||
|
}
|
|
@ -8,6 +8,7 @@ mod day_07;
|
||||||
mod day_08;
|
mod day_08;
|
||||||
mod day_09;
|
mod day_09;
|
||||||
mod day_10;
|
mod day_10;
|
||||||
|
mod day_11;
|
||||||
mod utils;
|
mod utils;
|
||||||
|
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
|
@ -78,3 +79,10 @@ pub fn day_10() -> DailyOutput {
|
||||||
|
|
||||||
( p1 as u128, p2 as u128, d )
|
( 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 )
|
||||||
|
}
|
||||||
|
|
|
@ -13,6 +13,7 @@ fn main() {
|
||||||
aoc.insert(8, aoc_2024::day_08());
|
aoc.insert(8, aoc_2024::day_08());
|
||||||
aoc.insert(9, aoc_2024::day_09());
|
aoc.insert(9, aoc_2024::day_09());
|
||||||
aoc.insert(10, aoc_2024::day_10());
|
aoc.insert(10, aoc_2024::day_10());
|
||||||
|
aoc.insert(11, aoc_2024::day_11());
|
||||||
|
|
||||||
aoc.show_diagnostics();
|
aoc.show_diagnostics();
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,7 +29,7 @@ impl AdventOfCode {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn show_diagnostics(&self) {
|
pub fn show_diagnostics(&self) {
|
||||||
println!("| | {: ^14} | {: ^14} | Duration |",
|
println!("| | {: ^15} | {: ^15} | Duration |",
|
||||||
"Part 1", "Part 2"
|
"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);
|
let r = horizontal_bar('#', ' ', 4.0 * BAR_WIDTH_UNIT * (fraction - 0.75), BAR_WIDTH_UNIT);
|
||||||
|
|
||||||
format!(
|
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(),
|
day, self.part_1, self.part_2, self.duration.as_millis(),
|
||||||
g.as_str().green(), o.as_str().yellow(), r.as_str().red()
|
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 {
|
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 {
|
fn horizontal_bar(full : char, empty : char, width : f32, max_width : f32) -> String {
|
||||||
|
|
Loading…
Reference in New Issue