chiark / gitweb /
369d861dcf852cfaf52d20e43c956d3cc8752f5a
[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         print $_;
37     } elsif (m/^var /) {
38         die "Complicated variable" unless m/^var (.)=\{0,1\}$/;
39         $vars{$1} = 1;
40     } else {
41         # Assume this is a table rule.
42         chomp;
43         my @cells = split /,/;
44         my %myvars = ();
45         # Only supports 8-neighbour automata
46         die "Unexpected number of comma-separated items" unless @cells == 10;
47         my @dirs = qw/c n ne e se s sw w nw/;
48         if (!$done_vars) {
49             # Variables to match 32 states rather than 2
50             # Numbering of states highly tied to bedbugs.c output
51             # Crap naming scheme: z=off, a=on, q=either
52             print "var zz={0," . join(",", 2..17) . "}\n";
53             print "var aa={" . join(",", 18..33) . "}\n";
54             foreach my $d (@dirs) {
55                 print "var z$d={zz}\n";
56                 print "var a$d={aa}\n";
57                 print "var q$d={z$d,a$d}\n";
58             }
59             $done_vars = 1;
60         }
61         my $i = 0;
62         while (my $dir = pop @dirs) {
63             # Assume each variable in the input is only referenced once
64             # per table row
65             die "Duplicate var" if exists($myvars{$cells[$i]});
66             if (exists($vars{$cells[$i]})) {
67                 $myvars{$cells[$i]} = 1;
68                 $cells[$i] = "q".$dir;
69             } elsif ($cells[$i] eq "0") {
70                 $cells[$i] = "z".$dir;
71             } elsif ($cells[$i] eq "1") {
72                 $cells[$i] = "a".$dir;
73             } else {
74                 die "Unexpected cell $cells[$i]";
75             }
76             $i++;
77         }
78         print join(",", @cells), "\n";
79     }
80 }