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;