Skip to main content

Advent of Code 2025 - Day 3

·3 mins
Before reading the solution, attempt to solve the problem on your own.

Part 1 #

Show solution

In this problem, we are given a list of lines of digits and asked to find the
largest 2-digit number that can be found in each line.
The idea is to form the number by taking the max digits from the line.
The first digit in our number cannot be the last digit of the line, because we need at least one digit after it.
For the second digit, we can take any digit from the line but past the first chosen digit.

open System.IO

[<Literal>]
let INPUT = "input.txt"

let banks =
    File.ReadAllLines INPUT
    |> Array.map (fun line ->
        line
        |> Seq.map (fun c -> int c - int '0')
        |> Seq.toArray)

let getBankMax bank =
    bank
    |> Seq.mapi (fun i v -> i, v)
    |> Seq.maxBy snd

let getBankJoltage bank =
    let len = Array.length bank
    let fstMax = bank |> Seq.take (len-1) |> getBankMax
    let sndMax = bank |> Seq.skip (fst fstMax + 1) |> getBankMax
    snd fstMax * 10 + snd sndMax

let joltage banks =
    banks
    |> Array.map getBankJoltage
    |> Array.sum

printfn "%d" (joltage banks)

Part 2 #

Show solution

The second part is a generalization of the first part.
We are asked to find the largest 12-digit number that can be found in each line.
Note on how we constructed the 2-digit number in the first part:

  • For the first digit, we took the max from the line ignoring the last digit
  • For the second digit, we took the max from the line past the first chosen digit and not ignoring any digit in the remaining sequence.

Therefore, the generalized algorithm (K-digit number) is as follows:

  1. Start with k = K-1 (where K = 12)
  2. Skip past the last chosen digit (if any)
  3. Ignore k digits from the end of the line (i.e. take the first len-k digits)
  4. Find the max digit in the remaining sequence
  5. Decrease k by 1
  6. Repeat steps 2-5 until k < 0
open System.IO
open System

[<Literal>]
let INPUT = "input.txt"
[<Literal>]
let K = 12

let banks =
    File.ReadAllLines INPUT
    |> Array.map (fun line ->
        line
        |> Seq.map (fun c -> bigint (int c - int '0'))
        |> Seq.toArray)

let getBankMax k bank =
    let len = Seq.length bank
    bank
    |> Seq.take (len - k)
    |> Seq.mapi (fun i v -> i, v)
    |> Seq.maxBy snd

let getBankJoltage bank =
    seq { K-1 .. -1 .. 0 }
    |> Seq.scan
        (fun (prevAbsIndex, _) k ->
            let offset = prevAbsIndex + 1
            let relIndex, digit =
                bank
                |> Seq.skip offset
                |> getBankMax k
            relIndex + offset, digit
        ) (-1, 0I)
    |> Seq.fold (fun number (_, digit) -> number * 10I + digit) 0I

let joltage banks =
    banks
    |> Array.map getBankJoltage
    |> Array.sum

printfn "%A" (joltage banks)

We can check that this is a generalization of the first part by setting K = 2 and observing that the result is the same as in the first part.