Data update

This commit is contained in:
Ingy dot Net 2024-04-19 16:56:29 -07:00
parent 0df55f9f24
commit aec8ed51b6
1045 changed files with 18889 additions and 2777 deletions

View file

@ -0,0 +1,84 @@
# Output: a prn in range(0;$n) where $n is .
def prn:
if . == 1 then 0
else . as $n
| (($n-1)|tostring|length) as $w
| [limit($w; inputs)] | join("") | tonumber
| if . < $n then . else ($n | prn) end
end;
# Input: an array
def knuthShuffle:
length as $n
| if $n <= 1 then .
else {i: $n, a: .}
| until(.i == 0;
.i += -1
| (.i + 1 | prn) as $j
| .a[.i] as $t
| .a[.i] = .a[$j]
| .a[$j] = $t)
| .a
end;
# Compass is a JSON object {n,s,e,w} representing the four possible
# directions in which to move, i.e. to open a gate.
# For example, Compass.n corresponds to a move north (i.e. dx is 0, dy is 1),
# and Compass.n.gates["N"] is true indicating that the "northern" gate should be opened.
def Compass:
{n: { gates: {"N": true}, dx: 0, dy: -1},
s: { gates: {"S": true}, dx: 0, dy: 1},
e: { gates: {"E": true}, dx: 1, dy: 0},
w: { gates: {"W": true}, dx:-1, dy: 0} }
| .n.opposite = .s
| .s.opposite = .n
| .e.opposite = .w
| .w.opposite = .e
;
# Produce a matrix representing an $x x $y maze.
# .[$i][$j] represents the box in row $i, column $j.
# Initially, all the gates of all the boxes are closed.
def MazeMatrix($x; $y):
[range(0;$x) | {} ] as $v | [range(0;$y) | $v];
# Input: a MazeMatrix
def generate($cx; $cy):
def interior($a; $upper): $a >= 0 and $a < $upper;
length as $x
| (.[0]|length) as $y
| Compass as $Compass
| ([$Compass.n, $Compass.s, $Compass.e, $Compass.w] | knuthShuffle) as $directions
| reduce $directions[] as $v (.;
($cx + $v.dx) as $nx
| ($cy + $v.dy) as $ny
| if interior($nx; $x) and interior($ny; $y) and .[$nx][$ny] == {}
then .[$cx][$cy] += $v.gates
| .[$nx][$ny] += $v.opposite.gates
| generate($nx; $ny)
end );
# Input: a MazeMatrix
def display:
. as $maze
| ($maze|length) as $x
| ($maze[0]|length) as $y
| ( range(0;$y) as $i
# draw the north edge
| ([range(0;$x) as $j
| if $maze[$j][$i]["N"] then "+ " else "+---" end] | join("")) + "+",
# draw the west edge
([range(0;$x) as $j
| if $maze[$j][$i]["W"] then " " else "| " end] | join("")) + "|" ),
# draw the bottom line
($x * "+---") + "+"
;
# Start the walk at the top left
def amaze($x;$y):
MazeMatrix($x; $y)
| generate(0; 0)
| display;
# Example
amaze(4; 5);

View file

@ -0,0 +1,37 @@
H ← 8
W ← 18
Ver ← 0
Hor ← 1
Vis ← 2
BreakNS ← ⊂Ver⊂⊃(/↥≡⊡0|⊡0_1)
BreakEW ← ⊂Hor⊂⊃(⊡0_0|/↥≡⊡1)
# ([here, next], maze) -> (maze')
BreakWall ← ⍜⊡(0◌)⟨BreakNS|BreakEW⟩=°⊟≡⊢.
Neighbours ← +⊙¤[[¯1 0] [1 0] [0 1] [0 ¯1]] # Gives N4
Shuffle ← ⊏⍏[⍥⚂]⧻.
IsVisited ← ¬⊡⊂Vis
MarkAsVisited ← ⟜(⍜(⊡|1◌)⊂Vis)
OnlyInBounds ← ▽≡IsVisited ⊙¤,, # (finds the boundary 1's)
# (here, maze) -> (maze')
Walk ← |2 (
MarkAsVisited
# (here, maze) -> ([[here, next] x(up to)4], maze)
≡⊟¤⟜(Shuffle OnlyInBounds Neighbours)
# Update maze for each in turn. For each, if it
# still isn't visited, break the wall, recurse into it.
∧(⟨◌|Walk ⊡1 ⟜BreakWall⟩IsVisited◌°⊟,,)
)
⊂↯H⊂↯W0 1↯+1W1 # vis (added 1's help bounds checks)
⊂↯H⊂↯W1 1↯+1W 0 # ver
↯+1H⊂↯W1 0 # hor
⊂⊟
# Stack: ([hor, ver, vis])
Walk [0 0]
PP! ← ≡/⊂∵^! # Pretty print using switch.
≡(&p$"_\n_")⊃(PP!⟨"+ "|"+--"⟩⊡Ver|PP!⟨" "|"| "⟩⊡Hor)