y2024d11
This commit is contained in:
parent
dd6e9dbe90
commit
c46843cf5a
1
y2024/resources/11_input.txt
Normal file
1
y2024/resources/11_input.txt
Normal file
@ -0,0 +1 @@
|
|||||||
|
5 62914 65 972 0 805922 6521 1639064
|
27
y2024/src/bin/d11.rs
Normal file
27
y2024/src/bin/d11.rs
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
use std::{fs, time::Instant};
|
||||||
|
|
||||||
|
use utils::time::get_elapsed_string;
|
||||||
|
use y2024::days::d11;
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let now = Instant::now();
|
||||||
|
println!("Part 1:");
|
||||||
|
part1();
|
||||||
|
println!("Ran in {}", get_elapsed_string(now.elapsed()));
|
||||||
|
let now = Instant::now();
|
||||||
|
println!("Part 2:");
|
||||||
|
part2();
|
||||||
|
println!("Ran in {}", get_elapsed_string(now.elapsed()));
|
||||||
|
}
|
||||||
|
|
||||||
|
fn part1() {
|
||||||
|
let root = env!("CARGO_MANIFEST_DIR");
|
||||||
|
let content = fs::read_to_string(format!("{root}/resources/11_input.txt")).unwrap();
|
||||||
|
println!("{}", d11::process_part1(&content));
|
||||||
|
}
|
||||||
|
|
||||||
|
fn part2() {
|
||||||
|
let root = env!("CARGO_MANIFEST_DIR");
|
||||||
|
let content = fs::read_to_string(format!("{root}/resources/11_input.txt")).unwrap();
|
||||||
|
println!("{}", d11::process_part2(&content, 75));
|
||||||
|
}
|
155
y2024/src/days/d11.rs
Normal file
155
y2024/src/days/d11.rs
Normal file
@ -0,0 +1,155 @@
|
|||||||
|
use std::collections::HashMap;
|
||||||
|
|
||||||
|
use itertools::Itertools;
|
||||||
|
|
||||||
|
pub fn process_part1(input: &str) -> u64 {
|
||||||
|
let stones = input
|
||||||
|
.split_whitespace()
|
||||||
|
.map(|stone| stone.parse::<u64>().unwrap())
|
||||||
|
.collect_vec();
|
||||||
|
let mut result = stones;
|
||||||
|
for _ in 0..25 {
|
||||||
|
result = blink(result);
|
||||||
|
}
|
||||||
|
let mut test = HashMap::new();
|
||||||
|
for stone in result.iter() {
|
||||||
|
test.entry(stone)
|
||||||
|
.and_modify(|count| *count += 1)
|
||||||
|
.or_insert(1);
|
||||||
|
}
|
||||||
|
result.len() as u64
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn process_part2(input: &str, blinks: u64) -> u64 {
|
||||||
|
let mut stones: HashMap<u64, u64> = HashMap::new();
|
||||||
|
input.split_whitespace().for_each(|stone| {
|
||||||
|
let stone = stone.parse::<u64>().unwrap();
|
||||||
|
stones
|
||||||
|
.entry(stone)
|
||||||
|
.and_modify(|count| *count += 1)
|
||||||
|
.or_insert(1);
|
||||||
|
});
|
||||||
|
let mut stones_after: HashMap<u64, u64> = HashMap::new();
|
||||||
|
for _idx in 0..blinks {
|
||||||
|
for (stone, count) in stones.iter() {
|
||||||
|
if *stone == 0 {
|
||||||
|
stones_after
|
||||||
|
.entry(1)
|
||||||
|
.and_modify(|inner_count| *inner_count += count)
|
||||||
|
.or_insert(*count);
|
||||||
|
} else if (((*stone as f64).log10() + 1.0).floor() as u64) % 2 == 0 {
|
||||||
|
let num_digits = ((*stone as f64).log10() + 1.0).floor() as u64;
|
||||||
|
let digits_per_side = num_digits / 2;
|
||||||
|
let left = stone / 10_u64.pow(digits_per_side as u32);
|
||||||
|
let right = stone % 10_u64.pow(digits_per_side as u32);
|
||||||
|
stones_after
|
||||||
|
.entry(left)
|
||||||
|
.and_modify(|inner_count| *inner_count += count)
|
||||||
|
.or_insert(*count);
|
||||||
|
stones_after
|
||||||
|
.entry(right)
|
||||||
|
.and_modify(|inner_count| *inner_count += count)
|
||||||
|
.or_insert(*count);
|
||||||
|
//stones_after.push(left);
|
||||||
|
//stones_after.push(right);
|
||||||
|
} else {
|
||||||
|
let new_stone = stone * 2024;
|
||||||
|
stones_after
|
||||||
|
.entry(new_stone)
|
||||||
|
.and_modify(|inner_count| *inner_count += count)
|
||||||
|
.or_insert(*count);
|
||||||
|
//stones_after.push(stone * 2024);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
stones = stones_after.clone();
|
||||||
|
stones_after.clear();
|
||||||
|
}
|
||||||
|
stones
|
||||||
|
.into_values()
|
||||||
|
.reduce(|acc, count| acc + count)
|
||||||
|
.unwrap()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn blink(stones: Vec<u64>) -> Vec<u64> {
|
||||||
|
let mut stones_after = Vec::new();
|
||||||
|
for stone in stones {
|
||||||
|
if stone == 0 {
|
||||||
|
stones_after.push(1);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
let num_digits = ((stone as f64).log10() + 1.0).floor() as u64;
|
||||||
|
if num_digits % 2 == 0 {
|
||||||
|
let digits_per_side = num_digits / 2;
|
||||||
|
let left = stone / 10_u64.pow(digits_per_side as u32);
|
||||||
|
let right = stone % 10_u64.pow(digits_per_side as u32);
|
||||||
|
stones_after.push(left);
|
||||||
|
stones_after.push(right);
|
||||||
|
} else {
|
||||||
|
stones_after.push(stone * 2024);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
stones_after
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use itertools::Itertools;
|
||||||
|
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
const INPUT_1: &str = "0 1 10 99 999";
|
||||||
|
const INPUT_2: &str = "125 17";
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_blink_1() {
|
||||||
|
let stones = INPUT_1
|
||||||
|
.split_whitespace()
|
||||||
|
.map(|stone| stone.parse::<u64>().unwrap())
|
||||||
|
.collect_vec();
|
||||||
|
let stones = blink(stones);
|
||||||
|
assert_eq!(stones, vec![1, 2024, 1, 0, 9, 9, 2021976]);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_blink_2() {
|
||||||
|
let stones = INPUT_2
|
||||||
|
.split_whitespace()
|
||||||
|
.map(|stone| stone.parse::<u64>().unwrap())
|
||||||
|
.collect_vec();
|
||||||
|
let mut result = stones;
|
||||||
|
for _ in 0..6 {
|
||||||
|
result = blink(result);
|
||||||
|
}
|
||||||
|
assert_eq!(
|
||||||
|
result,
|
||||||
|
vec![
|
||||||
|
2097446912, 14168, 4048, 2, 0, 2, 4, 40, 48, 2024, 40, 48, 80, 96, 2, 8, 6, 7, 6,
|
||||||
|
0, 3, 2
|
||||||
|
]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn part1() {
|
||||||
|
let result = process_part1(INPUT_2);
|
||||||
|
assert_eq!(result, 55312);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn part2_1() {
|
||||||
|
let result = process_part2(INPUT_1, 1);
|
||||||
|
assert_eq!(result, 7);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn part2_2() {
|
||||||
|
let result = process_part2(INPUT_2, 6);
|
||||||
|
assert_eq!(result, 22);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn part2_3() {
|
||||||
|
let result = process_part2(INPUT_2, 25);
|
||||||
|
assert_eq!(result, 55312);
|
||||||
|
}
|
||||||
|
}
|
@ -9,3 +9,5 @@ pub mod d8;
|
|||||||
pub mod d9;
|
pub mod d9;
|
||||||
|
|
||||||
pub mod d10;
|
pub mod d10;
|
||||||
|
|
||||||
|
pub mod d11;
|
||||||
|
Loading…
Reference in New Issue
Block a user