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 d10;
|
||||
|
||||
pub mod d11;
|
||||
|
Loading…
Reference in New Issue
Block a user