Last active
January 7, 2025 11:43
-
-
Save jhusain/fcc76d52d9444e2c6aab10f971d2f43d to your computer and use it in GitHub Desktop.
advent of code 2024 problem 7.roc
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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