-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
c2b2a7d
commit eb68e9f
Showing
8 changed files
with
170 additions
and
207 deletions.
There are no files selected for viewing
This file contains 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
This file contains 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
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,84 @@ | ||
//// Grid operations are kind of a pain to get right / can produce some | ||
//// boilerplate around results for get operations, so I'm gonna try and extract | ||
//// them to a module | ||
|
||
import gleam/dict | ||
import gleam/list | ||
import gleam/option.{type Option, None, Some} | ||
|
||
// Making the type generic since we do a grid of src | ||
// and a grid of interpreted values | ||
pub type Grid(a) { | ||
Grid(inner: dict.Dict(GridKey, a), cells: List(GridKey)) | ||
} | ||
|
||
pub opaque type GridKey { | ||
GridKey(row: Int, col: Int) | ||
} | ||
|
||
pub fn row(grid_key: GridKey) -> Int { | ||
grid_key.row | ||
} | ||
|
||
pub fn col(grid_key: GridKey) -> Int { | ||
grid_key.col | ||
} | ||
|
||
pub fn new(width: Int, height: Int, default: a) -> Grid(a) { | ||
let cols = list.range(1, width) | ||
let rows = list.range(1, height) | ||
|
||
let #(g, c) = | ||
list.fold(rows, #(dict.new(), []), fn(acc, row) { | ||
let #(grid, cells) = acc | ||
|
||
let #(g, c) = | ||
list.fold(cols, #(dict.new(), []), fn(acc, col) { | ||
let #(g, c) = acc | ||
#(dict.insert(g, GridKey(row:, col:), default), [ | ||
GridKey(row:, col:), | ||
..c | ||
]) | ||
}) | ||
|
||
#(dict.merge(grid, g), list.concat([c, cells])) | ||
}) | ||
|
||
Grid(g, c) | ||
} | ||
|
||
pub fn insert(grid: Grid(a), key: GridKey, item: a) -> Grid(a) { | ||
Grid(..grid, inner: dict.insert(grid.inner, key, item)) | ||
} | ||
|
||
pub fn fold(grid: Grid(a), acc: b, do: fn(b, GridKey, a) -> b) -> b { | ||
dict.fold(grid.inner, acc, do) | ||
} | ||
|
||
pub fn map_values(grid: Grid(a), do: fn(GridKey, a) -> b) -> Grid(b) { | ||
Grid(inner: dict.map_values(grid.inner, do), cells: grid.cells) | ||
} | ||
|
||
pub fn get(grid: Grid(a), key: GridKey) -> a { | ||
// Because the `GridKey` is an opaque type produced | ||
// by creating the grid, the get operation is safe. | ||
let assert Ok(item) = dict.get(grid.inner, key) | ||
item | ||
} | ||
|
||
pub fn cell_to_the_right(grid: Grid(a), key: GridKey) -> Result(GridKey, Nil) { | ||
list.find(grid.cells, fn(k) { k.row == key.row && k.col == key.col + 1 }) | ||
} | ||
|
||
pub fn intersect(row_cell: GridKey, col_cell: GridKey) -> Result(GridKey, Nil) { | ||
let GridKey(row, col_check) = row_cell | ||
let GridKey(row_check, col) = col_cell | ||
case row != row_check && col != col_check { | ||
False -> Error(Nil) | ||
True -> Ok(GridKey(row:, col:)) | ||
} | ||
} | ||
|
||
pub fn to_list(grid: Grid(a)) -> List(#(GridKey, a)) { | ||
dict.to_list(grid.inner) | ||
} |
Oops, something went wrong.