Skip to content

Instantly share code, notes, and snippets.

@jhusain
Created December 10, 2024 20:45
Show Gist options
  • Save jhusain/88b4fb2d20d417103f67d00ea2186e39 to your computer and use it in GitHub Desktop.
Save jhusain/88b4fb2d20d417103f67d00ea2186e39 to your computer and use it in GitHub Desktop.
advent-of-code-2024-9.roc
digitToInt =
\char -> Num.intCast (char - '0')
appendNTimes =
\list, v, n ->
if n == 0 then
list
else
appendNTimes (List.append list v) v (n - 1)
toDisk =
\diskMapString ->
diskMapString
|> Str.walkUtf8WithIndex
(0, [])
\(id, list), cur, idx ->
numBlocks = digitToInt cur
if Num.isOdd idx then
(id, appendNTimes list (EmptyBlock) numBlocks)
else
(id + 1, appendNTimes list (FileBlock id) numBlocks)
|> \(_, list) -> Disk list
defragmentHelper =
\blocks, leftIdx, rightIdx ->
if leftIdx >= rightIdx then
Ok (Disk blocks)
else
when List.get? blocks leftIdx is
FileBlock _ -> defragmentHelper blocks (leftIdx + 1u64) rightIdx
EmptyBlock ->
when List.get? blocks rightIdx is
EmptyBlock -> defragmentHelper blocks leftIdx (rightIdx - 1u64)
FileBlock _ ->
defragmentHelper (List.swap blocks leftIdx rightIdx) (leftIdx + 1u64) (rightIdx - 1u64)
crashOnErr =
\err, msg ->
when err is
Ok a -> a
Err _ -> crash msg
defragment =
\Disk blocks ->
result = defragmentHelper blocks 0 ((List.len blocks) - 1u64)
crashOnErr result "Index out of bounds error"
checksum =
\Disk blocks ->
blocks
|> List.walkWithIndex
0
\acc, cur, idx ->
when cur is
EmptyBlock -> acc
FileBlock id -> acc + (id * (Num.intCast idx))
"2333133121414131402"
|> toDisk
|> defragment
|> checksum
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment