Pseudozufälliger zellularer Automat


14

Einführung

In dieser Aufgabe simulieren wir einen bestimmten probabilistischen zellulären Automaten mit sehr schlechten Pseudozufallszahlen. Der zellulare Automat wird in binären Zeichenfolgen durch die folgende lokale Regel definiert. Angenommen, der linke Nachbar einer Zelle und die Zelle selbst haben die Zustände aund b.

  • Wenn min(a,b) == 0, dann wird der neue Zustand bheißt max(a,b).
  • Wenn ja min(a,b) == 1, dann wird der neue Zustand bzufällig aus ausgewählt {0,1}.

Das folgende Bild zeigt eine mögliche 10-stufige Entwicklung eines einzelnen 1.

1
11
101
1111
11001
101011
1111111
10001001
110011011
1010111101

Man beachte, wie sich zwei benachbarte 1s manchmal zu 1und manchmal zu 0entwickeln und die am weitesten am Rand liegenden Bits immer 1s sind. Ihre Aufgabe ist es, einen zellulären Automaten dieser Form zu entwickeln.

Eingänge

Ihre Eingaben sind eine positive Ganzzahl n, die die Anzahl der anzuzeigenden Zeilen angibt, und eine nicht leere Liste von Bits L, die wir als Zufallsquelle verwenden.

Ausgabe

Ihre Ausgabe ist eine Liste von Listen oder ein 2D-Array von Bits, die die Entwicklung eines einzelnen Elements 1für nZeitschritte wie in der obigen Abbildung darstellen. Sie können die Ausgabe mit 0s auffüllen, um Zeilen gleicher Länge zu erhalten. Es dürfen jedoch keine führenden 0s vorhanden sein.

Die zufälligen Auswahlen im zellularen Automaten müssen aus der Liste gezogen werden Lund an den Anfang zurückspringen, wenn sie erschöpft sind. Genauer gesagt, wenn die Ausgabe zeilenweise von oben nach unten und von links nach rechts durchlaufen wird, bilden die aufeinanderfolgenden Zufallsauswahlen die Liste, die Lso oft wie nötig wiederholt wird.

Beispiel

Angenommen, die Eingaben sind n = 7und L = [0,1,0]. Dann entwickelt sich der zellulare Automat wie folgt in den 7 Schritten, in denen wir vüber jede zufällige Auswahl ein Rechts setzen :

[1]

[1,1]
   v
[1,0,1]

[1,1,1,1]
   v v v
[1,1,0,0,1]
   v
[1,1,1,0,1,1]
   v v   v
[1,0,0,1,1,1,1]

Wenn wir alle mit einem gekennzeichneten Bits lesen v, erhalten wir 01001001, was L2,66-mal wiederholt wird. Das nächste zufällige Bit wäre 0.

Regeln und Wertung

Sie können ein vollständiges Programm oder eine Funktion schreiben. Die niedrigste Byteanzahl gewinnt, und Standardlücken sind nicht zulässig. Das genaue Format der Ein- und Ausgänge ist (aus vernünftigen Gründen) unwichtig.

Testfälle

Deterministische Version, jedes zufällige Bit ist 0:

Inputs: 10 [0]
Output:
1
11
101
1111
10001
110011
1010101
11111111
100000001
1100000011

Jeder Zufallsbit ist 1:

Inputs: 6 [1,1]
Output:
1
11
111
1111
11111
111111

Pseudozufällige Versionen:

Inputs: 10 [0,0,1]
Output:
1
11
101
1111
10101
111111
1010011
11110101
101011111
1111101001

Inputs: 10 [1,0,0,1]
Output:
1
11
111
1001
11011
111111
1001101
11010111
111111101
1011001111

Inputs: 15 [1,1,1,0,0,0]
Output:
1
11
111
1111
10001
110011
1110111
11011001
111111011
1100011111
11100100011
111101100101
1001111101111
11011000111111
101101001011101

Antworten:


3

Pyth, 33 Bytes

jjLk.u++1m?hSde=.<Q1sd.:N2 1tvz]1

Probieren Sie es online aus: Demonstration oder Test Suite

Erläuterung:

jjLk.u++1m?hSde=.<Q1sd.:N2 1tvz]1  implicit: Q = input list
    .u                      tvz]1  reduce N=[1] input-1 times by applying
                      .:N2           all substrings of length 2
         m                           map each d of ^ to:
          ?hSd                         if min(d) = 0 then:
               =.<Q1                     rotate Q by one
              e                          and use the last element
                    sd                 else use sum(d) (=max(d))
      ++1                  1         add a 1 at the front and the back
                                   .u gives all intermediate results
 jLk                               join these lists to strings
j                                  print each string on a line

7

Netzhaut , 139 Bytes

^.
1

 00:0 01:1 10:1 11:
(m`^(..)((\S*)(?<=0) .*)
$1$3#$1!$2
+m`(?<=^(?<-2>.)*(..).*?#(.)*.)\d!(.)(.*\1:)(.)(\d*)
$5$3!$4$6$5
)`!0
0
 .+
<empty>

Wobei <empty>darauf hinweist, dass am Ende eine leere Zeile steht. Jede Zeile wird in eine separate Datei geschrieben und #sollte durch Zeilenvorschübe (0x0A) ersetzt werden.

Erwartet , dass die eingegeben werden nin unäre (hergestellt von Nullen, wie in Unary ), gefolgt von einem Leerzeichen, gefolgt von dem „pseudo-random“ string, zB10, [1, 0, 0, 1] würde , wie zu lesen

0000000000 1001

Die Ausgabe erfolgt wie bei der Abfrage, jedoch mit Nullen aufgefüllt, z

1000000000
1100000000
1110000000
1001000000
1101100000
1111110000
1001101000
1101011100
1111111010
1011001111

Das war viel kniffliger als ich erwartet hatte ...


3

Python, 142 135 132 131 Bytes

133 132 131 Byte Version

f=input;n=f();L=f()*n*n;r=[1];i=1
while i<=n:print r;r=[L.pop(0)if r[x-1]&r[x]else r[x-1]+r[x]for x in range(1,i)];r=[1]+r+[1];i+=1

ersetzt r[x-1]+r[x]>1durch r[x-1]&r[x]Wäre der bitweise Operator & ergibt den Minimalwert in(r[x-1],r[x])

Vielen Dank an @ThomasKwa für den Vorschlag n*nstattn**2 1 Byte zu sparen!

Danke @Shebang für das -1 Byte

135-Byte-Version

f=input;n=f();L=f()*n**2;r=[1];i=1
while i<=n:print r;r=[L.pop(0)if r[x-1]+r[x]>1 else r[x-1]+r[x]for x in range(1,i)];r=[1]+r+[1];i+=1

Danke an @Cole für die -7 Bytes:

min(r[x-1],r[x])->r[x-1]+r[x]>1

max(r[x-1],r[x])->r[x-1]+r[x]

142-Byte-Version

f=input;n=f();L=f()*n**2;r=[1];i=1
while i<=n:print r;r=[L.pop(0)if min(r[x-1],r[x])else max(r[x-1],r[x])for x in range(1,i)];r=[1]+r+[1];i+=1

Nicht einmal in der Nähe von @ Jakubes Antwort, aber ich hatte viel Spaß beim Codieren und Golfen.

Erwartet zwei Eingaben: Die erste Eingabe ist die Anzahl der Zeilen und die zweite Eingabe ist die Pseudozufallsquellenliste . Es wird eine Zeile nach der anderen in einer neuen Zeile auf der Konsole gedruckt.

Als Beispiel:

10 # This is input
[0] # This is input
[1] <- First output row
[1, 1]
[1, 0, 1]
[1, 1, 1, 1]
[1, 0, 0, 0, 1]
[1, 1, 0, 0, 1, 1]
[1, 0, 1, 0, 1, 0, 1]
[1, 1, 1, 1, 1, 1, 1, 1]
[1, 0, 0, 0, 0, 0, 0, 0, 1]
[1, 1, 0, 0, 0, 0, 0, 0, 1, 1]

Nun eine kurze Erklärung, wie es funktioniert:

f=input;n=f();L=f()*n*n;r=[1];i=1 First we define the input() function as f 
                                   for saving bytes as we have to call it twice.
                                   Then L is defined as a list made of the 
                                   pseudorandom numbers in their order *many* times 
                                   (were *many* is an upperbound of the canges that 
                                   could be done); r as the first row and i as the row 
                                   counter.

while i<=n:print r                 A while loop that exits when the nth row has been 
                                   calculated and the printing of the actual row.

r=[L.pop(0)if r[x-1]&r[x] else r[x-1]+r[x] for x in range(1,i)];r=[1]+r+[1];i+=1
     ^           ^                 ^                         ^
     |           |                 |Same as max(r[x-1],r[x]) | from 2nd to last element
     |           | Same as min(r[x-1],r[x]) (0->False;1->True)                
     | get random bit from pseudorandom list    

Der Trick dabei ist, dass wir wissen, dass die Bitliste immer mit einem beginnt und endet, 1da das erste und das letzte Element aufgrund der Spezifikationen niemals geändert werden. der Frage. Das ist der Grund für die Aussage[1]+r+[1] .

Aber wenn rwie initialisiert wird [1], gibt es keine Änderungen in der ersten Zeile und dann fügen wir hinzu, [1]+r+[1]wie kommt es, dass die zweite Zeile nicht ist [1,1,1]?

Dies liegt daran, dass bei der ersten Iteration i=1so range(1,i)eine leere Liste zurückgegeben wird und infolge des forin der Liste enthaltenen Verständnisses nichts zu iterieren ist, rso dass eine leere Liste entsteht [1]+r+[1]=[1,1]. Dies geschieht nur bei der ersten Iteration, die für uns gerade ideal ist!

PS: Sie können gerne Vorschläge machen, wie Sie mehr Golf spielen können.


1
Ich entschuldige mich, wenn ich die Herausforderung nicht richtig verstehe, aber können Sie nicht min(a,b)mit a+b>1und max(a,b)mit ersetzen a+b? Mir ist klar, dass Sie wahrscheinlich etwas tun müssen, um den allerersten Fall von 1-> zu behandeln 11(ich denke, Sie könnten es tun L=[1]+f()...oder einen Weg finden, 1 in die Vorderseite von einzufügen, Lda dies immer 1 für die zweite Zeile
einschließen

@Cole Glücklicherweise müssen keine Änderungen am Rest des Programms vorgenommen werden, da die Änderungen nur die Art und Weise beeinflussen, wie die Min- und Max-Werte eines Bitpaares bekannt sind.
Ioannes

1
Sie haben verpasst, dass Sie hier ein Leerzeichen entfernen können: r[x-1]&r[x] else:)
Kade

Würde n ** 2 -> n * n funktionieren?
Lirtosiast

@ Thomas Du hast recht!
Ioannes

2

MATLAB, 146, 143 138

(Funktioniert auch mit Octave Online, aber Sie müssen sich anmelden, um die Funktion in einer Datei zu speichern.)

function o=c(n,L);o=zeros(n);o(:,1)=1;for i=2:n;for j=2:i;a=o(i-1,j-1);b=o(i-1,j);c=a|b;d=a&b;c(d)=L(d);L=circshift(L,-d);o(i,j)=c;end;end

Die Funktion nimmt eine Eingabe nund Lund gibt ein Array zurücko das die Ausgabe enthält.

Bei den Eingabewerten nhandelt es sich um einen Skalar und Leinen Spaltenvektor, der im Format angegeben werden kann [;;;]. Nicht ganz das, was du zeigst, aber du sagst, es ist innerhalb der Vernunft flexibel und das scheint so.

Die Ausgabe ist als n x nArray mit 0en und 1en formatiert .

Und eine Erklärung:

function o=c(n,L)
%Create the initial array - an n x n square with the first column made of 1's
o=zeros(n);o(:,1)=1;
%For each row (starting with the second, as the first is done already)
for i=2:n;
    %For each column in that row, again starting with the second as the first is done
    for j=2:i;
        %Extract the current and previous elements in the row above
        a=o(i-1,j-1); %(previous)
        b=o(i-1,j);   %(current)
        %Assume that min()==0, so set c to max();
        c=a|b;
        %Now check if min()==1
        d=a&b;
        %If so, set c to L(1)
        c(d)=L(d);
        %Rotate L around only if min()==1
        L=circshift(L,-d);
        %And store c back to the output matrix
        o(i,j)=c;
    end;
end

Update: Ich habe es geschafft, die if-else-Anweisung zu optimieren, um ein paar Bytes zu sparen. Das Eingabeformat wurde wieder in den Spaltenvektor geändert.


1

Haskell, 153 149 Bytes

j[_]o l=(l,o)
j(a:u@(b:c))o q@(l:m)|a*b==0=j u(o++[a+b])q|1<2=j u(o++[l])m
k(r,a)=fmap((1:).(++[1]))$j a[]r
n%l=map snd$take n$iterate k(cycle l,[1])

%gibt eine Liste von Bitlisten zurück. Anwendungsbeispiel:

> 10 % [1,0,0,1] 
[[1],[1,1],[1,1,1],[1,0,0,1],[1,1,0,1,1],[1,1,1,1,1,1],[1,0,0,1,1,0,1],[1,1,0,1,0,1,1,1],[1,1,1,1,1,1,1,0,1],[1,0,1,1,0,0,1,1,1,1]]

Ach je! Das Tragen der zufälligen Liste List Schmerz pur. Mal sehen, ob das kürzer sein kann.


1

152 Bytes

Hier gibt es nichts Besonderes. Die Funktion gibt ein 2D-Array zurück, wobei der erste Rang die Zeile und der zweite die Spalte ist.

Eingezogene und neue Zeilen für Klarheit:

int[,]F(int n,int[]l){
    var o=new int[n,n];
    for(int y=0,x,i=0,m;y<n;y++)
        for(o[y,x=0]=1;x++<y;)
            o[y,x]=(m=o[y-1,x-1]+o[y-1,x])<2?m:l[i++%l.Length];
    return o;
}

1

TI-BASIC, 106 94 87 86 87 Bytes

Prompt N,B
"∟B(1+remainder(𝑛,dim(∟B→u
{1
For(I,1,N
Disp Ans
augment({0},Ans)+augment(Ans,{0
Ans and Ans≠2+seq(u(𝑛-(Ans(X)<2)+2dim(∟B)),X,1,dim(Ans
End

TI-BASIC hat keinen Inkrementoperator, oder? Nun, das tut es irgendwie. Die unormalerweise bei Sequenzen verwendete Gleichungsvariable hat eine undurchsichtige Eigenschaft: Wenn usie mit einem Argument aufgerufen wird, die Variable𝑛 auf eins größer als dieses Argument gesetzt. Das bedingte Inkrement hängt davon ab. (Ich habe lange darauf gewartet, es zu benutzen.)

Damit die Listenindizierung ordnungsgemäß funktioniert, 𝑛muss der Standardwert 0 und 𝑛Minder Standardwert 1 sein. Löschen Sie daher entweder den Arbeitsspeicher Ihres Rechners oder legen Sie diese Werte manuell fest, bevor Sie dies ausführen.

augment({0},Ans)+augment(Ans,{0Berechnet eine Liste von Summen zweier benachbarter Elemente, sodass eine Liste von 0s, 1s und 2s zurückgegeben wird. Dann ist die Magie in dieser Zeile:

Ans and Ans≠2+seq(u(𝑛-(Ans(X)≠2)+dim(∟B)),X,1,dim(Ans

Ans and                 ;set 0s to 0
Ans≠                    ;set to 0 all sums that equal...
2+
  seq(...,X,1,dim(Ans   ;execute for each element of the list
      u(                ;return this element in list of bits (looping)        
        𝑛               ;current location in the list
        -(Ans(X)≠2)+    ;subtract 1 if the element isn't 2
        2dim(∟B)        ;Add twice the dimension of the list
                           ;(because n<nMin on the first iteration, it's out of the domain
                           ;this prevents an error)
       )                      ;set n to one greater than that value
                              ;i.e. increment if element≠2
                        ;Will equal Ans(X) iff Ans(X)=2 and the bit read false

Das Ergebnis dieser Zeile ist, dass Listenelemente 0 sind, wenn sie 0 waren oder wenn sie 2 waren und das gelesene Bit 0 war.

Result of above line
n \ u |  0  |  1
0        0     0

Testfall:

N=?7
B=?{0,1,0
             {1}
           {1 1}
         {1 0 1}
       {1 1 1 1}
     {1 1 0 0 1}
   {1 1 1 0 1 1}
 {1 0 0 1 1 1 1}
            Done
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.