Close

Advent of Code 2025 – Day 3

Lobby

I was kind of disappointed in day 3 because it’s the same puzzle twice. So one solution solves both parts 1 and 2, just changing the length from 2 to 12.

I start by looping from the first digit (most significant) down to the least significant digit. So, for a 2-digit joltage, I find the “tens” first (i.e. 101), then the “ones” (100). For a 12-digit joltage I loop from 1011 down to 100

Regardless of the number of digits for each position I look for 9, then 8, then 7, etc down to 1, stopping the first time I find one. That way I always get the largest available digit for each position, thus ensuring the maximum joltage. The only trick with the search is making sure I start after the previous digit was used, but I make sure I don’t search too far ahead such that there won’t be enough digits to follow to make a full-digit joltage.

For example with one of the sample lines: 811111111111119. I can’t start with 9 because then I’d have only a 1-digit joltage since no batteries follow that. With a two-digit joltage, I can use the 8 and then jump to the 9 because I don’t need any batteries after that. With that 12-digit joltage though, I need to use ten of the 1s and then finish with the 9.

Thus, after finding the largest available digit, I add it to the result, multiplying by the appropriate power of 10 to fill in from most to least significant digits.
When I’ve filled all positions I return the result.

This works for any number of digits, so the same function is used in both part 1 and part 2, I just change the second parameter from 2 to 12.

CREATE OR REPLACE FUNCTION find_joltage(p_str IN VARCHAR2, p_digits IN PLS_INTEGER)
    RETURN NUMBER
IS
    v_length   PLS_INTEGER := LENGTH(p_str);
    v_digit    PLS_INTEGER;
    v_test     PLS_INTEGER;
    v_index    PLS_INTEGER := 1;
    v_next     PLS_INTEGER;
    v_result   NUMBER := 0;
    j          PLS_INTEGER := p_digits - 1;
BEGIN
    WHILE j >= 0
    LOOP
        FOR i IN REVERSE 1 .. 9
        LOOP
            v_test := INSTR(p_str, TO_CHAR(i), v_index);

            IF v_test > 0 AND v_test <= v_length - j
            THEN
                v_next := v_test;
                v_digit := i;
                EXIT;
            END IF;
        END LOOP;

        v_result := v_result + v_digit * POWER(10, j);
        j := j - 1;
        v_index := v_next + 1;
    END LOOP;

    RETURN v_result;
END;

Once I have the joltage for each line, I sum them up to get the answer.

WITH data
    AS
        (SELECT s.*, find_joltage(str, 2) j
           FROM advent.data2rows('advent2025-3sample') s)
SELECT SUM(j)
  FROM data;

WITH data
    AS
        (SELECT s.*, find_joltage(str, 12) j
           FROM advent.data2rows('advent2025-3sample') s)
SELECT SUM(j)
  FROM data;

Leave a Reply