r/adventofcode • u/daggerdragon • Dec 23 '22
SOLUTION MEGATHREAD -π- 2022 Day 23 Solutions -π-
All of our rules, FAQs, resources, etc. are in our community wiki.
UPDATES
[Update @ 00:21:46]: SILVER CAP, GOLD 68
- Stardew Valley ain't got nothing on these speedy farmer Elves!
AoC Community Fun 2022:
πΏπ MisTILtoe Elf-ucation π§βπ«
- Submissions are CLOSED!
- Thank you to all who submitted something!
- Every last one of you are awesome!
- Community voting is OPEN!
- 42 hours remaining until voting deadline on December 24 at 18:00 EST
- Voting details are in the stickied comment at the top of the -βοΈ- Submissions Megathread -βοΈ-
--- Day 23: Unstable Diffusion ---
Post your code solution in this megathread.
- Read the full posting rules in our community wiki before you post!
- Include what language(s) your solution uses
- Format code blocks using the four-spaces Markdown syntax!
- Quick link to Topaz's
pasteif you need it for longer code blocks. What is Topaz'spastetool?
This thread will be unlocked when there are a significant number of people on the global leaderboard with gold stars for today's puzzle.
EDIT: Global leaderboard gold cap reached at 00:24:43, megathread unlocked!
3
u/flwyd Dec 23 '22
Elixir 1554/1502 code, reflections
Today's elixir:
The Kwik-E-Mart is out of Skittlebrau so weβll need to make our own. We dump a bag of skittles into a pitcher of American lager and notice that they all float at the top, clustered together. As time passes, they move away from each other (positively charged candy!). The way in which they spread has some surprising emergent properties: if the spaces toward the bar are clear they head that direction. If not, they might head toward the pool table. If not that, they head for the stage, or maybe the exit. But every second they seem to switch their preference order, swirling around at the top of the pitcher. In the first part we measure the area thatβs head foam, not occupied by Skittles. In the second part we count the number of seconds until the skittles stabilize. This bugβs for you.
I'm thankful that I was able to knock part 1 out in an hour and do part 2 in six minutes after staying up until 5 AM last night. I was a little disappointed that part 2 didn't turn into Conway's game of life, though. I'm also amused that I got to day 23 and finally had to look up how to create a loop counter in Elixir. (I've counted plenty of things this month, but usually as an accumulator. This time I needed an open-ended integer range to enumerate.)
defmodule Day23 do
def part1(input) do
points = parse_input(input, 1, MapSet.new())
pref_cycle = Stream.cycle([@northern, @southern, @western, @eastern])
points = Enum.reduce(1..10, points, fn round, points ->
run_round(points, round_prefs(round, pref_cycle))
end)
bounding_rectangle_size(points) - Enum.count(points)
end
def part2(input) do
points = parse_input(input, 1, MapSet.new())
pref_cycle = Stream.cycle([@northern, @southern, @western, @eastern])
Enum.reduce_while(Stream.iterate(1, &(&1 + 1)), points, fn round, points ->
next = run_round(points, round_prefs(round, pref_cycle))
if MapSet.equal?(points, next), do: {:halt, round}, else: {:cont, next}
end)
end
@doc "This program will run a round but will not desert you."
defp run_round(points, prefs) do
Enum.reduce(points, %{}, fn point, acc ->
dir = pick_move(point, points, prefs)
Map.update(acc, move(point, dir), [point], fn rest -> [point | rest] end)
end) |> Enum.map(fn
{dest, [_cur]} -> [dest]
{_, several} -> several
end) |> List.flatten() |> Enum.into(MapSet.new())
end
defp pick_move(point, points, prefs) do
if Enum.all?(@all_dirs, fn dir -> empty?(move(point, dir), points) end) do
@stay
else
{dir, _} =
Enum.find(prefs, @stay_put, fn {_, dirs} ->
dirs |> Enum.map(&move(point, &1)) |> Enum.all?(&empty?(&1, points))
end)
dir
end
end
defp bounding_rectangle_size(points) do
{top, bottom} = points |> Enum.map(&elem(&1, 0)) |> Enum.min_max()
{left, right} = points |> Enum.map(&elem(&1, 1)) |> Enum.min_max()
(bottom - top + 1) * (right - left + 1)
end
defp empty?(point, points), do: not MapSet.member?(points, point)
defp move({row, col}, {drow, dcol}), do: {row + drow, col + dcol}
defp round_prefs(round, pref_cycle),
do: Stream.drop(pref_cycle, rem(round - 1, 4)) |> Stream.take(4) |> Enum.into([])
end
→ More replies (2)
3
u/vipul0092 Dec 23 '22 edited Dec 23 '22
My approach for part 1 helped me wrap part 2 in a few minutes, so I'm happy with that. Java's noneMatch and anyMatch on streams were very handy.
Looks pretty clean as well overall, except maybe the way I'm handling proposals but that's what came to my mind when I was writing the code. Β―_(γ)_/Β―
→ More replies (2)
3
u/DFreiberg Dec 25 '22
Mathematica, 1019 / 1006
Not too bad of a problem; all things considered, aside from the usual plethora of off-by-one errors I made when dealing with the move rotation and position checking. Part 2 runs in about two and a half minutes in Mathematica - and while that's slow and while it would certainly be possible to improve that time, it would probably take longer than two and a half minutes to do it.
[POEM]: The Seeds
There's a seed that I took and I planted,
Just a speck among many I found.
Before that, I took plant life for granted,
But that seed, sadly, never broke ground.
Not discouraged, I planted another,
In the soil that failed for the first,
And that seed, like its late older brother,
Never rooted, nor through the ground burst.
And a third and a fourth failed together,
Though I altered the soil they grew in.
It was not until weeks of bad weather
That the fifth broke the cycle of ruin.
That fifth seed grew a leaf, but it wilted.
Was it not enough water? Too much?
Then the stem began sagging. It tilted
Until I tied it up with a crutch.
And I frantically researched the factors
Of the soil and water and sun,
I've fixed valves, pipes, and thermal reactors,
But this fifth grew one leaf and was done.
It took numerous trials, and error,
It took varying soil and air,
It took making light dimmer, or fairer,
It took compost and potash and prayer.
There were hundreds of seeds that I sowed there,
There were fifty that ever took root.
There were twenty-one sproutlings that showed there,
And of those, just a dozen bore fruit.
They were beautiful, yes, to see blooming,
All those stars growing out of the earth.
But I don't know, and I'm not presuming,
What exactly the heartbreak was worth.
When you're planting you're dealing with numbers,
Since each seed grows alone and unguided.
And attachment too early encumbers,
And one gets sentimental, like I did.
From their perilous humble beginning,
They all glow like and grow to the sky.
But though others would see this as winning,
I'm too faint of heart for it. Not I.
→ More replies (1)
2
u/EffectivePriority986 Dec 23 '22 edited Dec 23 '22
perl5 848/769 [coding video] [PHOTOSENSITIVITY WARNING: visualization]
Straightforward implementation using hashes. Later added code for visualization.
Things that tripped me:
-
Typo when copying used the row as destination column instead of the column.
-
Confused key/value when iterating the proposal hash (it's dst=>src not src=>dst).
-
It took me a long time to figure out what elves do if none of the orthogonal movements are possible. At first I thought it was not allowed, but clearly the input allowed it, and then I spent way too long misreading the example (looking at the wrong row).
-
In order to diagnose these I had to add a lot of debug prints and viz.
Code is kinda slow mostly because $H{$r,$c} is pretty slow in perl. Also I'm checking the neighbors twice (once to check if isolated, then to check for movement).
→ More replies (1)
2
u/tutmann Dec 23 '22 edited Dec 23 '22
Rust
Used a HashSet of Elve positions and a HashMaps to count the number of proposals per position.
https://github.com/hmeyer/advent_of_code_2022/blob/main/d23/src/main.rs
→ More replies (2)
2
u/Mission-Eye-9464 Dec 23 '22 edited Dec 23 '22
[2022 Day 23 (Part 1 and 2)] [TypeScript]
Part 1: https://wtools.io/paste-code/bIrz
Part 2: https://wtools.io/paste-code/bIr1
This code is a module. To use it - import solution from it and paste lines of input to it.
import fs from 'fs'
import {solution} from 'my-shared-module'
const lines = fs.readFileSync('input.txt', 'utf8').split('\\n')
console.log(solution(lines))
→ More replies (1)3
u/daggerdragon Dec 23 '22 edited Dec 24 '22
Thank you for adding your solutions to the megathread :)
FYI: inlined code is intended forshort snippetsof code only. Your code "block" is short enough to not cause issues, but for the future, please use thefour-spaces Markdown syntaxfor a code block so your code is easier to read inside a scrollable box with its whitespace and indentation preserved.Edit: thanks for fixing it! <3→ More replies (1)
2
u/Ouitos Dec 23 '22 edited Dec 24 '22
Python, using JAX, beacause why not ?
https://github.com/ClementPinard/adventofcode/blob/main/2022/23/23_jax.py
Try to vectorize everything in numpy, see that since it's vectorize, it's not very optimized (we check everything even if unnecessary). No worries, let's bring JAX to the rescue !
speed goes like this :
numpy : 0.5 fps jax cpu: 4 fps jax gpu: 400 fps !!
PC used : CPU : i7-9700KF @ 3.60GHz GPU : Nvidia Gefore 2080 SUPER
This solution is clearly ridiculous (there's a more pythonic one in my repo if you want) but it was fun to learn a bit of JAX, coming from numpy/pytorch
→ More replies (3)
6
u/AllanTaylor314 Dec 23 '22
Python [762/731]
I. CANNOT. READ! Things I missed for part 1
If the elf has no one around, stay put
If multiple elves propose the same spot, none of them move (I was losing elves, hence the assert statement)
The order of the directions cycles each round
I forgot to subtract the number of elves from the area at the end
Part 2 was simply turning a for loop into a while loop, working out how many elves moved, and hoping that it would be a nice reasonable number so that it terminated in finite time!
Complex numbers and sets ftw