37 lines
1.3 KiB
Text
37 lines
1.3 KiB
Text
def lines: split("\n")|length;
|
|
|
|
def cols: split("\n")[0]|length + 1; # allow for the newline
|
|
|
|
# Is there an "H" at [x,y] relative to position i, assuming the width is w?
|
|
# Input is an array; 72 is "H"
|
|
def isH(x; y; i; w): if .[i+ w*y + x] == 72 then 1 else 0 end;
|
|
|
|
def neighborhood(i;w):
|
|
isH(-1; -1; i; w) + isH(0; -1; i; w) + isH(1; -1; i; w) +
|
|
isH(-1; 0; i; w) + isH(1; 0; i; w) +
|
|
isH(-1; 1; i; w) + isH(0; 1; i; w) + isH(1; 1; i; w) ;
|
|
|
|
# The basic rules:
|
|
# Input: a world
|
|
# Output: the next state of .[i]
|
|
def evolve(i; width) :
|
|
# "Ht. " | explode => [ 72, 116, 46, 32 ]
|
|
.[i] as $c
|
|
| if $c == 32 then $c # " " => " "
|
|
elif $c == 116 then 46 # "t" => "."
|
|
elif $c == 72 then 116 # "H" => "t"
|
|
elif $c == 46 then # "."
|
|
# updates are "simultaneous" i.e. relative to $world
|
|
neighborhood(i; width) as $sum
|
|
| (if [1,2]|index($sum) then 72 else . end) # "H"
|
|
else $c
|
|
end ;
|
|
|
|
# [world, lines, cols] | next(w) => [world, lines, cols]
|
|
def next:
|
|
.[0] as $world | .[1] as $lines | .[2] as $w
|
|
| reduce range(0; $world|length) as $i
|
|
($world;
|
|
$world | evolve($i; $w) as $next
|
|
| if .[$i] == $next then . else .[$i] = $next end )
|
|
| [., $lines, $w] ; #
|