Skip to content

Instantly share code, notes, and snippets.

@Szer
Last active December 4, 2023 16:17
Show Gist options
  • Save Szer/a6fd7895af8e9a00967945f565399c1b to your computer and use it in GitHub Desktop.
Save Szer/a6fd7895af8e9a00967945f565399c1b to your computer and use it in GitHub Desktop.
Advent of Code 2023 3
open System
let input = [|
"467..114.."
"...*......"
"..35..633."
"......#..."
"617*......"
".....+.58."
"..592....."
"......755."
"...$.*...."
".664.598.."
|]
type Coordinate = { line: int ; column: int }
type Digit =
{ number: int
start: Coordinate }
member this.finish = this.start.column + this.number.ToString().Length - 1
member this.IsAdjacentTo (other: Coordinate) =
other.column >= this.start.column - 1 &&
other.column <= this.finish + 1 &&
other.line >= this.start.line - 1 &&
other.line <= this.start.line + 1
let parseInput (input: string[]) =
let digits = ResizeArray<Digit>()
let symbols = ResizeArray<Coordinate>()
let gears = ResizeArray<Coordinate>()
let mutable currentNumber = None
for line in 0 .. input.Length - 1 do
// if we go to the next line, we need to add the current number
currentNumber
|> Option.iter (fun number ->
digits.Add { number = number; start = { line = line - 1; column = input.[line].Length - number.ToString().Length } }
currentNumber <- None
)
for column in 0 .. input.[line].Length - 1 do
if Char.IsDigit input.[line].[column] then
let digit = int input.[line].[column] - 48
let newDigit =
currentNumber
|> Option.map ((*) 10 >> (+) digit)
|> Option.defaultValue digit
currentNumber <- Some newDigit
else
currentNumber
|> Option.iter (fun number ->
digits.Add { number = number; start = { line = line; column = column - number.ToString().Length } }
currentNumber <- None
)
if input.[line].[column] = '*' then
gears.Add { line = line; column = column }
if input.[line].[column] <> '.' then
symbols.Add { line = line; column = column }
digits, symbols, gears
let part1 =
parseInput
>> fun (digits, symbols, _) ->
digits
|> Seq.filter (fun digit ->
symbols
|> Seq.exists digit.IsAdjacentTo
)
|> Seq.sumBy (fun digit -> digit.number)
part1 input // 4361
let part2 =
parseInput
>> fun (digits, _, gears) ->
gears
|> Seq.map (fun gear ->
digits
|> Seq.filter (fun digit -> digit.IsAdjacentTo gear)
|> Seq.map (fun digit -> digit.number)
)
|> Seq.filter (Seq.length >> (=) 2)
|> Seq.sumBy (Seq.fold (*) 1)
part2 input // 467835
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment