Metadata
-
Date
-
Tagged
-
Part of series
- Advent of Code 2024 Day 1
- Advent of Code 2024 Day 2
- Advent of Code 2024 Day 3
- Advent of Code 2024 Day 4
- Advent of Code 2024 Day 5
- Advent of Code 2024 Day 6
- Advent of Code 2024 Day 7
- Advent of Code 2024 Day 8
- Advent of Code 2024 Day 9
- Advent of Code 2024 Day 10
- Advent of Code 2024 Day 11
- Advent of Code 2024 Day 12
- Advent of Code 2024 Day 13
- Advent of Code 2024 Day 14
- Advent of Code 2024 Day 15
- Advent of Code 2024 Day 16
- Advent of Code 2024 Day 17
- Advent of Code 2024 Day 18
- Advent of Code 2024 Day 19
- Advent of Code 2024 Day 20
- Advent of Code 2024 Day 21
- Advent of Code 2024 Day 22
- Advent of Code 2024 Day 23
- Advent of Code 2024 Day 24
- Advent of Code 2024 Day 25
-
Older post
-
Newer post
Advent of Code 2024 Day 11
Day 11: Plutonian Pebbles
https://adventofcode.com/2024/day/11
Another day, another familiar location.
You are in a spot with a bunch of numbered stones in a straight line.
An example input looks like this:
0 1 10 99 999
The input is one line. Each stone number is separated by a space.
Each time you blink, the stones change all at once according to a few rules.
Ooh, I know this one, it’s a cellular automaton, like the game of life
The rules for how the (markings on the) stones change:
- 0 becomes 1
- Even number of digit stones turn into 2 new stones:
- Left stone gets the first half of the digits
- Right stone gets the second half of the digits
- Otherwise, the number get multiplied by 2024
Parsing
Because each stone is completely independent, and stones with the same number acts in exactly the same way, I chose to work on a map of key-value pairs where a key is a stone number, and the value is the amount of stones with that number.
Oh, and this is a day again where the numbers can get large.
fn parse(input: &str) -> HashMap<u64, u64> { let mut stones: HashMap<u64, u64> = HashMap::new(); for num in input.split_ascii_whitespace() { let num = num.parse().unwrap(); *stones.entry(num).or_default() += 1; } stones}
Helper
Implementing the rules for what happens when you blink. This helper function takes in a map of stones, and returns a new map of stones.
fn blink(stones: &HashMap<u64, u64>) -> HashMap<u64, u64> { let mut new = HashMap::new(); for (stone, amount) in stones { if *stone == 0 { *new.entry(1).or_default() += amount; } else { let digits = stone.ilog10() + 1; if digits % 2 == 0 { let magnitude = 10u64.pow(digits / 2); *new.entry(stone % magnitude).or_default() += amount; *new.entry(stone / magnitude).or_default() += amount; } else { *new.entry(stone * 2024).or_default() += amount; } } } new}
Part 1
The question asks how many stones there would be after blinking 25 times.
fn part_1(input: &str) -> u64 { let mut stones = parse(input); for _ in 0..25 { stones = blink(&stones); } stones.values().sum()}
Part 2
What was this, blinking for ants?!, it needs to be at least 3 times bigger!
The question asks how many stones there would be after blinking 75 times.
- Take the part 1 code
- Change 25 to 75
- Success
fn part_2(input: &str) -> u64 { let mut stones = parse(input); for _ in 0..75 { stones = blink(&stones); } stones.values().sum()}
Final code
To combine both parts: Looping 75 times and recording the sum at loop number 25.
use std::collections::HashMap;
fn parse(input: &str) -> HashMap<u64, u64> { let mut stones: HashMap<u64, u64> = HashMap::new(); for num in input.split_ascii_whitespace() { let num = num.parse().unwrap(); *stones.entry(num).or_default() += 1; } stones}
fn blink(stones: &HashMap<u64, u64>) -> HashMap<u64, u64> { let mut new = HashMap::new(); for (stone, amount) in stones { if *stone == 0 { *new.entry(1).or_default() += amount; } else { let digits = stone.ilog10() + 1; if digits % 2 == 0 { let magnitude = 10u64.pow(digits / 2); *new.entry(stone % magnitude).or_default() += amount; *new.entry(stone / magnitude).or_default() += amount; } else { *new.entry(stone * 2024).or_default() += amount; } } } new}
fn both(input: &str) -> (u64, u64) { let mut stones = parse(input); let mut p1 = 0; for i in 0..75 { if i == 25 { p1 = stones.values().sum(); } stones = blink(&stones); } (p1, stones.values().sum())}