Skip to content

Instantly share code, notes, and snippets.

@jhusain
Last active January 7, 2025 11:43
Show Gist options
  • Save jhusain/fcc76d52d9444e2c6aab10f971d2f43d to your computer and use it in GitHub Desktop.
Save jhusain/fcc76d52d9444e2c6aab10f971d2f43d to your computer and use it in GitHub Desktop.
advent of code 2024 problem 7.roc
app [main] { pf: platform "https://github.com/roc-lang/basic-cli/releases/download/0.17.0/lZFLstMUCUvd5bjnnpYromZJXkQUrdhbva4xdBInicE.tar.br" }
import pf.Stdout
import pf.Stderr
appendN = \list, a, num ->
if num == 0 then
list
else
appendN (List.append list a) a (num - 1)
getDisk = \diskMapString ->
diskMap =
diskMapString
|> Str.toUtf8
|> List.map \ch -> ch - '0'
diskSize =
diskMap
|> List.map \num -> Num.toU64 num
|> List.sum
diskMap
|> List.walkWithIndex
{ id: 0, disk: List.withCapacity diskSize }
\{ id, disk }, num, idx ->
if Num.isEven idx then
{ id: id + 1, disk: appendN disk (Full id) num }
else
{ id: id, disk: appendN disk Empty num }
|> \{ disk } -> Disk disk
defrag =
\Disk initList ->
loop = \list, leftIdx, rightIdx ->
if leftIdx >= rightIdx then
list
else
leftmostEmptyIdxResult =
list
|> List.sublist { start: leftIdx, len: Num.subWrap rightIdx leftIdx }
|> List.findFirstIndex \val -> val == Empty
|> Result.map \idx -> Num.addWrap leftIdx idx
rightmostFullIdxResult =
list
|> List.sublist { start: leftIdx, len: Num.addWrap (Num.subWrap rightIdx leftIdx) 1 }
|> List.findLastIndex \val ->
when val is
Full _ -> Bool.true
Empty -> Bool.false
|> Result.map \idx -> Num.addWrap leftIdx idx
when (leftmostEmptyIdxResult, rightmostFullIdxResult) is
(Ok leftmostEmptyIdx, Ok rightmostFullIdx) ->
loop (List.swap list leftmostEmptyIdx rightmostFullIdx) (Num.addSaturated leftmostEmptyIdx 1) (Num.subSaturated rightmostFullIdx 1)
(_, _) -> list
Disk (loop initList 0 (Num.subSaturated (List.len initList) 1))
showDisk = \Disk disk ->
disk
|> List.map \cell ->
when cell is
Full v -> '0' + v
Empty -> '.'
|> Str.fromUtf8
expect
getDisk "12345"
|> defrag
|> showDisk
==
Ok "022111222......"
expect
getDisk "2333133121414131402"
|> defrag
|> showDisk
==
Ok "0099811188827773336446555566.............."
main =
defragmentedDisk =
getDisk "2333133121414131402"
|> defrag
|> showDisk
when defragmentedDisk is
Ok disk -> Stdout.line! disk
Err _ -> Stderr.line! "Error"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment