Advent of Code 2025 - Day 2
Part 1 #
Show solution
The core of the problem is to correctly identify the invalid ids. Once we have this, we can iterate over the list of ids and sum the invalid ones.
In part 1, an id is invalid if its first half is equal to its second half.
Here is the full solution:
open System.IO
open System
[<Literal>]
let INPUT = "input.txt"
let isInvalidId (id: bigint) =
let idStr = id.ToString()
if idStr.Length % 2 <> 0 then
false
else
let halfLen = idStr.Length / 2
idStr[..(halfLen-1)] = idStr[halfLen..]
let arrayOfRanges =
(File.ReadAllLines INPUT |> Array.head).Split [|','|]
|> Array.map (fun range -> range.Split [|'-'|] |> Array.map bigint.Parse)
let computeSum (ranges: bigint array array) =
ranges
|> Array.map (fun range ->
seq { range[0] .. range[1] }
|> Seq.filter isInvalidId
|> Seq.sum)
|> Array.sum
arrayOfRanges |> computeSum |> printfn "%A"
Part 2 #
Show solution
In part 2, the definition of an invalid id is different. An id is invalid if it’s only made of at least 2 repeated sequences of digits.
We’ll define two new helper functions:
let chunkByLen k (s:string) =
s
|> Seq.chunkBySize k
|> Seq.map (fun chars -> String chars)
let allEqual (chunks:seq<string>) =
let head = Seq.head chunks
Seq.forall ((=) head) chunks
chunkByLen splits the string into chunks of length k and allEqual checks if a sequence of strings are all equal. Then the new definition of isInvalidId becomes:
let isInvalidId (id: bigint) =
let idStr = id.ToString()
let halfLen = idStr.Length / 2
seq {1..halfLen}
|> Seq.exists (fun k -> chunkByLen k idStr |> allEqual)
We iterate over the possible chunk sizes and check if any of them splits the id into equal chunks. If so, the id is invalid. The rest of the implementation remains the same.