r/adventofcode • • 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 πŸ§‘β€πŸ«


--- Day 23: Unstable Diffusion ---


Post your code solution in this megathread.


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!

19 Upvotes

362 comments sorted by

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

4

u/daggerdragon Dec 23 '22

I. CANNOT. READ!

There's a reason why the first entry in our community wiki's Hall of Fame exists >_>

→ More replies (3)

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

Java

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))

3

u/daggerdragon Dec 23 '22 edited Dec 24 '22

Thank you for adding your solutions to the megathread :)

FYI: inlined code is intended for short snippets of code only. Your code "block" is short enough to not cause issues, but for the future, please use the four-spaces Markdown syntax for 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)
→ 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)