Roc

Other Roc solutions.
module [rectangles]

# Heavy inspiration from Ageron's solution.

rectangles : Str -> U64
rectangles = \diagram ->
    grid =
        Str.split diagram "\n"
        |> List.map Str.toUtf8

    height = List.len grid

    List.mapWithIndex grid \row, y1 ->
        List.mapWithIndex row \_, x1 ->
            y2s = List.range { start: After y1, end: Before height }
            List.map y2s \y2 ->
                x2s = List.range { start: After x1, end: Before (List.len row) }
                List.map x2s \x2 ->
                    if isRectangle grid (x1, y1) (x2, y2) then
                        1
                    else
                        0
                |> List.sum
            |> List.sum
        |> List.sum
    |> List.sum

isRectangle : List (List U8), (U64, U64), (U64, U64) -> Bool
isRectangle = \grid, (x1, y1), (x2, y2) ->
    getGridValue = \x, y ->
        row = List.get? grid y
        value = List.get row x
        value

    hasTopLeftCorner = getGridValue x1 y1 == Ok '+'
    hasBottomLeftCorner = getGridValue x1 y2 == Ok '+'
    hasTopRightCorner = getGridValue x2 y1 == Ok '+'
    hasBottomRightCorner = getGridValue x2 y2 == Ok '+'

    hasTopHorizontalEdge =
        xs = List.range { start: At x1, end: At x2 }
        List.all xs \x ->
            getGridValue x y1 == Ok '+' || getGridValue x y1 == Ok '-'

    hasBottomHorizontalEdge =
        xs = List.range { start: At x1, end: At x2 }
        List.all xs \x ->
            getGridValue x y2 == Ok '+' || getGridValue x y2 == Ok '-'

    hasLeftVerticalEdge =
        ys = List.range { start: At y1, end: At y2 }
        List.all ys \y ->
            getGridValue x1 y == Ok '+' || getGridValue x1 y == Ok '|'

    hasRightVerticalEdge =
        ys = List.range { start: At y1, end: At y2 }
        List.all ys \y ->
            getGridValue x2 y == Ok '+' || getGridValue x2 y == Ok '|'

    List.all
        [
            hasTopLeftCorner,
            hasBottomLeftCorner,
            hasTopRightCorner,
            hasBottomRightCorner,
            hasTopHorizontalEdge,
            hasBottomHorizontalEdge,
            hasLeftVerticalEdge,
            hasRightVerticalEdge,
        ]
        \identity -> identity