summaryrefslogtreecommitdiff
path: root/module/tex/context/third/simpleslides/automata/automata-eca.lua
diff options
context:
space:
mode:
Diffstat (limited to 'module/tex/context/third/simpleslides/automata/automata-eca.lua')
-rw-r--r--module/tex/context/third/simpleslides/automata/automata-eca.lua108
1 files changed, 108 insertions, 0 deletions
diff --git a/module/tex/context/third/simpleslides/automata/automata-eca.lua b/module/tex/context/third/simpleslides/automata/automata-eca.lua
new file mode 100644
index 0000000..95d1f71
--- /dev/null
+++ b/module/tex/context/third/simpleslides/automata/automata-eca.lua
@@ -0,0 +1,108 @@
+--
+--------------------------------------------------------------------------------
+-- FILE: automata-eca.lua
+-- DESCRIPTION: drawing elementary cellular automata
+-- REQUIREMENTS: ConTeXt MkIV with Simple Slides module
+-- BUGS: uncountable
+-- AUTHOR: Philipp Gesang (Phg), <megas.kapaneus@gmail.com>
+-- VERSION: 1.0
+-- CREATED: 14/08/10 19:43:35 CEST
+--------------------------------------------------------------------------------
+--
+
+environment.loadluafile( "automata-life" )
+
+local help = gol.helpers
+
+local C, Cs, Ct, P, R, S, match = lpeg.C, lpeg.Cs, lpeg.Ct, lpeg.P, lpeg.R, lpeg.S, lpeg.match
+
+
+eca = {}
+
+
+function eca.parse_file (fname)
+ local f = assert(io.open(fname, "r"), "No such file: "..fname..".")
+ local init = f:read("*all")
+ f:close()
+
+ return help.strip(init)
+end
+
+function eca.to_base(number, base)
+ local alphabet, result, cnt, remainder = "0123456789abcdef", "", 0
+ while number > 0 do
+ cnt = cnt + 1
+ number, remainder = math.floor(number / base), (number % base) + 1
+ result = string.sub(alphabet, remainder, remainder) .. result
+ end
+ return result
+end
+
+function eca.gen_rule(nr)
+ local rules = {}
+ local states = { "111", "110", "101", "100", "011", "010", "001", "000" }
+
+ nr = string.format("%8s",eca.to_base(nr, 2)):gsub(" ", "0")
+
+ local n = 1
+ while n <= #states do
+ rules[states[n]] = nr:sub(n,n)
+ n = n + 1
+ end
+
+ return rules
+end
+
+function eca.next_line(from, rule)
+ local new = ""
+ from = "0"..from.."0" -- assume dead borders
+ --from = string.format("0%s0", from) -- too slow
+
+ local cell = C(S"01")
+ local cells= Ct(cell * #(cell * cell)) / function (t)
+ local three = t[1]..t[2]..t[3]
+ new = new .. rule[three]
+ end
+ lpeg.match(cells^1, from)
+ return new
+end
+
+function eca.stripcells (str, dir, cnt)
+ if dir == "left" then
+ return str:sub( cnt )
+ elseif dir == "right" then
+ return str:sub( 0, str:len() - cnt )
+ else -- assume ambilateral clipping
+ return str:sub( cnt, str:len() - cnt )
+ end
+end
+
+function eca.gen_frame(from, lines, rule)
+
+ local cnt = 1
+ local c = mplife.setup.current
+
+ local new = { [1] = eca.stripcells(from, c.clip, c.diff ) }
+
+ repeat
+ from = eca.next_line(from, rule)
+ table.insert( new, eca.stripcells(from, c.clip, c.diff) )
+ cnt = cnt + 1
+ until cnt == lines
+ return eca.next_line(from, rule), new
+end
+
+function eca.successive (current)
+ local thisframe
+ current.from, thisframe = eca.gen_frame(current.from, current.framesize, current.rule)
+ if not context then -- cli invocation
+ for _,j in ipairs(thisframe) do
+ io.write(j:gsub("0","ยท"):gsub("1","O").."\n")
+ end
+ else
+
+ end
+ return 0
+end
+
+return eca