Skip to content

Instantly share code, notes, and snippets.

@object
Created December 15, 2023 06:38
Show Gist options
  • Save object/4aacbc21062e5cf1efc6259c7c80b4a7 to your computer and use it in GitHub Desktop.
Save object/4aacbc21062e5cf1efc6259c7c80b4a7 to your computer and use it in GitHub Desktop.
Advent of Code 2023, December 15
#time "on"
open System
open System.IO
let splitOn c (s: string) =
s.Split [|c|]
let input =
File.ReadAllText(__SOURCE_DIRECTORY__ + "/../data/input15.txt").Replace("\r", "").Replace("\n", "")
|> splitOn ','
let computeHash (chars: char array) =
chars
|> Array.fold (fun acc c -> (acc + int c) * 17 % 256) 0
module List =
let safeSkip count ls =
if count < List.length ls then List.skip count ls else []
// Part One
input
|> Array.map Seq.toArray
|> Array.map computeHash
|> Array.sum
// Part Two
type Command =
| Remove of string
| Add of string * int
let parseCommand (str: string) =
let items = str.Split [|'-';'='|]
let label = items[0]
let command = if str.Contains "-" then Remove label else Add (label, Int32.Parse items[1])
command
let commands = input |> Array.map parseCommand
let applyCommand boxes command =
let label = match command with | Remove x -> x | Add (x,_) -> x
let boxNumber = label |> Seq.toArray |> computeHash
match boxes |> Map.tryFind boxNumber with
| Some boxContent ->
let newContent =
match command with
| Remove _ -> boxContent |> List.filter (fun (x,y) -> x <> label)
| Add (x,y) ->
match boxContent |> List.tryFindIndex (fun (x,y) -> x = label) with
| Some index ->
List.concat [boxContent |> List.take index; [x,y]; boxContent |> List.safeSkip (index+1)]
| None -> boxContent @ [x,y]
if Seq.isEmpty newContent then boxes |> Map.remove boxNumber else boxes |> Map.add boxNumber newContent
| None ->
match command with
| Remove _ -> boxes
| Add (x,y) -> boxes |> Map.add boxNumber [x,y]
commands
|> Array.fold (fun boxes command -> applyCommand boxes command) Map.empty
|> Map.toList
|> List.map (fun (boxNumber, boxContent) -> (boxNumber+1) * (boxContent |> List.mapi (fun index lense -> (index+1) * (snd lense)) |> List.sum))
|> List.sum
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment