Add tasks for all the new languages
This commit is contained in:
parent
9dc3c2bb62
commit
bba7bfd280
13208 changed files with 134745 additions and 0 deletions
|
|
@ -0,0 +1,31 @@
|
|||
\ one-dimensional automaton
|
||||
|
||||
\ direct map of input state to output state:
|
||||
{
|
||||
" " : 32,
|
||||
" #" : 32,
|
||||
" # " : 32,
|
||||
" ##" : 35,
|
||||
"# " : 32,
|
||||
"# #" : 35,
|
||||
"## " : 35,
|
||||
"###" : 32,
|
||||
} var, lifemap
|
||||
|
||||
: transition \ s ix (r:s') -- (r:s')
|
||||
>r dup r@ n:1- 3 s:slice
|
||||
lifemap @ swap caseof
|
||||
r> swap r@ -rot s:! >r ;
|
||||
|
||||
\ run over 'state' and generate new state
|
||||
: gen \ s -- s'
|
||||
clone >r
|
||||
dup s:len 2 n:-
|
||||
' transition 1 rot loop
|
||||
drop r> ;
|
||||
|
||||
: life \ s -- s'
|
||||
dup . cr gen ;
|
||||
|
||||
" ### ## # # # # # " ' life 10 times
|
||||
bye
|
||||
|
|
@ -0,0 +1,45 @@
|
|||
shared void run() {
|
||||
|
||||
class Automata1D<Cell>({Cell*} data, Cell alive, Cell dead)
|
||||
given Cell satisfies Object {
|
||||
|
||||
assert(data.every((Cell element) => element == alive || element == dead));
|
||||
|
||||
value imaginaryFirstCell = data.first else dead;
|
||||
value imaginaryLastCell = data.last else dead;
|
||||
|
||||
value cells = Array {*data.rest.exceptLast};
|
||||
|
||||
function isAlive(Cell c) => c == alive;
|
||||
function flipped(Cell c) => c == alive then dead else alive;
|
||||
|
||||
shared Boolean evolve() {
|
||||
value buffer = Array {
|
||||
*cells.indexed.map((Integer->Cell element) {
|
||||
value index->cell = element;
|
||||
value left = cells[index - 1] else imaginaryFirstCell;
|
||||
value right = cells[index + 1] else imaginaryLastCell;
|
||||
if(isAlive(left) && isAlive(right)) {
|
||||
return flipped(cell);
|
||||
}
|
||||
if(isAlive(cell) && !isAlive(left) && !isAlive(right)) {
|
||||
return dead;
|
||||
}
|
||||
return cell;
|
||||
}
|
||||
)};
|
||||
value changed = buffer != cells;
|
||||
buffer.copyTo(cells);
|
||||
return changed;
|
||||
}
|
||||
|
||||
string => imaginaryFirstCell.string + "".join(cells) + imaginaryLastCell.string;
|
||||
}
|
||||
|
||||
value automata = Automata1D("_###_##_#_#_#_#__#__", '#', '_');
|
||||
variable value generation = 0;
|
||||
print("generation ``generation`` ``automata``");
|
||||
while(automata.evolve() && generation < 10) {
|
||||
print("generation ``++generation`` ``automata``");
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
PROGRAM ONEDIM_AUTOMATA
|
||||
|
||||
! for rosettacode.org
|
||||
!
|
||||
|
||||
!VAR I,J,N,W,K
|
||||
|
||||
!$DYNAMIC
|
||||
DIM X[0],X2[0]
|
||||
|
||||
BEGIN
|
||||
|
||||
DATA(20,0,1,1,1,0,1,1,0,1,0,1,0,1,0,1,0,0,1,0,0)
|
||||
|
||||
PRINT(CHR$(12);)
|
||||
N=20 ! number of generation required
|
||||
READ(W)
|
||||
!$DIM X[W+1],X2[W+1]
|
||||
FOR I=1 TO W DO
|
||||
READ(X[I])
|
||||
END FOR
|
||||
FOR K=1 TO N DO
|
||||
PRINT("Generation";K;TAB(16);)
|
||||
FOR J=1 TO W DO
|
||||
IF X[J]=1 THEN PRINT("#";) ELSE PRINT("_";) END IF
|
||||
IF X[J-1]+X[J]+X[J+1]=2 THEN X2[J]=1 ELSE X2[J]=0 END IF
|
||||
END FOR
|
||||
PRINT
|
||||
FOR J=1 TO W DO
|
||||
X[J]=X2[J]
|
||||
END FOR
|
||||
END FOR
|
||||
END PROGRAM
|
||||
|
|
@ -0,0 +1,90 @@
|
|||
import Maybe exposing (withDefault)
|
||||
import List exposing (length, tail, reverse, concat, head, append, map3)
|
||||
import Html exposing (Html, div, h1, text)
|
||||
import String exposing (join)
|
||||
import Svg exposing (svg)
|
||||
import Svg.Attributes exposing (version, width, height, viewBox,cx,cy, fill, r)
|
||||
import Html.App exposing (program)
|
||||
import Random exposing (step, initialSeed, bool, list)
|
||||
import Matrix exposing (fromList, mapWithLocation, flatten) -- chendrix/elm-matrix
|
||||
import Time exposing (Time, second, every)
|
||||
|
||||
type alias Model = { history : List (List Bool)
|
||||
, cols : Int
|
||||
, rows : Int
|
||||
}
|
||||
|
||||
view : Model -> Html Msg
|
||||
view model =
|
||||
let
|
||||
circleInBox (row,col) value =
|
||||
if value
|
||||
then [ Svg.circle [ r "0.3"
|
||||
, fill ("purple")
|
||||
, cx (toString (toFloat col + 0.5))
|
||||
, cy (toString (toFloat row + 0.5))
|
||||
]
|
||||
[]
|
||||
]
|
||||
else []
|
||||
|
||||
showHistory model =
|
||||
model.history
|
||||
|> reverse
|
||||
|> fromList
|
||||
|> mapWithLocation circleInBox
|
||||
|> flatten
|
||||
|> concat
|
||||
in
|
||||
div []
|
||||
[ h1 [] [text "One Dimensional Cellular Automata"]
|
||||
, svg [ version "1.1"
|
||||
, width "700"
|
||||
, height "700"
|
||||
, viewBox (join " "
|
||||
[ 0 |> toString
|
||||
, 0 |> toString
|
||||
, model.cols |> toString
|
||||
, model.rows |> toString
|
||||
]
|
||||
)
|
||||
]
|
||||
(showHistory model)
|
||||
]
|
||||
|
||||
update : Msg -> Model -> (Model, Cmd Msg)
|
||||
update msg model =
|
||||
if length model.history == model.rows
|
||||
then (model, Cmd.none)
|
||||
else
|
||||
let s1 = model.history |> head |> withDefault []
|
||||
s0 = False :: s1
|
||||
s2 = append (tail s1 |> withDefault []) [False]
|
||||
|
||||
gen d0 d1 d2 =
|
||||
case (d0,d1,d2) of
|
||||
(False, True, True) -> True
|
||||
( True, False, True) -> True
|
||||
( True, True, False) -> True
|
||||
_ -> False
|
||||
|
||||
updatedHistory = map3 gen s0 s1 s2 :: model.history
|
||||
updatedModel = {model | history = updatedHistory}
|
||||
in (updatedModel, Cmd.none)
|
||||
|
||||
|
||||
init : Int -> (Model, Cmd Msg)
|
||||
init n =
|
||||
let gen1 = fst (step (list n bool) (initialSeed 34))
|
||||
in ({ history = [gen1], rows = n, cols= n }, Cmd.none)
|
||||
|
||||
type Msg = Tick Time
|
||||
|
||||
subscriptions model = every (0.2 * second) Tick
|
||||
|
||||
main = program
|
||||
{ init = init 40
|
||||
, view = view
|
||||
, update = update
|
||||
, subscriptions = subscriptions
|
||||
}
|
||||
|
|
@ -0,0 +1,113 @@
|
|||
'
|
||||
' One Dimensional Cellular Automaton
|
||||
'
|
||||
start$="01110110101010100100"
|
||||
max_cycles%=20 ! give a maximum depth
|
||||
'
|
||||
' Global variables hold the world, with two rows
|
||||
' world! is set up with 2 extra cells width, so there is a FALSE on either side
|
||||
' cur% gives the row for current world,
|
||||
' new% gives the row for the next world.
|
||||
'
|
||||
size%=LEN(start$)
|
||||
DIM world!(size%+2,2)
|
||||
cur%=0
|
||||
new%=1
|
||||
clock%=0
|
||||
'
|
||||
@setup_world(start$)
|
||||
OPENW 1
|
||||
CLEARW 1
|
||||
DO
|
||||
@display_world
|
||||
@update_world
|
||||
EXIT IF @same_state
|
||||
clock%=clock%+1
|
||||
EXIT IF clock%>max_cycles% ! safety net
|
||||
LOOP
|
||||
~INP(2)
|
||||
CLOSEW 1
|
||||
'
|
||||
' parse given string to set up initial states in world
|
||||
' -- assumes world! is of correct size
|
||||
'
|
||||
PROCEDURE setup_world(defn$)
|
||||
LOCAL i%
|
||||
' clear out the array
|
||||
ARRAYFILL world!(),FALSE
|
||||
' for each 1 in string, set cell to true
|
||||
FOR i%=1 TO LEN(defn$)
|
||||
IF MID$(defn$,i%,1)="1"
|
||||
world!(i%,0)=TRUE
|
||||
ENDIF
|
||||
NEXT i%
|
||||
' set references to cur and new
|
||||
cur%=0
|
||||
new%=1
|
||||
RETURN
|
||||
'
|
||||
' Display the world
|
||||
'
|
||||
PROCEDURE display_world
|
||||
LOCAL i%
|
||||
FOR i%=1 TO size%
|
||||
IF world!(i%,cur%)
|
||||
PRINT "#";
|
||||
ELSE
|
||||
PRINT ".";
|
||||
ENDIF
|
||||
NEXT i%
|
||||
PRINT ""
|
||||
RETURN
|
||||
'
|
||||
' Create new version of world
|
||||
'
|
||||
PROCEDURE update_world
|
||||
LOCAL i%
|
||||
FOR i%=1 TO size%
|
||||
world!(i%,new%)=@new_state(@get_value(i%))
|
||||
NEXT i%
|
||||
' reverse cur/new
|
||||
cur%=1-cur%
|
||||
new%=1-new%
|
||||
RETURN
|
||||
'
|
||||
' Test if cur/new states are the same
|
||||
'
|
||||
FUNCTION same_state
|
||||
LOCAL i%
|
||||
FOR i%=1 TO size%
|
||||
IF world!(i%,cur%)<>world!(i%,new%)
|
||||
RETURN FALSE
|
||||
ENDIF
|
||||
NEXT i%
|
||||
RETURN TRUE
|
||||
ENDFUNC
|
||||
'
|
||||
' Return new state of cell given value
|
||||
'
|
||||
FUNCTION new_state(value%)
|
||||
SELECT value%
|
||||
CASE 0,1,2,4,7
|
||||
RETURN FALSE
|
||||
CASE 3,5,6
|
||||
RETURN TRUE
|
||||
ENDSELECT
|
||||
ENDFUNC
|
||||
'
|
||||
' Compute value for cell + neighbours
|
||||
'
|
||||
FUNCTION get_value(cell%)
|
||||
LOCAL result%
|
||||
result%=0
|
||||
IF world!(cell%-1,cur%)
|
||||
result%=result%+4
|
||||
ENDIF
|
||||
IF world!(cell%,cur%)
|
||||
result%=result%+2
|
||||
ENDIF
|
||||
IF world!(cell%+1,cur%)
|
||||
result%=result%+1
|
||||
ENDIF
|
||||
RETURN result%
|
||||
ENDFUNC
|
||||
|
|
@ -0,0 +1,68 @@
|
|||
import math
|
||||
randomize()
|
||||
|
||||
type
|
||||
TBoolArray = array[0..30, bool] # an array that is indexed with 0..10
|
||||
TSymbols = tuple[on: char , off: char]
|
||||
|
||||
const
|
||||
num_turns = 20
|
||||
symbols:TSymbols = ('#','_')
|
||||
|
||||
proc `==` (x:TBoolArray,y:TBoolArray): bool =
|
||||
if len(x) != len(y):
|
||||
return False
|
||||
for i in 0..(len(x)-1):
|
||||
if x[i] != y[i]:
|
||||
return False
|
||||
return True
|
||||
|
||||
proc count_neighbours(map:TBoolArray , tile:int):int =
|
||||
result = 0
|
||||
if tile != len(map)-1 and map[tile+1]:
|
||||
result += 1
|
||||
if tile != 0 and map[tile-1]:
|
||||
result += 1
|
||||
|
||||
proc print_map(map:TBoolArray, symbols:TSymbols) =
|
||||
for i in map:
|
||||
if i:
|
||||
write(stdout,symbols[0])
|
||||
else:
|
||||
write(stdout,symbols[1])
|
||||
write(stdout,"\n")
|
||||
|
||||
proc random_map(): TBoolArray =
|
||||
var map = [False,False,False,False,False,False,False,False,False,False,False,
|
||||
False,False,False,False,False,False,False,False,False,False,False,
|
||||
False,False,False,False,False,False,False,False,False]
|
||||
for i in 0..(len(map)-1):
|
||||
map[i] = bool(random(2))
|
||||
return map
|
||||
|
||||
proc fixed_map(): TBoolArray =
|
||||
var map = [False,True,True,True,False,True,True,False,True,False,True,
|
||||
False,True,False,True,False,False,True,False,False,False,False,
|
||||
False,False,False,False,False,False,False,False,False]
|
||||
return map
|
||||
|
||||
#make the map
|
||||
var map:TBoolArray
|
||||
#map = random_map() # uncomment for random start
|
||||
map = fixed_map()
|
||||
print_map(map,symbols)
|
||||
for i in 0..num_turns:
|
||||
var new_map = map
|
||||
for j in 0..(len(map)-1):
|
||||
if map[j]:
|
||||
if count_neighbours(map, j) == 2 or
|
||||
count_neighbours(map, j) == 0:
|
||||
new_map[j] = False
|
||||
else:
|
||||
if count_neighbours(map, j) == 2:
|
||||
new_map[j] = True
|
||||
if new_map == map:
|
||||
print_map(map,symbols)
|
||||
break
|
||||
map = new_map
|
||||
print_map(map,symbols)
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
const
|
||||
s_init: string = "_###_##_#_#_#_#__#__"
|
||||
arrLen: int = 20
|
||||
|
||||
var q0: string = s_init & repeatChar(arrLen-20,'_')
|
||||
var q1: string = q0
|
||||
|
||||
proc life(s:string): char =
|
||||
var str: string = s
|
||||
if len(normalize(str)) == 2: # normalize eliminates underscores
|
||||
return '#'
|
||||
return '_'
|
||||
|
||||
proc evolve(q: string): string =
|
||||
result = repeatChar(arrLen,'_')
|
||||
#result[0] = '_'
|
||||
for i in 1 .. q.len-1:
|
||||
result[i] = life(substr(q & '_',i-1,i+1))
|
||||
|
||||
echo(q1)
|
||||
q1 = evolve(q0)
|
||||
echo(q1)
|
||||
while q1 != q0:
|
||||
q0 = q1
|
||||
q1 = evolve(q0)
|
||||
echo(q1)
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
: nextGen(l)
|
||||
| i |
|
||||
StringBuffer new
|
||||
l size loop: i [
|
||||
l at( i 1- ) '#' ==
|
||||
l at( i 1+ ) '#' == +
|
||||
l at( i ) '#' == +
|
||||
2 == ifTrue: [ '#' ] else: [ '_' ] over add
|
||||
] ;
|
||||
|
||||
: gen(l, n) l dup println #[ nextGen dup println ] times(n) ;
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
string s = "_###_##_#_#_#_#__#__"
|
||||
integer prev='_', curr, toggled = 1
|
||||
|
||||
while 1 do
|
||||
?s
|
||||
for i=2 to length(s)-1 do
|
||||
curr = s[i]
|
||||
if prev=s[i+1]
|
||||
and (curr='#' or prev='#') then
|
||||
s[i] = 130-curr
|
||||
toggled = 1
|
||||
end if
|
||||
prev = curr
|
||||
end for
|
||||
if not toggled then ?s exit end if
|
||||
toggled = 0
|
||||
end while
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
string s = "________________________#________________________"
|
||||
integer prev='_', curr, toggled = 1
|
||||
|
||||
for limit=1 to 24 do
|
||||
?s
|
||||
for i=2 to length(s)-1 do
|
||||
curr = s[i]
|
||||
if (prev=s[i+1]) = (curr='#') then
|
||||
s[i] = 130-curr
|
||||
end if
|
||||
prev = curr
|
||||
end for
|
||||
end for
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
var seq = "_###_##_#_#_#_#__#__";
|
||||
var x = '';
|
||||
|
||||
loop {
|
||||
seq.tr!('01', '_#');
|
||||
say seq;
|
||||
seq.tr!('_#', '01');
|
||||
seq.gsub!(/(?<=(.))(.)(?=(.))/, {|s1,s2,s3| s1 == s3 ? (s1 ? 1-s2 : 0) : s2});
|
||||
(x != seq) && (x = seq) || break;
|
||||
}
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
class Automaton(rule, cells) {
|
||||
|
||||
method init {
|
||||
rule = sprintf("%08b", rule).chars.map{.to_i}.reverse;
|
||||
}
|
||||
|
||||
method next {
|
||||
var previous = cells.map{_};
|
||||
var len = previous.len;
|
||||
cells[] = rule[
|
||||
previous.range.map { |i|
|
||||
4*previous[i-1 % len] +
|
||||
2*previous[i] +
|
||||
previous[i+1 % len]
|
||||
}...
|
||||
]
|
||||
}
|
||||
|
||||
method to_s {
|
||||
cells.map { _ ? '#' : ' ' }.join;
|
||||
}
|
||||
}
|
||||
|
||||
var size = 10;
|
||||
var auto = Automaton(
|
||||
rule: 104,
|
||||
cells: [(size/2).of(0)..., 111011010101.digits..., (size/2).of(0)...],
|
||||
);
|
||||
|
||||
size.times {
|
||||
say "|#{auto}|";
|
||||
auto.next;
|
||||
}
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
def (gens n l)
|
||||
prn l
|
||||
repeat n
|
||||
zap! gen l
|
||||
prn l
|
||||
|
||||
def (gen l)
|
||||
with (a nil b nil c l.0)
|
||||
collect nil # won't insert paren without second token
|
||||
each x cdr.l
|
||||
shift! a b c x
|
||||
yield (next a b c)
|
||||
yield (next b c nil)
|
||||
|
||||
def (next a b c) # next state of b given neighbors a and c
|
||||
if (and a c) not.b
|
||||
(or a c) b
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
def (uca l) # new datatype: unidim CA
|
||||
(tag uca (list l len.l))
|
||||
|
||||
def (len l) :case (isa uca l) # how to compute its length
|
||||
rep.l.1
|
||||
|
||||
defcoerce uca list # converting it to list
|
||||
(fn(_) rep._.0)
|
||||
|
||||
def (pr l) :case (isa uca l) # how to print it
|
||||
each x l # transparently coerces to a list for iterating over
|
||||
pr (if x "#" "_")
|
||||
|
||||
# (l i) returns ith cell when l is a uca, and nil when i is out-of-bounds
|
||||
defcall uca (l i)
|
||||
if (0 <= i < len.l)
|
||||
rep.l.0.i
|
||||
|
||||
def (gens n l)
|
||||
prn l
|
||||
repeat n
|
||||
zap! gen l
|
||||
prn l
|
||||
|
||||
def (gen l)
|
||||
uca+collect+for i 0 (i < len.l) ++i
|
||||
yield (next (l i-1) l.i (l i+1))
|
||||
|
||||
# next state of b, given neighbors a and c
|
||||
def (next a b c)
|
||||
if (and a c) not.b
|
||||
(or a c) b
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
# The 1-d cellular automaton:
|
||||
def next:
|
||||
# Conveniently, jq treats null as 0 when it comes to addition
|
||||
# so there is no need to fiddle with the boundaries
|
||||
. as $old
|
||||
| reduce range(0; length) as $i
|
||||
([];
|
||||
($old[$i-1] + $old[$i+1]) as $s
|
||||
| if $s == 0 then .[$i] = 0
|
||||
elif $s == 1 then .[$i] = (if $old[$i] == 1 then 1 else 0 end)
|
||||
else .[$i] = (if $old[$i] == 1 then 0 else 1 end)
|
||||
end);
|
||||
|
||||
|
||||
# pretty-print an array:
|
||||
def pp: reduce .[] as $i (""; . + (if $i == 0 then " " else "*" end));
|
||||
|
||||
# continue until quiescence:
|
||||
def go: recurse(. as $prev | next | if . == $prev then empty else . end) | pp;
|
||||
|
||||
# Example:
|
||||
[0,1,1,1,0,1,1,0,1,0,1,0,1,0,1,0,0,1,0,0] | go
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
$ jq -c -r -n -f One-dimensional_cellular_automata.jq
|
||||
*** ** * * * * *
|
||||
* ***** * * *
|
||||
** ** * *
|
||||
** *** *
|
||||
** * **
|
||||
** ***
|
||||
** * *
|
||||
** *
|
||||
**
|
||||
Loading…
Add table
Add a link
Reference in a new issue