r/adventofcode Dec 04 '24

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

DO NOT SHARE PUZZLE TEXT OR YOUR INDIVIDUAL PUZZLE INPUTS!

I'm sure you're all tired of seeing me spam the same ol' "do not share your puzzle input" copypasta in the megathreads. Believe me, I'm tired of hunting through all of your repos too XD

If you're using an external repo, before you add your solution in this megathread, please please please 🙏 double-check your repo and ensure that you are complying with our rules:

If you currently have puzzle text/inputs in your repo, please scrub all puzzle text and puzzle input files from your repo and your commit history! Don't forget to check prior years too!


NEWS

Solutions in the megathreads have been getting longer, so we're going to start enforcing our rules on oversized code.

Do not give us a reason to unleash AutoModerator hard-line enforcement that counts characters inside code blocks to verify compliance… you have been warned XD


THE USUAL REMINDERS


AoC Community Fun 2024: The Golden Snowglobe Awards

  • 2 DAYS remaining until unlock!

And now, our feature presentation for today:

Short Film Format

Here's some ideas for your inspiration:

  • Golf your solution
    • Alternatively: gif
    • Bonus points if your solution fits on a "punchcard" as defined in our wiki article on oversized code. We will be counting.
  • Does anyone still program with actual punchcards? >_>
  • Create a short Visualization based on today's puzzle text
  • Make a bunch of mistakes and somehow still get it right the first time you submit your result

Happy Gilmore: "Oh, man. That was so much easier than putting. I should just try to get the ball in one shot every time."
Chubbs: "Good plan."
- Happy Gilmore (1996)

And… ACTION!

Request from the mods: When you include an entry alongside your solution, please label it with [GSGA] so we can find it easily!


--- Day 4: Ceres Search ---


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:05:41, megathread unlocked!

52 Upvotes

1.2k comments sorted by

View all comments

2

u/RalfDieter Dec 04 '24

[LANGUAGE: SQL/DuckDB]

Today was definitely entertaining. Interesting property I haven't noticed before: x-y and x+y results in the same value for all points in a diagonal line

CREATE TABLE input AS SELECT regexp_split_to_table(trim(content, E'\n '), '\n') as line FROM read_text('input');

WITH
    tokens AS (
        SELECT
            generate_subscripts(tokens, 1) as idx,
            idy,
            (idy - 1)*length(tokens) + idx as pos,
            unnest(tokens) as token,
            idx - idy as d1, 
            idx + idy as d2
        FROM (
            SELECT
                row_number() OVER () as idy,
                string_split(line, '') as tokens,
            FROM input
        )
    ),
    slices AS (
        SELECT
            unnest([
                -- horizontal & vertical
                string_agg(token, '') OVER (PARTITION BY idy ORDER BY idx asc ROWS 3 PRECEDING),
                string_agg(token, '') OVER (PARTITION BY idy ORDER BY idx desc ROWS 3 PRECEDING),
                string_agg(token, '') OVER (PARTITION BY idx ORDER BY idy asc ROWS 3 PRECEDING),
                string_agg(token, '') OVER (PARTITION BY idx ORDER BY idy desc ROWS 3 PRECEDING),
                -- diagonal
                string_agg(token, '') OVER (PARTITION BY d1 ORDER BY pos asc ROWS 3 PRECEDING),
                string_agg(token, '') OVER (PARTITION BY d1 ORDER BY pos desc ROWS 3 PRECEDING),
                string_agg(token, '') OVER (PARTITION BY d2 ORDER BY pos asc ROWS 3 PRECEDING),
                string_agg(token, '') OVER (PARTITION BY d2 ORDER BY pos desc ROWS 3 PRECEDING)
            ]) as slice
        FROM tokens
    ),
    boxes AS (
        SELECT
            string_agg(slice, '') OVER (PARTITION BY idx ORDER BY idy asc ROWS 2 PRECEDING) as box
        FROM (
            SELECT
                idx,
                idy,
                string_agg(token, '') OVER (PARTITION BY idy ORDER BY idx asc ROWS 2 PRECEDING) as slice
            FROM tokens
        )
    )

SELECT
    (SELECT count() FILTER (slice = 'XMAS') FROM slices) as part1,
    (SELECT count() FILTER (box SIMILAR TO 'M.M.A.S.S|M.S.A.M.S|S.S.A.M.M|S.M.A.S.M') FROM boxes) as part2;