Skip to content

Instantly share code, notes, and snippets.

@athas
Created September 20, 2020 13:26
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save athas/9ae5dc6d2bcd4f37540ef094c2d1e670 to your computer and use it in GitHub Desktop.
Save athas/9ae5dc6d2bcd4f37540ef094c2d1e670 to your computer and use it in GitHub Desktop.
type cell = i32
type dir = #north | #south | #east | #west
let dir_to_bit (d: dir) : i32 =
match d
case #north -> 1
case #south -> 2
case #east -> 4
case #west -> 8
let has_dir (c: cell) (d: dir) : bool =
c & dir_to_bit d != 0
let set_dir (c: cell) (d: dir) : cell =
c | dir_to_bit d
let combine_cells (x: cell) (y: cell) =
x | y
let empty_cell : cell =
0
let cell_to_char (c: cell) : i32 =
match {n=has_dir c #north,
s=has_dir c #south,
e=has_dir c #east,
w=has_dir c #west}
case {n=false, s=false, e=false, w=false} -> ' '
case {n=false, s=true, e=false, w=false} -> '╷'
case {n=true, s=false, e=false, w=false} -> '╵'
case {n=true, s=true, e=false, w=false} -> '│'
case {n=true, s=true, e=true, w=false} -> '├'
case {n=true, s=true, e=false, w=true} -> '┤'
case {n=true, s=true, e=true, w=true} -> '┼'
case {n=false, s=true, e=true, w=true} -> '┬'
case {n=true, s=false, e=true, w=true} -> '┴'
case {n=false, s=false, e=true, w=true} -> '─'
case {n=false, s=false, e=false, w=true} -> '╴'
case {n=false, s=false, e=true, w=false} -> '╶'
case {n=false, s=true, e=true, w=false} -> '┌'
case {n=true, s=false, e=true, w=false} -> '└'
case {n=false, s=true, e=false, w=true} -> '┐'
case {n=true, s=false, e=false, w=true} -> '┘'
import "lib/github.com/diku-dk/segmented/segmented"
type pos = (i32,i32)
let line_horiz ((x,y): pos) (w: i32) : [w](pos, cell) =
let f i =
((x+i, y),
if i == 0 then empty_cell `set_dir` #east
else if i == w-1 then empty_cell `set_dir` #west
else empty_cell `set_dir` #west `set_dir` #east)
in tabulate w f
let line_vert ((x,y): pos) (h: i32) : [h](pos, cell) =
let f i =
((x, y+i),
if i == 0 then empty_cell `set_dir` #south
else if i == h-1 then empty_cell `set_dir` #north
else empty_cell `set_dir` #south `set_dir` #north)
in tabulate h f
let put_cells [h][w][n] (canvas: *[h][w]cell) (draw: [n](pos, cell))
: *[h][w]cell =
let flat_idx (x,y) = if x >= 0 && x < w && y >= 0 && y < h
then y*w+x
else -1
in unflatten h w (reduce_by_index (flatten canvas)
combine_cells empty_cell
(map ((.0) >-> flat_idx) draw)
(map (.1) draw))
let main (h: i32) (w: i32) : [h][w]i32 =
let canvas = replicate h (replicate w empty_cell)
let draw = []
++ line_horiz (0,10) 20
++ line_vert (10,0) 20
++ line_horiz (5,5) 11
++ line_vert (5,5) 11
++ line_vert (15,5) 11
++ line_horiz (5,15) 11
in map (map cell_to_char) (put_cells canvas draw)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment