Regel 110 simulieren


27

Regel 110 ist ein zellularer Automat mit einigen interessanten Eigenschaften. Ihr Ziel ist es, eine Regel 110 mit möglichst wenigen Zeichen zu simulieren.

Für diejenigen, die es nicht wissen, wird Regel 110 Zeile für Zeile in einem Raster simuliert. Jedes Quadrat in einer Zeile des Rasters untersucht die Quadrate oben, oben links und oben rechts, um zu bestimmen, welche Zelle es sein soll.

current pattern  111 110 101 100 011 010 001 000
new cell          0   1   1   0   1   1   1   0

Eingabe: Zahlen von 0 bis 39, die das n-te Eingabequadrat in der obersten Zeile in einem beliebigen Format darstellen (durch Kommas getrennte Zeichenfolge, Liste, Funktionsargumente). Um 1-indizierte Sprachen zu unterstützen, können Zahlen auch 1-indiziert sein und liegen daher im Bereich von 1 bis 40.

Beispiel Eingabe:

38,39

Ausgabe: Ein 40 x 40-Raster, das die laufenden Automaten einschließlich der ersten Zeile darstellt. Sie sollten 0 als Leerzeichen und 1 als sichtbares Druckzeichen lassen. Nachgestellte Leerzeichen sind zulässig, solange das tatsächliche Raster angemessen unterschieden werden kann. Am unteren Rand des Rasters befindet sich möglicherweise ein Zeilenumbruch, zwischen den Rasterlinien sollten jedoch keine Leerzeichen stehen.

Beispielausgabe:

                                  XX
                                 XXX
                                XX X
                               XXXXX
                              XX   X
                             XXX  XX
                            XX X XXX
                           XXXXXXX X
                          XX     XXX
                         XXX    XX X
                        XX X   XXXXX
                       XXXXX  XX   X
                      XX   X XXX  XX
                     XXX  XXXX X XXX

etc.

Hinweis: Eine ähnliche Frage zu 1D-Zellularautomaten wurde bereits gestellt, aber ich hoffe, dass mit nur einer Regel kürzere Antworten geschrieben werden können.


4
Machen die Muster einen Zeilenumbruch (dh prüft die Zelle ganz links die Zelle ganz rechts in der Zeile darüber)?
Ventero

4
Wenn es singulär ist, dann ist es ein zellularer Automat .
ClickRick

1
Die Antworten können geringfügig kürzer sein als bei der Simulation eines 1D-Zellularautomaten, da die Regel hartcodiert ist und nicht aus der Eingabe analysiert werden muss, ansonsten sind die Antworten jedoch gleich. Wenn es eine andere Regel gäbe, gäbe es Einsparpotential, aber wie um alles in der Welt könnte eine Turing-mächtige Regel etwas gegen eine allgemeine Implementierung sparen?
Peter Taylor

1
@Ventero Das gibt es in dieser Version nicht.
Qwr

1
@BMO Dies ist eine alte Frage, aber da heutzutage der Konsens darin besteht, flexible Eingabeformate zuzulassen, werde ich die Frage ändern, um dies zuzulassen
qwr

Antworten:


8

CJam - 47

S40*l',/{i'!t}/{N40,S3$S++f{>3<2b137Yb='!^}}39*

Es wird !für "1" -Zellen verwendet.

Versuchen Sie es unter http://cjam.aditsu.net/

Erläuterung:

S40*macht einen String (Array) von 40 Plätzen
l',/eine Linie und Splits durch Komma liest
{…}/führt für jedes Element (die Zahlen in Fadenform) , um den Block
- i'!twandelt die Zahl auf ganzzahlige und setzt in dieser Position in der vorherige Zeichenfolge , die die Position (ursprünglich 40 Plätze ) zu '!'
Zu diesem Zeitpunkt haben wir die erste Zeile erhalten.
{…}39*Führt den Block 39 Mal aus
- Nfügt eine neue Zeile hinzu
- erstellt 40,das Array [0 1… 39]
- S3$S++kopiert die vorherige Zeile (Position 3 auf dem Stapel) und füllt sie mit einem Leerzeichen auf jeder Seite auf
- f{…}führt den Block für {jede Zahl von 0 aus bis 39} und {die gepolsterte Zeile}
- >3<Nimmt einen Teil von 3 Elementen aus der gepolsterten Zeile, beginnend mit der aktuellen Nummer
- 2bkonvertiert von Basis 2; Die Elemente, die wir in Scheiben schneiden, sind keine Ziffern zur Basis 2, aber Zeichen werden in ihre ASCII-Werte konvertiert und '' mod 8 ist 0 und '!' mod 8 ist 1
- 137Ybwandelt 137 in Basis 2 ( Y= 2) um und erhält [1 0 0 0 1 0 0 1], das 110 invertiert und negiert ist (auf 8 Bits)
- ='!^erhält die entsprechende Basis-2-Ziffer (die Das Array wird umbrochen, sodass der Index in Mod 8 aufgenommen wird. Zeichen, was zu '!' für 0 und '' für 1


17

Ruby, 113 Zeichen

c=[0]*41
eval"[#{gets}].map{|i|c[i]=1}"+'
c=(0..39).map{|x|putc" X"[u=c[x]]
110[4*c[x-1]+2*u+c[x+1]]}<<0;puts'*40

Übernimmt die Eingabe für stdin. Wenn Sie eine andere Regel verwenden 110möchten , ersetzen Sie einfach die in der letzten Zeile angegebene Regel durch die gewünschte Regel.

Beispiel:

$ ruby 110.rb <<< 38,39
                                      XX
                                     XXX
                                    XX X
                                   XXXXX
                                  XX   X
                                 XXX  XX
                                XX X XXX
                               XXXXXXX X
                              XX     XXX
                             XXX    XX X
                            XX X   XXXXX
                           XXXXX  XX   X
                          XX   X XXX  XX
                         XXX  XXXX X XXX
                        XX X XX  XXXXX X
                       XXXXXXXX XX   XXX
                      XX      XXXX  XX X
                     XXX     XX  X XXXXX
                    XX X    XXX XXXX   X
                   XXXXX   XX XXX  X  XX
                  XX   X  XXXXX X XX XXX
                 XXX  XX XX   XXXXXXXX X
                XX X XXXXXX  XX      XXX
               XXXXXXX    X XXX     XX X
              XX     X   XXXX X    XXXXX
             XXX    XX  XX  XXX   XX   X
            XX X   XXX XXX XX X  XXX  XX
           XXXXX  XX XXX XXXXXX XX X XXX
          XX   X XXXXX XXX    XXXXXXXX X
         XXX  XXXX   XXX X   XX      XXX
        XX X XX  X  XX XXX  XXX     XX X
       XXXXXXXX XX XXXXX X XX X    XXXXX
      XX      XXXXXX   XXXXXXXX   XX   X
     XXX     XX    X  XX      X  XXX  XX
    XX X    XXX   XX XXX     XX XX X XXX
   XXXXX   XX X  XXXXX X    XXXXXXXXXX X
  XX   X  XXXXX XX   XXX   XX        XXX
 XXX  XX XX   XXXX  XX X  XXX       XX X
XX X XXXXXX  XX  X XXXXX XX X      XXXXX
XXXXXX    X XXX XXXX   XXXXXX     XX   X

8

Mathematica, 122 Bytes

f[a_]:=Riffle[CellularAutomaton[110,Array[If[MemberQ[ToExpression["{"<>a<>"}"],#-1],1,0]&,40],39]/.0->" "/.1->"X","
"]<>""

Ja, Sie könnten dies als Missbrauch dieser Lücke ansehen , aber a) diese Lücke ist ziemlich umstritten, b) eine Frage zum Zellularautomaten benötigt eine Mathematica-Antwort (insbesondere eine zu Regel 110) und c) Venteros Ruby-Antwort ist sowieso kürzer, also ziehe ich sie an Ich glaube nicht, dass irgendein Schaden angerichtet wird.

Die meisten Zeichen werden zum Parsen und Formatieren von Eingaben verwendet. Der tatsächliche Automat wird mit simuliert

CellularAutomaton[110,initialGrid,39]

Hierbei werden periodische Randbedingungen verwendet (das Raster wird also umbrochen).


8

Python - 141

i=input()
o=range(40)
l=''.join(' X'[c in i]for c in o)
for r in o:print l;l=''.join('X '[l[c-1:c+2]in('XXX','   ','X  ','','  ')]for c in o)

Laufen Sie als zB python 110.py <<< 38,39


3
['X',' ']könnte geändert werden 'X ', um 5 Zeichen zu speichern.
Calvins Hobbys

16
Meine Lieblingsfrucht ist jetzt eino=range()
kitcar2000

7

q, 67, 62 58 Bytes

Vorausgesetzt, kein Wrap-Around:

{40{not(2 sv'flip 1 0 -1 xprev\:x)in 0 4 7}\@[40#0b;x;~:]}

Alte Version

{40{not(flip(prev;::;next)@\:x)in 3 cut 111100000b}\@[40#0b;x;not]}
{40{not(flip 1 0 -1 xprev\:x)in 3 3#111100000b}\@[40#0b;x;~:]}

5

Python, 186

def r(s,m=range(40)):
 s=[int(i in s)for i in m]
 for g in m:print''.join([' X'[i]for i in s]);s=[int(not''.join(map(str,s[i-1:i+2]if i else s[:2]))in'111 100 000 00'.split())for i in m]

Ordentlich, aber wahrscheinlich nicht optimal.

Sie haben nicht angegeben, wie die Eingabe erfolgt, also habe ich gerade eine Funktion erstellt.

Anwendungsbeispiel:

r ([38,39])

Ausgabe:

                                      XX
                                     XXX
                                    XX X
                                   XXXXX
                                  XX   X
                                 XXX  XX
                                XX X XXX
                               XXXXXXX X
                              XX     XXX
                             XXX    XX X
                            XX X   XXXXX
                           XXXXX  XX   X
                          XX   X XXX  XX
                         XXX  XXXX X XXX
                        XX X XX  XXXXX X
                       XXXXXXXX XX   XXX
                      XX      XXXX  XX X
                     XXX     XX  X XXXXX
                    XX X    XXX XXXX   X
                   XXXXX   XX XXX  X  XX
                  XX   X  XXXXX X XX XXX
                 XXX  XX XX   XXXXXXXX X
                XX X XXXXXX  XX      XXX
               XXXXXXX    X XXX     XX X
              XX     X   XXXX X    XXXXX
             XXX    XX  XX  XXX   XX   X
            XX X   XXX XXX XX X  XXX  XX
           XXXXX  XX XXX XXXXXX XX X XXX
          XX   X XXXXX XXX    XXXXXXXX X
         XXX  XXXX   XXX X   XX      XXX
        XX X XX  X  XX XXX  XXX     XX X
       XXXXXXXX XX XXXXX X XX X    XXXXX
      XX      XXXXXX   XXXXXXXX   XX   X
     XXX     XX    X  XX      X  XXX  XX
    XX X    XXX   XX XXX     XX XX X XXX
   XXXXX   XX X  XXXXX X    XXXXXXXXXX X
  XX   X  XXXXX XX   XXX   XX        XXX
 XXX  XX XX   XXXX  XX X  XXX       XX X
XX X XXXXXX  XX  X XXXXX XX X      XXXXX
XXXXXX    X XXX XXXX   XXXXXX     XX   X

Ich habe die Eingabe angegeben: In Ihrem Fall müssten Sie input () verwenden und die Eingabe wie im ursprünglichen Beitrag angegeben formatieren.
Qwr

5

Mathematica, 113 Zeichen

Eine andere Mathematica-Antwort mit CellularAutomaton.

Print@@" "["X"][[#]]&/@CellularAutomaton[110,SparseArray[#+1->1&/@ImportString[InputString[],"CSV"][[1]],40],39];

Interessant, wie funktioniert das " "["X"][[#]]&?
Martin Ender

@m.buettner " "["X"][[1]]ist "X". " "["X"][[0]]gibt den Kopf von " "["X"]nämlich zurück " ".
Alephalpha

Oh, ich verstehe. Das spart also im Allgemeinen ein Zeichen für Listen. Das ist wirklich klug. Ich denke, Sie könnten es zu codegolf.stackexchange.com/questions/12900/…
Martin Ender

4

C - 178

Dieser Code hängt von der Tatsache ab, dass jede Zeile in einer Matrix in einem zusammenhängenden Speicher gespeichert ist. Außerdem wird nicht die erste Zeile, sondern die nächsten 40 gedruckt, da in den Regeln nur ein Raster von 40 x 40 angegeben wurde.

Nur zur besseren Lesbarkeit eingerückt, enthält die Byteanzahl nur den erforderlichen Code.

a[41][42],i,j,*t;
main(){
    while(scanf("%d,",&j)>0)
        a[i][j]=1;
    for(;i<40;i++,puts(""))
        for(j=0;++j<40;)
            t=&a[i][j],
            putchar((*(t+42)=1&(110>>(*(t+1)?1:0)+(*t?2:0)+(*(t-1)?4:0)))?88:32);
}

3

Lua - 351

Nicht die ideale Sprache zum Golfen.

s,n,t,u=arg[1],{},table.remove,table.insert
for i=1,40 do u(n,i,'.') end
for i in s:gmatch("%d+")do u(n,i,'x');t(n)end
function a(b) c="";for i=1,40 do c=c..b[i] end;print(c);return c end
for i=1,40 do z= n[40]..a(n)..n[1];for k=2,41 do y=string.sub(z,k-1,k+1);if y=="xxx"or y=="x.." or y=="..." then u(n,k-1,'.')else u(n,k-1,'x')end;t(n)end end

1
do u(n,i,'x')das ist beabsichtigt, nicht wahr?
Stan Strum


3

Haskell , 135 131 130 Bytes

-1 Byte dank Ørjan Johansen (Neuordnung take 40)

Völlig andere Herangehensweise an die Antwort von FrownyFrog, aber ungefähr gleich lang:

(a?b)r=mod(b+r+b*r+a*b*r)2
r x=0:(zipWith3(?)x=<<tail$tail x++[0])
f y=take 40$map(" o"!!)<$>iterate r[sum[1|elem i y]|i<-[0..40]]

1

Erläuterung

4101

f y=                               [sum[1|elem i y]|i<-[0..40]]

40

    take 40$              iterate r

01 einem ausgefallenen Charakter zu:

            map(" o"!!)<$>

r110zipWith3(?)

r x=0:(zipWith3(?)x=<<tail$tail x++[0])

Der (?)Operator ist der interessanteste Teil der Lösung: Früher habe ich eine Boolesche Regel verwendet, die mit einer Karnaugh-Karte generiert wurde, aber es stellt sich heraus, dass es einen noch präziseren Weg gibt:

(a?b)r=mod(b+r+b*r+a*b*r)2

1
Speichern Sie ein Byte, indem Sie take 40$davor setzen map(" o"!!)<$>.
Ørjan Johansen

3

Schale , 31 28 Bytes

Hah, Husk schlägt Jelly!

†!¨↑¨↑40¡ȯẊȯ!ḋ118ḋėΘ`:0M#ŀ40

Probieren Sie es online!

Erklärung & Ungolfed

Bevor ich eine Erklärung hinzufüge, lassen Sie mich dies ein wenig aufheben. Entfernen wir zuerst die verschiedenen Kompositionen, fügen explizite Klammern hinzu und dekomprimieren die ¨↑¨Zeichenfolge. Auch lassen sie ersetzen 40mit 4für eine besser lesbare Erklärung:

†!"t "↑4¡(Ẋ(!ḋ118ḋė)Θ`:0)M#ŀ4  -- example input: [3]
                           ŀ4  -- lower range of 4: [0,1,2,3]
                         M     -- map over left argument
                          #    -- | count in list
                               -- : [0,0,0,1]
        ¡(              )      -- iterate the following indefinitely (example with [0,1,1,1])
                     `:0       -- | append 0: [0,1,1,1,0]
                    Θ          -- | prepend 0: [0,0,1,1,1,0]
          Ẋ(       )           -- | map over adjacent triples (example with  1 1 0
                  ė            -- | | create list: [1,1,0]
                 ḋ             -- | | convert from base-2: 6
                               -- | | convert 118 to base-2: [1,1,1,0,1,1,0]
                               -- | | 1-based index: 1
                               -- | : [1,1,0,1]
                               -- : [[0,0,0,1],[0,0,1,1],[0,1,1,1],[1,1,0,1],[1,1,1,1],[1,0,0,1],...]
      ↑4                       -- take 4: [[0,0,0,1],[0,0,1,1],[0,1,1,1],[1,1,0,1]]
†                              -- deep map the following (example with [1,1,0,1])
 !"t "                         -- | use each element to index into "t ": "tt t"
                               -- : ["   t","  tt"," ttt","tt t"]

2

Java, 321 Zeichen

Die Eingabe wurde beispielsweise als Argument von der Befehlszeile übergeben java R 38,39

Ich habe noch nie mehr verschleierten Java-Code geschrieben :-)

class R{public static void main(String[]a) {
Integer s=40;boolean[]n,o=new boolean[s];
for(String x:a[0].split(","))o[s.valueOf(x)]=s>0;
for(Object b:o){n=o.clone();
for(int j=0;j<s;j++){
boolean l=j>1&&o[j-1],r=o[j],c=j+1<s&&o[j+1];
n[j]=!(l&c&r|l&!c&!r|!(l|c|r));
System.out.print((r?"X":" ")+(j>s-2?"\n":""));
}o=n;}}}

2

Update: Richtiges Ausgabebeispiel hier (mit 40 Zeilen statt 50): Neue Ausgabe unten (vorherige aus Gründen der Kürze entfernt):

                                      xx
                                     xxx
                                    xx x
                                   xxxxx
                                  xx   x
                                 xxx  xx
                                xx x xxx
                               xxxxxxx x
                              xx     xxx
                             xxx    xx x
                            xx x   xxxxx
                           xxxxx  xx   x
                          xx   x xxx  xx
                         xxx  xxxx x xxx
                        xx x xx  xxxxx x
                       xxxxxxxx xx   xxx
                      xx      xxxx  xx x
                     xxx     xx  x xxxxx
                    xx x    xxx xxxx   x
                   xxxxx   xx xxx  x  xx
                  xx   x  xxxxx x xx xxx
                 xxx  xx xx   xxxxxxxx x
                xx x xxxxxx  xx      xxx
               xxxxxxx    x xxx     xx x
              xx     x   xxxx x    xxxxx
             xxx    xx  xx  xxx   xx   x
            xx x   xxx xxx xx x  xxx  xx
           xxxxx  xx xxx xxxxxx xx x xxx
          xx   x xxxxx xxx    xxxxxxxx x
         xxx  xxxx   xxx x   xx      xxx
        xx x xx  x  xx xxx  xxx     xx x
       xxxxxxxx xx xxxxx x xx x    xxxxx
      xx      xxxxxx   xxxxxxxx   xx   x
     xxx     xx    x  xx      x  xxx  xx
    xx x    xxx   xx xxx     xx xx x xxx
   xxxxx   xx x  xxxxx x    xxxxxxxxxx x
  xx   x  xxxxx xx   xxx   xx        xxx
 xxx  xx xx   xxxx  xx x  xxx       xx x
xx x xxxxxx  xx  x xxxxx xx x      xxxxx
xxxxxx    x xxx xxxx   xxxxxx     xx   x

Bei einem weiteren Rätsel habe ich etwas Interessantes über das Verschachteln von Anweisungen in for-Schleifen in PHP gelernt, und plötzlich sind sie weitaus komplexer als ich ursprünglich dachte. Wenn ich Zeit habe, schätze ich, kann ich diese Punktzahl deutlich übertreffen. Vorerst bleibt es jedoch unverändert bei einem nicht wettbewerbsfähigen Wert von 408.


Meine PHP-Version 408 Zeichen:

Das war ein tolles Rätsel. Ich habe auch ewig mit den Eingaben gespielt, da dies faszinierende Dinge sind, die gesagt werden müssen. Wie auch immer, hier ist meine PHP-Version (die bei weitem nicht so gut ist wie einige der Antworten, aber vollständig ist. In Position 0 nur oben und oben rechts, in Position 39 nur oben und oben links, dh ohne Zeilenumbruch. Also hier ist meine Version:

<?php $a='38,39';$b='';$d=explode(',',$a);for($i=0;$i<40;++$i){$c=' ';
foreach($d as $k=>$v){if($v == $i){$c='x';}}$b.=$c;}echo $b."\n";
for($x=1;$x<41;++$x){$o='';for($i=1;$i<41;++$i){if(($i>1)AND(substr($b,$i-2,1)=='x')){
$l=1;}else{$l=0;}if((substr($b,$i-1,1))=='x'){$v=1;}else{$v=0;}if((substr($b,$i,1))=='x'){
$r=1;}else{$r=0;}if((($l+$v+$r)==2)OR(($v+$r)==1)){$o.='x';}else{$o.=' ';}}
echo $o."\n";$b=$o;}?>

Sie können es hier sehen und ausführen: http://codepad.org/3905T8i8

Eingabe ist eine Eingabezeichenfolge am Anfang als $ a = '38, 39 ';

Die Ausgabe ist wie folgt:

xx removed as was too long originally - had 50 lines, not 40 xx

Hoffe du magst es!!!

PS Ich musste dem Code ein paar Zeilenumbrüche hinzufügen, damit Sie alles sehen und nicht mit einer Bildlaufleiste über die Seite strecken können.


Ihre Ausgabe hat 50 Zeilen
aditsu

Ah, das war, weil ich damit gespielt habe, nachdem ich fertig war und gesehen habe, was passiert ist. Eine geringfügige Änderung der Regeln hat solche interessanten Auswirkungen. Jedenfalls habe ich es jetzt auf 40 geändert und es tut mir leid, dass ich das verpasst habe.
Paul Drewett

Vielleicht möchten Sie auch die Ausgabe ändern: p
aditsu

Die Ausgabe wurde korrigiert und ein neuer Codepad-Link mit dem korrekten Wert hinzugefügt. Danke nochmal.
Paul Drewett

2

Stax , 24 Bytes CP437

╦♥µ╤u{£┬íQ<;▀ΦΣ╢╕╚äZ↕áû↑

Online ausführen und debuggen!

Verwendet den Codepunkt 1 in CP437 für "1" -Zellen.

Hervorragender Fall, um die Kraft dieser Sprache zu zeigen.

Erläuterung

Verwendet die entpackte Version (29 Bytes), um zu erklären.

0]40X*,1&xDQ0]|S3B{:b^374:B@m
0]40X*                           Prepare a tape with 40 cells
      ,1&                        Assign 1 to the cells specified by the input
         xD                      Repeat the rest of the program 40 times
           Q                     Output current tape
            0]|S                 Prepend and append a 0 cell to it
                3B               All runs of length 3
                  {         m    Map each run with block
                   :b            Convert from binary
                     ^           Increment (call this value `n`)
                      374:B      The binary representation of 374
                                 [1,0,1,1,1,0,1,1,0]
                                 which is `01101110` reversed and prepended a 1
                           @     Element at 0-based index `n`

1

K (ngn / k) , 44 bis 35 Bytes

{"X "39{(2\145)@2/'3'1,x,1}\^x?!40}

Probieren Sie es online!

{ } Funktion mit Argument x

!40 Liste der Ints von 0 bis 39

x?Finden Sie ihre Indizes in x, verwenden Sie 0N(die "Ganzzahl Null") für nicht gefunden

^Welche von ihnen sind Nullen? Dies gibt uns die Eingabe, negiert

39{ }\ Wende es 39 Mal an und sammle Zwischenergebnisse in einer Liste

1,x,1 Umgeben Sie die Liste mit 1s (negierte 0s)

3' Dreifache Anzahl aufeinanderfolgender Elemente

2/' jeweils binär decodieren

@ Verwendung als Indizes in ...

2\145 Binärkodierung 145 (negierte Bits von 110)

"X "Verwenden Sie schließlich die 40x40-Matrix als Indizes in der Zeichenfolge "X "(das @hier ist implizit)


Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.