Skip to content

Instantly share code, notes, and snippets.

@jhusain
Last active January 7, 2025 11:43
Show Gist options
  • Select an option

  • Save jhusain/fcc76d52d9444e2c6aab10f971d2f43d to your computer and use it in GitHub Desktop.

Select an option

Save jhusain/fcc76d52d9444e2c6aab10f971d2f43d to your computer and use it in GitHub Desktop.

Revisions

  1. jhusain revised this gist Jan 7, 2025. 1 changed file with 33 additions and 9 deletions.
    42 changes: 33 additions & 9 deletions Advent of code 2024 9.roc
    Original file line number Diff line number Diff line change
    @@ -30,14 +30,6 @@ getDisk = \diskMapString ->
    { id: id, disk: appendN disk Empty num }
    |> \{ disk } -> Disk disk

    showDisk = \Disk disk ->
    disk
    |> List.map \cell ->
    when cell is
    Full v -> '0' + v
    Empty -> '.'
    |> Str.fromUtf8

    defrag =
    \Disk initList ->
    loop = \list, leftIdx, rightIdx ->
    @@ -65,4 +57,36 @@ defrag =

    (_, _) -> list

    Disk (loop initList 0 (Num.subSaturated (List.len initList) 1))
    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"
  2. jhusain revised this gist Jan 7, 2025. 1 changed file with 20 additions and 82 deletions.
    102 changes: 20 additions & 82 deletions Advent of code 2024 9.roc
    Original file line number Diff line number Diff line change
    @@ -25,23 +25,18 @@ getDisk = \diskMapString ->
    { id: 0, disk: List.withCapacity diskSize }
    \{ id, disk }, num, idx ->
    if Num.isEven idx then
    newDisk = appendN disk (Full id) num
    { id: id + 1, disk: newDisk }
    { id: id + 1, disk: appendN disk (Full id) num }
    else
    newDisk = appendN disk Empty num
    { id: id, disk: newDisk }
    { id: id, disk: appendN disk Empty num }
    |> \{ disk } -> Disk disk

    move = \idx, direction ->
    when direction is
    Left -> Num.subWrap idx 1
    Right -> Num.addWrap idx 1

    findIndexByStep = \list, idx, step, predicate ->
    when List.get list idx is
    Ok val if predicate val -> Ok idx
    Ok _ -> findIndexByStep list (step idx) step predicate
    Err OutOfBounds -> Err NotFound
    showDisk = \Disk disk ->
    disk
    |> List.map \cell ->
    when cell is
    Full v -> '0' + v
    Empty -> '.'
    |> Str.fromUtf8

    defrag =
    \Disk initList ->
    @@ -50,81 +45,24 @@ defrag =
    list
    else
    leftmostEmptyIdxResult =
    findIndexByStep list leftIdx (\idx -> move idx Right) \val -> val == Empty
    list
    |> List.sublist { start: leftIdx, len: Num.subWrap rightIdx leftIdx }
    |> List.findFirstIndex \val -> val == Empty
    |> Result.map \idx -> Num.addWrap leftIdx idx

    rightmostFullIdxResult =
    findIndexByStep list rightIdx (\idx -> move idx Left) \val ->
    list
    |> List.sublist { start: leftIdx, len: Num.addWrap (Num.subWrap rightIdx leftIdx) 1 }
    |> List.findLastIndex \val ->
    when val is
    Full _ -> Bool.true
    _ -> Bool.false
    Empty -> Bool.false
    |> Result.map \idx -> Num.addWrap leftIdx idx

    when (leftmostEmptyIdxResult, rightmostFullIdxResult) is
    (Ok leftmostEmptyIdx, Ok rightmostFullIdx) ->
    loop (List.swap list leftmostEmptyIdx rightmostFullIdx) (move leftmostEmptyIdx Right) (move rightmostFullIdx Left)
    loop (List.swap list leftmostEmptyIdx rightmostFullIdx) (Num.addSaturated leftmostEmptyIdx 1) (Num.subSaturated rightmostFullIdx 1)

    (_, _) -> list

    Disk (loop initList 0 (move (List.len initList) Left))


    showDisk = \Disk disk ->
    disk
    |> List.map \cell ->
    when cell is
    Full v -> '0' + v
    Empty -> '.'
    |> Str.fromUtf8

    expect
    (getDisk "12345")
    ==
    Disk [Full 0, Empty, Empty, Full 1, Full 1, Full 1, Empty, Empty, Empty, Empty, Full 2, Full 2, Full 2, Full 2, Full 2]

    expect (move 0 Left) == Num.maxU64
    expect (move 0 Right) == 1
    expect (move Num.maxU64 Right) == 0
    expect (move Num.maxU64 Left) == Num.maxU64 - 1

    expect
    (findIndexByStep [1, 2, 3, 4, 5] 4 (\idx -> move idx Left) \val -> val == 3)
    ==
    Ok 2

    expect
    (findIndexByStep [] 0 (\idx -> move idx Left) \val -> val == 3)
    ==
    Err NotFound

    expect
    (findIndexByStep [1, 2, 3, 4, 5] 0 (\idx -> move idx Right) \val -> val == 3)
    ==
    Ok 2

    expect
    (findIndexByStep [] 0 (\idx -> move idx Right) \val -> val == 3)
    ==
    Err NotFound


    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"
    Disk (loop initList 0 (Num.subSaturated (List.len initList) 1))
  3. jhusain renamed this gist Jan 6, 2025. 1 changed file with 40 additions and 38 deletions.
    78 changes: 40 additions & 38 deletions gistfile1.txt → Advent of code 2024 9.roc
    Original file line number Diff line number Diff line change
    @@ -32,55 +32,17 @@ getDisk = \diskMapString ->
    { id: id, disk: newDisk }
    |> \{ disk } -> Disk disk

    expect
    (getDisk "12345")
    ==
    Disk [Full 0, Empty, Empty, Full 1, Full 1, Full 1, Empty, Empty, Empty, Empty, Full 2, Full 2, Full 2, Full 2, Full 2]

    move = \idx, direction ->
    when direction is
    Left -> Num.subWrap idx 1
    Right -> Num.addWrap idx 1

    expect (move 0 Left) == Num.maxU64
    expect (move 0 Right) == 1
    expect (move Num.maxU64 Right) == 0
    expect (move Num.maxU64 Left) == Num.maxU64 - 1

    findIndexByStep = \list, idx, step, predicate ->
    when List.get list idx is
    Ok val if predicate val -> Ok idx
    Ok _ -> findIndexByStep list (step idx) step predicate
    Err OutOfBounds -> Err NotFound

    expect
    (findIndexByStep [1, 2, 3, 4, 5] 4 (\idx -> move idx Left) \val -> val == 3)
    ==
    Ok 2

    expect
    (findIndexByStep [] 0 (\idx -> move idx Left) \val -> val == 3)
    ==
    Err NotFound

    expect
    (findIndexByStep [1, 2, 3, 4, 5] 0 (\idx -> move idx Right) \val -> val == 3)
    ==
    Ok 2

    expect
    (findIndexByStep [] 0 (\idx -> move idx Right) \val -> val == 3)
    ==
    Err NotFound

    showDisk = \Disk disk ->
    disk
    |> List.map \cell ->
    when cell is
    Full v -> '0' + v
    Empty -> '.'
    |> Str.fromUtf8

    defrag =
    \Disk initList ->
    loop = \list, leftIdx, rightIdx ->
    @@ -104,6 +66,46 @@ defrag =

    Disk (loop initList 0 (move (List.len initList) Left))


    showDisk = \Disk disk ->
    disk
    |> List.map \cell ->
    when cell is
    Full v -> '0' + v
    Empty -> '.'
    |> Str.fromUtf8

    expect
    (getDisk "12345")
    ==
    Disk [Full 0, Empty, Empty, Full 1, Full 1, Full 1, Empty, Empty, Empty, Empty, Full 2, Full 2, Full 2, Full 2, Full 2]

    expect (move 0 Left) == Num.maxU64
    expect (move 0 Right) == 1
    expect (move Num.maxU64 Right) == 0
    expect (move Num.maxU64 Left) == Num.maxU64 - 1

    expect
    (findIndexByStep [1, 2, 3, 4, 5] 4 (\idx -> move idx Left) \val -> val == 3)
    ==
    Ok 2

    expect
    (findIndexByStep [] 0 (\idx -> move idx Left) \val -> val == 3)
    ==
    Err NotFound

    expect
    (findIndexByStep [1, 2, 3, 4, 5] 0 (\idx -> move idx Right) \val -> val == 3)
    ==
    Ok 2

    expect
    (findIndexByStep [] 0 (\idx -> move idx Right) \val -> val == 3)
    ==
    Err NotFound


    expect
    getDisk "12345"
    |> defrag
  4. jhusain revised this gist Jan 1, 2025. 1 changed file with 8 additions and 1 deletion.
    9 changes: 8 additions & 1 deletion gistfile1.txt
    Original file line number Diff line number Diff line change
    @@ -1,6 +1,7 @@
    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
    @@ -118,4 +119,10 @@ expect
    Ok "0099811188827773336446555566.............."

    main =
    Stdout.line! "hello"
    defragmentedDisk =
    getDisk "2333133121414131402"
    |> defrag
    |> showDisk
    when defragmentedDisk is
    Ok disk -> Stdout.line! disk
    Err _ -> Stderr.line! "Error"
  5. jhusain revised this gist Jan 1, 2025. 1 changed file with 8 additions and 8 deletions.
    16 changes: 8 additions & 8 deletions gistfile1.txt
    Original file line number Diff line number Diff line change
    @@ -46,29 +46,29 @@ expect (move 0 Right) == 1
    expect (move Num.maxU64 Right) == 0
    expect (move Num.maxU64 Left) == Num.maxU64 - 1

    findIndexInDirection = \list, idx, direction, predicate ->
    findIndexByStep = \list, idx, step, predicate ->
    when List.get list idx is
    Ok val if predicate val -> Ok idx
    Ok _ -> findIndexInDirection list (move idx direction) direction predicate
    Ok _ -> findIndexByStep list (step idx) step predicate
    Err OutOfBounds -> Err NotFound

    expect
    (findIndexInDirection [1, 2, 3, 4, 5] 4 Left \val -> val == 3)
    (findIndexByStep [1, 2, 3, 4, 5] 4 (\idx -> move idx Left) \val -> val == 3)
    ==
    Ok 2

    expect
    (findIndexInDirection [] 0 Left \val -> val == 3)
    (findIndexByStep [] 0 (\idx -> move idx Left) \val -> val == 3)
    ==
    Err NotFound

    expect
    (findIndexInDirection [1, 2, 3, 4, 5] 0 Right \val -> val == 3)
    (findIndexByStep [1, 2, 3, 4, 5] 0 (\idx -> move idx Right) \val -> val == 3)
    ==
    Ok 2

    expect
    (findIndexInDirection [] 0 Right \val -> val == 3)
    (findIndexByStep [] 0 (\idx -> move idx Right) \val -> val == 3)
    ==
    Err NotFound

    @@ -87,10 +87,10 @@ defrag =
    list
    else
    leftmostEmptyIdxResult =
    findIndexInDirection list leftIdx Right \val -> val == Empty
    findIndexByStep list leftIdx (\idx -> move idx Right) \val -> val == Empty

    rightmostFullIdxResult =
    findIndexInDirection list rightIdx Left \val ->
    findIndexByStep list rightIdx (\idx -> move idx Left) \val ->
    when val is
    Full _ -> Bool.true
    _ -> Bool.false
  6. jhusain created this gist Jan 1, 2025.
    121 changes: 121 additions & 0 deletions gistfile1.txt
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,121 @@
    app [main] { pf: platform "https://github.com/roc-lang/basic-cli/releases/download/0.17.0/lZFLstMUCUvd5bjnnpYromZJXkQUrdhbva4xdBInicE.tar.br" }

    import pf.Stdout

    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
    newDisk = appendN disk (Full id) num
    { id: id + 1, disk: newDisk }
    else
    newDisk = appendN disk Empty num
    { id: id, disk: newDisk }
    |> \{ disk } -> Disk disk

    expect
    (getDisk "12345")
    ==
    Disk [Full 0, Empty, Empty, Full 1, Full 1, Full 1, Empty, Empty, Empty, Empty, Full 2, Full 2, Full 2, Full 2, Full 2]

    move = \idx, direction ->
    when direction is
    Left -> Num.subWrap idx 1
    Right -> Num.addWrap idx 1

    expect (move 0 Left) == Num.maxU64
    expect (move 0 Right) == 1
    expect (move Num.maxU64 Right) == 0
    expect (move Num.maxU64 Left) == Num.maxU64 - 1

    findIndexInDirection = \list, idx, direction, predicate ->
    when List.get list idx is
    Ok val if predicate val -> Ok idx
    Ok _ -> findIndexInDirection list (move idx direction) direction predicate
    Err OutOfBounds -> Err NotFound

    expect
    (findIndexInDirection [1, 2, 3, 4, 5] 4 Left \val -> val == 3)
    ==
    Ok 2

    expect
    (findIndexInDirection [] 0 Left \val -> val == 3)
    ==
    Err NotFound

    expect
    (findIndexInDirection [1, 2, 3, 4, 5] 0 Right \val -> val == 3)
    ==
    Ok 2

    expect
    (findIndexInDirection [] 0 Right \val -> val == 3)
    ==
    Err NotFound

    showDisk = \Disk disk ->
    disk
    |> List.map \cell ->
    when cell is
    Full v -> '0' + v
    Empty -> '.'
    |> Str.fromUtf8

    defrag =
    \Disk initList ->
    loop = \list, leftIdx, rightIdx ->
    if leftIdx >= rightIdx then
    list
    else
    leftmostEmptyIdxResult =
    findIndexInDirection list leftIdx Right \val -> val == Empty

    rightmostFullIdxResult =
    findIndexInDirection list rightIdx Left \val ->
    when val is
    Full _ -> Bool.true
    _ -> Bool.false

    when (leftmostEmptyIdxResult, rightmostFullIdxResult) is
    (Ok leftmostEmptyIdx, Ok rightmostFullIdx) ->
    loop (List.swap list leftmostEmptyIdx rightmostFullIdx) (move leftmostEmptyIdx Right) (move rightmostFullIdx Left)

    (_, _) -> list

    Disk (loop initList 0 (move (List.len initList) Left))

    expect
    getDisk "12345"
    |> defrag
    |> showDisk
    ==
    Ok "022111222......"

    expect
    getDisk "2333133121414131402"
    |> defrag
    |> showDisk
    ==
    Ok "0099811188827773336446555566.............."

    main =
    Stdout.line! "hello"