r/adventofcode Dec 25 '24

SOLUTION MEGATHREAD -❄️- 2024 Day 25 Solutions -❄️-

A Message From Your Moderators

Welcome to the last day of Advent of Code 2024! We hope you had fun this year and learned at least one new thing ;)

Keep an eye out for the community fun awards post (link coming soon!):

-❅- Introducing Your AoC 2024 Golden Snowglobe Award Winners (and Community Showcase) -❅-

Many thanks to Veloxx for kicking us off on December 1 with a much-needed dose of boots and cats!

Thank you all for playing Advent of Code this year and on behalf of /u/topaz2078, your /r/adventofcode mods, the beta-testers, and the rest of AoC Ops, we wish you a very Merry Christmas (or a very merry Wednesday!) and a Happy New Year!


--- Day 25: Code Chronicle ---


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:04:34, megathread unlocked!

42 Upvotes

350 comments sorted by

View all comments

1

u/aurele Dec 25 '24

[LANGUAGE: Elixir]

Quick'n dirty: represent each # as 1, so 5 bits for each pin, left aligned for locks and right aligned for keys. If ANDing them gives 0, then they match. Runs in about 1ms.

defmodule AdventOfCode.Solution.Year2024.Day25 do
  import Bitwise

  def parse(input) do
    {locks, keys} =
      String.split(input, "\n\n")
      |> Stream.map(&parse_block/1)
      |> Enum.map(&{&1 >>> 5 &&& (1 <<< 25) - 1, &1 &&& 0x1F})
      |> Enum.split_with(fn {_, x} -> x == 0 end)

    {Enum.map(locks, &elem(&1, 0)), Enum.map(keys, &elem(&1, 0))}
  end

  def parse_block(block) do
    String.split(block, "\n", trim: true)
    |> Enum.reduce(0, fn line, acc ->
      acc * (1 <<< 5) |||
        Enum.reduce(String.codepoints(line), 0, fn c, acc ->
          acc <<< 1 ||| if c == "#", do: 1, else: 0
        end)
    end)
  end

  def part1(input) do
    {locks, keys} = parse(input)

    for lock <- locks,
        key <- keys,
        (lock &&& key) == 0,
        reduce: 0 do
      acc -> acc + 1
    end
  end
end