chiark / gitweb /
Automate creation of Bedbugs.rule
[bedbugs.git] / src / mungetable.pl
1 #! /usr/bin/perl -w
2 # This awful single-use script expands out a description of a
3 # two-state cellular automaton in Golly table format (such as Conway's
4 # Life) into an equivalent rule table that collapses the 32 "Bedstead"
5 # states (16 on, 16 off) into the 2 automaton states while applying
6 # the same rule.
7 # It's slightly complicated because it's designed to work with
8 # the output of Golly make-ruletable.cpp, which is somewhat optimised
9 # using variables, but this script makes no attempt to optimise its
10 # output. It uses poorly-named variables to do a lot of its work.
11
12 # This file is part of Bedbugs.
13 # Copyright (C) 2014 Jacob Nevins.
14 #
15 # This program is free software; you can redistribute it and/or modify
16 # it under the terms of the GNU General Public License as published by
17 # the Free Software Foundation; either version 2 of the License, or
18 # (at your option) any later version.
19 #
20 # This program is distributed in the hope that it will be useful,
21 # but WITHOUT ANY WARRANTY; without even the implied warranty of
22 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
23 # GNU General Public License for more details.
24 #
25 # You should have received a copy of the GNU General Public License along
26 # with this program; if not, write to the Free Software Foundation, Inc.,
27 # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
28
29 my %vars = ();
30 my $done_vars = 0;
31
32 while(<>) {
33     if (m/^#/) {
34         print $_;
35     } elsif (m/^(n_states|neighborhood|symmetries):/) {
36         # Suppress -- assume matching ones will be provided elsewhere
37         ;
38     } elsif (m/^var /) {
39         die "Complicated variable" unless m/^var (.)=\{0,1\}$/;
40         $vars{$1} = 1;
41     } else {
42         # Assume this is a table rule.
43         chomp;
44         my @cells = split /,/;
45         my %myvars = ();
46         # Only supports 8-neighbour automata
47         die "Unexpected number of comma-separated items" unless @cells == 10;
48         my @dirs = qw/c n ne e se s sw w nw/;
49         if (!$done_vars) {
50             # Variables to match 32 states rather than 2
51             # Numbering of states highly tied to bedbugs.c output
52             # Crap naming scheme: z=off, a=on, q=either
53             print "var zz={0," . join(",", 2..17) . "}\n";
54             print "var aa={" . join(",", 18..33) . "}\n";
55             foreach my $d (@dirs) {
56                 print "var z$d={zz}\n";
57                 print "var a$d={aa}\n";
58                 print "var q$d={z$d,a$d}\n";
59             }
60             $done_vars = 1;
61         }
62         my $i = 0;
63         while (my $dir = pop @dirs) {
64             # Assume each variable in the input is only referenced once
65             # per table row
66             die "Duplicate var" if exists($myvars{$cells[$i]});
67             if (exists($vars{$cells[$i]})) {
68                 $myvars{$cells[$i]} = 1;
69                 $cells[$i] = "q".$dir;
70             } elsif ($cells[$i] eq "0") {
71                 $cells[$i] = "z".$dir;
72             } elsif ($cells[$i] eq "1") {
73                 $cells[$i] = "a".$dir;
74             } else {
75                 die "Unexpected cell $cells[$i]";
76             }
77             $i++;
78         }
79         print join(",", @cells), "\n";
80     }
81 }