Fisica Bitstring


21

sfondo

Sì, la fisica del bittring è una cosa reale . L'idea è quella di costruire una nuova teoria della fisica usando solo stringhe di bit che si evolvono sotto una regola probabilistica ... o qualcosa del genere. Nonostante abbia letto un paio di articoli a riguardo, sono ancora piuttosto confuso. Tuttavia, l'universo bitstring rende un piccolo codice golf.

Programma Universo

La fisica della bitstring si svolge in un cosiddetto universo del programma . Ad ogni passo dell'evoluzione dell'universo, esiste un elenco finito Ldi stringhe di bit di una certa lunghezza k, a partire dall'elenco a due elementi in [10,11]cui k = 2. Un timestep viene elaborato come segue (nello pseudocodice simile a Python).

A := random element of L
B := random element of L
if A == B:
    for each C in L:
        append a random bit to C
else:
    append the bitwise XOR of A and B to L

Tutte le scelte casuali sono uniformemente casuali e indipendenti l'una dall'altra.

Esempio

Un'evoluzione di esempio di 4 passaggi potrebbe essere simile alla seguente. Inizia con l'elenco iniziale L:

10
11

Scegliamo casualmente A := 10e B := 10, che sono la stessa riga, il che significa che dobbiamo estendere ogni stringa Lcon un bit casuale:

101
110

Quindi, scegliamo A := 101e B := 110, e poiché non sono uguali, aggiungiamo il loro XOR a L:

101
110
011

Quindi, scegliamo A := 011e B := 110, e di nuovo, aggiungiamo il loro XOR:

101
110
011
101

Infine, scegliamo A := 101(ultima riga) e B := 101(prima riga), che sono uguali, quindi estendiamo con bit casuali:

1010
1100
0111
1010

L'obiettivo

Il tuo compito è prendere un intero non negativo tcome input, simulare l'universo del programma per i ttimestep e restituire o stampare l'elenco risultante L. Si noti che t = 0risulta nell'elenco iniziale [10,11]. È possibile produrre Lun elenco di elenchi di numeri interi, un elenco di elenchi di valori booleani o un elenco di stringhe; se l'output va su STDOUT, puoi anche stampare le stringhe di bit una per riga in un formato ragionevole. L'ordine delle stringhe di bit è significativo; in particolare, l'elenco iniziale non può essere [11,10], [01,11]o qualcosa di simile. Sono accettabili sia le funzioni che i programmi completi, le scappatoie standard sono vietate e vince il conteggio di byte più basso.


Possiamo limitare la lunghezza della stringa di bit (ovvero: posso usare numeri a 32 bit e operazioni sui bit)?
edc65,

1
@ edc65 No, la lunghezza delle stringhe può diventare arbitrariamente alta.
Zgarb,

3
@ edc65 I tempi e i requisiti di memoria previsti per superare i 32 bit sono astronomici, ma è giusto dal momento che stiamo simulando un universo. ;)
Zgarb,

5
Questa fisica della stringa di bit è un'idea da crackpot? Non ho letto l'intero documento, ma la frase Abbiamo usato la fisica delle stringhe di bit per fornire una teoria in cui l'approssimazione hbar c / e2 = 22 - 1 + 23 - 1 + 27 - 1 = 137 ha senso in termini di un algoritmo informatico e una teoria dell'informazione mi sembrano un po '... numerologici.
xebtl,

1
@xebtl Anche a me sembra folle. Ricordo di aver letto una giustificazione per l'algoritmo da qualche parte, e suonava più come una pseudo-filosofia cattiva che fisica. Inoltre, la tua descrizione dell'algoritmo sembra corrispondere alla mia versione, forse ti sto fraintendendo in qualche modo.
Zgarb,

Risposte:


7

Pyth, 27 26 byte

u?+RO2GqFKmOG2aGxVFKQ*]1U2

Provalo online: dimostrazione

Spiegazione:

                              implicit: Q = input number
                     *]1U2    the initial list [[1,0], [1,1]]
u                   Q         reduce, apply the following expression Q times to G = ^
          mOG2                  take two random elements of G
         K                      store in K
       qF                       check if they are equal
 ?                              if they are equal:
  +RO2G                           append randomly a 0 or 1 to each element of G
                                else:
              aG                  append to G
                xVFK              the xor of the elements in K

xVFKè equivalente a xMK.
Isaacg,

@isaacg No, xVFKequivale a xMCK, stesso conteggio byte.
Jakube,

11

CJam, 42 40 38 37 byte

1 byte salvato da Sp3000.

B2b2/q~{:L_]:mR_~#L@~.^a+L{2mr+}%?}*p

Spiegazione

Crea lo stato iniziale come numero base-2:

B2b e# Push the the binary representation of 11: [1 0 1 1]
2/  e# Split into chunks of 2 to get [[1 0] [1 1]]

Quindi esegui il ciclo principale e stampa il risultato alla fine:

q~       e# Read and eval input t.
{        e# Run this block t times.
  :L     e#   Store the current universe in L.
  _]     e#   Copy it and wrap both copies in an array.
  :mR    e#   Pick a random element from each copy.
  _~     e#   Duplicate those two elements, and unwrap them.
  #      e#   Find the second element in the first. If they are equal, it will be found at
         e#   index 0, being falsy. If they are unequal, it will not be found, giving
         e#   -1, which is truthy.

         e#   We'll now compute both possible universes for the next step and then select
         e#   the right one based on this index. First, we'll build the one where they were
         e#   not equal.

  L@~    e#   Push L, pull up the other copy of the selected elements and unwrap it.
  .^     e#   Take the bitwise XOR.
  a+     e#   Append this element to L.

  L      e#   Push L again.
  {      e#   Map this block onto the elements in L.
    2mr+ e#     Append 0 or 1 at random. 
  }%     
  ?      e#   Select the correct follow-up universe.
}*
p        e# Pretty-print the final universe.

Provalo qui.


6

Julia, 141 129 byte

t->(L=Any[[1,0],[1,1]];for i=1:t r=1:length(L);A=L[rand(r)];B=L[rand(r)];A==B?for j=r L[j]=[L[j],rand(0:1)]end:push!(L,A$B)end;L)

Niente di intelligente. Crea una funzione senza nome che accetta un numero intero come input e restituisce una matrice di matrici. Per chiamarlo, dagli un nome, ad esf=t->... .

Ungolfed + spiegazione:

function f(t)
    # Start with L0
    L = Any[[1,0], [1,1]]

    # Repeat for t steps
    for i = 1:t
        # Store the range of the indices of L
        r = 1:length(L)

        # Select 2 random elements
        A = L[rand(r)]
        B = L[rand(r)]

        if A == B
            # Append a random bit to each element of L
            for j = r
                L[j] = [L[j], rand(0:1)]
            end
        else
            # Append the XOR of A and B to L
            push!(L, A $ B)
        end
    end

    # Return the updated list
    L
end

Esempi:

julia> f(4)
4-element Array{Any,1}:
 [1,0,1,0]
 [1,1,1,1]
 [0,1,1,0]
 [0,1,0,0]

julia> f(3)
3-element Array{Any,1}:
 [1,0,1,1]
 [1,1,1,0]
 [0,1,0,1]

Risparmiato 12 byte grazie a ML!


Puoi raderlo fino a 133 caratteri se usi l'operatore ternay invece di if / else e se cambi A=something;B=something else to A,B=something,something else:t->(L=Any[[1,0],[1,1]];for i=1:t r=1:length(L);A,B=L[rand(r)],L[rand(r)];A==B?(for j=r L[j]=[L[j],rand(0:1)]end):(push!(L,A$B))end;L)
ML

@ML: bello grazie. Non avevo pensato di usare l'operatore ternario. Ma in realtà non hai bisogno delle parentesi nel ternario, che salva un altro 4 sul tuo suggerimento. Assegnare Ae Bseparatamente è in realtà la stessa lunghezza di assegnarli insieme, quindi ho lasciato quella parte così com'è. Grazie ancora per il tuo suggerimento!
Alex A.

Prego. Ah, capisco. Sì, le parentesi non sono necessarie.
ML

4

Python 2, 141

Ho provato alcuni metodi diversi, ma il meglio che ho potuto ottenere è stato relativamente semplice. Grazie a @ Sp3000 per circa 15 caratteri (e per avermi insegnato sull'esistenza di int.__xor__).

from random import*
L=[[1,0],[1,1]];C=choice
exec"A=C(L);B=C(L);L=[L+[map(int.__xor__,A,B)],[x+[C([1,0])]for x in L]][A==B];"*input()
print L

Ecco 141: link
Sp3000,

4

Python 2, 127 122

Supponendo che le stringhe di bit Python del modulo '0b1'ecc. Siano OK:

from random import*
C=choice
L=[2,3]
exec"x=C(L)^C(L);L=L+[x]if x else[a*2+C([0,1])for a in L];"*input()
print map(bin,L)

L'unica leggera sfumatura qui è l'uso del fatto che XOR (A, B) = 0 iff A = B.

Grazie a @ Sp300 per abbreviare il forciclo di chiusura


Dando un'occhiata ai commenti, penso che gli zero
iniziali

Non posso testare questa risposta in questo momento, ma se non mantiene gli zeri iniziali, è purtroppo errato.
Zgarb,

3

Pyth, 34

u?+RO`TGqJOGKOG+Gsm`s!dqVJKQ[`T`11

Gli usi si riducono per applicare ogni iterazione. Ti spiego quando ho finito di giocare a golf.

Provalo qui


2

K, 46 53 46 byte

{x{:[~/t:2?x;{x,*1?2}'x;x,,,/~=/t]}/(1 0;1 1)}

Una buona parte della dimensione (circa 7 byte) di questo è dovuta al fatto che K non ha xor operatore, quindi ho dovuto implementarne uno da solo. Inizialmente, ho usato un elenco di stringhe, seguito dal rendermi conto che era follemente stupido. Quindi ora ho tagliato di nuovo i 7 byte!

Prima:

{x{:[~/t:2?x;{x,*$1?2}'x;x,,,/$~=/(0$')'t]}/$:'10 11}

@JohnE ha sottolineato nei commenti che lo stato iniziale doveva essere hardcoded, che costa 7 byte extra. : /


La mia lettura delle specifiche del problema è che devi sempre iniziare con l '"universo" hardcoded (1 0;1 1)- il tuo programma lo accetta come input.
JohnE,

@JohnE Risolto. Tuttavia, non esiste alcuna garanzia che funzioni perché non ho verificato le modifiche; Ho appena provato la parte finale nel tuo oK repl ...
kirbyfan64sos il

Sembra funzionare bene anche a Kona.
JohnE,

2

JavaScript ( ES6 ) 152

Una funzione, usando stringhe (con i numeri dovrebbe essere più breve, ma nelle operazioni a bit javascript sono limitate a numeri interi a 32 bit).

Prova in Firefox utilizzando lo snippet di seguito.

F=(t,L=['10','11'],l=2,R=n=>Math.random()*n|0,a=L[R(l)],b=L[R(l)])=>
   t--?a==b
     ?F(t,L.map(x=>x+R(2)),l)
     :F(t,L,L.push([...a].map((x,p)=>x^b[p]).join('')))
  :L
  
test=_=>O.innerHTML=F(+I.value).join('\n')
#I{width:3em}
<input id=I value=10><button onclick=test()>-></button><pre id=O></pre>


1

K, 45 41 38 byte

{x{(x,,~=/t;{x,1?2}'x)@~/t:2?x}/1,'!2}

La struttura della mia risposta è abbastanza simile a quella di @ kirbyfan64sos, ma invece delle stringhe ho usato i vettori 1/0 ed evito la necessità di un condizionale ( :[ ; ; ]) indicizzando invece un elenco.

Alcune corse:

  {x{(x,,~=/t;{x,1?2}'x)@~/t:2?x}/1,'!2}3
(1 0 0 0
 1 1 1 1
 0 1 1 1)

  {x{(x,,~=/t;{x,1?2}'x)@~/t:2?x}/1,'!2}3
(1 0 0
 1 1 0
 0 1 0
 1 0 0)

  {x{(x,,~=/t;{x,1?2}'x)@~/t:2?x}/1,'!2}3
(1 0 0
 1 1 0
 0 1 0
 1 1 0)

Modificare:

Hai salvato quattro byte con un modo più compatto per costruire l'universo iniziale:

1,'!2     / new
(1 0;1 1) / old

Edit2:

Ho dimenticato che "scegliere" può prendere un elenco come argomento giusto:

  2?"abcd"
"dc"
  2?"abcd"
"cc"
  2?"abcd"
"ca"

Quindi posso semplificare una parte di questo. Ringraziando dove è dovuto, Kirby ha ottenuto questo trucco prima di me.

2?x    / new
x@2?#x / old

1
Dang, a volte penso di conoscere K, quindi vedo le tue risposte ...: O
kirbyfan64sos

Penso che questa soluzione sia sicuramente considerata uno sforzo di squadra!
Giovanni,

1

Javascript, 241 233 byte

È un po 'lungo.

a=[[1,0],[1,1]];for(b=prompt();b--;)if(c=a.length,d=a[c*Math.random()|0],e=a[c*Math.random()|0],d+""==e+"")for(f=0;f<c;f++)a[f].push(2*Math.random()|0);else{g=[];for(h=0;h<d.length;h++)g.push(d[h]^e[h]);a.push(g)}alert(a.join("\n"));


216 byte:, for(b=prompt(a=[[1,0],[1,1]]),R=Math.random;b--;){c=a.length;d=a[c*R()|0];e=a[c*R()|0];if(d+""==e+"")for(f=0;f<c;f++)a[f].push(2*R()|0);else{for(h=0,g=[];h<d.length;)g.push(d[h]^e[h++]);a.push(g)}}alert(a.join("\n"))produce l'output desiderato 3/5 del tempo.
Ismael Miguel,

217 byte: for(b=prompt(a=[[1,0],[1,1]]),R=Math.random;b--;){c=a.length;d=a[c*R()|0];e=a[c*R()|0];if(d+""==e+"")for(f=0;f<c;f++)a[f].push(2*R()|0);else{g=[];for(h=0;h<d.length;h++)g.push(d[h]^e[h]);a.push(g)}}alert(a.join("\n"))funziona il 90% delle volte.
Ismael Miguel,

1

T-SQL (2012+), 1019

Mi dispiace davvero che questo non sia affatto competitivo, ma ad essere sincero non pensavo di riuscire a farlo funzionare e ho dovuto pubblicarlo una volta. Ho provato a golf un po ':)

Per gestire le conversioni binarie / intere ho dovuto creare un paio di funzioni scalari (513 byte). Apassa da un numero intero a una stringa di bit. Bfa il contrario.

CREATE FUNCTION A(@ BIGINT)RETURNS VARCHAR(MAX)AS
BEGIN
DECLARE @S VARCHAR(MAX);
WITH R AS(SELECT @/2D,CAST(@%2 AS VARCHAR(MAX))M
UNION ALL
SELECT D/2,CAST(D%2 AS VARCHAR(MAX))+M
FROM R
WHERE D>0)SELECT @S=M FROM R WHERE D=0
RETURN @S
END
CREATE FUNCTION B(@ VARCHAR(MAX))RETURNS BIGINT AS
BEGIN
DECLARE @I BIGINT;
WITH R AS(SELECT CAST(RIGHT(@,1)AS BIGINT)I,1N,LEFT(@,LEN(@)-1)S
UNION ALL 
SELECT CAST(RIGHT(S,1)AS BIGINT)*POWER(2,N),N+1,LEFT(S,LEN(S)-1)
FROM R
WHERE S<>''
)SELECT @I=SUM(I)FROM R
RETURN @I
END

Quindi c'è la procedura. @Cè il numero di passaggi

DECLARE @C INT=9
DECLARE @ TABLE(S VARCHAR(MAX))
DECLARE @R VARCHAR(MAX)
INSERT @ VALUES('10'),('11')
WHILE(@C>=0)
BEGIN
SET @C-=1
SELECT @R=CASE WHEN MAX(S)=MIN(S)THEN''ELSE RIGHT(REPLICATE('0',99)+dbo.A(dbo.B(MAX(S))^dbo.B(MIN(S))),LEN(MAX(S)))END
FROM(SELECT TOP 2S,ROW_NUMBER()OVER(ORDER BY(SELECT\))N FROM @,(VALUES(1),(1),(1))D(D)ORDER BY RAND(CAST(NEWID()AS VARBINARY(50))))A
IF @R=''UPDATE @ SET S=CONCAT(S,ROUND(RAND(CAST(NEWID() AS VARBINARY(50))),0))
ELSE INSERT @ VALUES(@R)
END
SELECT * FROM @

Diecimila iterazioni impiegarono circa 2 minuti e restituirono 9991 righe

1001001100110
1101001001110
0111100100101
1111100001011
1111001010011
0110101001101
...
1110101000100
1111011101100
1100001100010
0110010001001
1110100010100

0

Pyth - 37 byte

Ovvio, segue solo psuedocode. Probabilmente può giocare a golf molto.

KPP^,1Z2VQ=K?m+dO1KqFJ,OKOKaKxVhJeJ;K

Provalo qui online .


3
È necessario O2invece di O1. O1ti dà un numero casuale dall'intervallo U1 = [0].
Jakube,

2
Quindi aggiungi sempre a 0.
Jakube,

0

Mathematica, 106 byte

Nest[If[Equal@@#,Map[#~Append~RandomInteger[]&],Append[BitXor@@#]]&[#~RandomChoice~2]@#&,{{1,0},{1,1}},#]&

0

Perl, 102

#!perl -p
@l=qw(10 11);$_=$l[rand@l]^$l[rand@l],$_|=y//0/cr,@l=/1/?(@l,$_):map{$_.~~rand 2}@l for 1..$_;$_="@l"

Prova a me .


0

R, 186

L=list(0:1,c(1,1))
if(t>0)for(t in 1:t){A=sample(L,1)[[1]]
B=sample(L,1)[[1]]
if(all(A==B)){L=lapply(L,append,sample(0:1, 1))}else{L=c(L,list(as.numeric(xor(A,B))))}}
L

Niente di magico qui. Immettere il valore per tnella console R ed eseguire lo script. È difficile "golf" codice R ma ecco una versione più leggibile:

L <- list(0:1, c(1, 1))
if(t > 0) {
  for(t in 1:t) {
    A <- sample(L, 1)[[1]]
    B <- sample(L, 1)[[1]]
    if (all(A == B)) {
      L <- lapply(L, append, sample(0:1, 1))
    } else {
      L <- c(L,list(as.numeric(xor(A, B))))
    }
  }
}
L

È possibile salvare un numero di caratteri assegnando samplea una variabile. ad esempio s=sample, quindi utilizzare s anziché il campione. Sfortunatamente penso che il tuo metodo di aggiungere un bit casuale lapplyfinirà con l'aggiunta di un campione casuale a tutti gli elementi dell'elenco. lapply(L,function(x)append(x,sample(0:1,1)))sembra funzionare, ma a un costo. Puoi sostituirti as.numericcon il 1*quale dovresti riaverne un po '.
MickyT,

Buona presa su entrambi i punti, e anche un bel trucco di coercizione
Shadowtalker,

Inoltre ho appena notato che il tuo conto è fuori. Lo uso 168 usando questo
MickyT

0

Ruby, 82

Praticamente semplice. Rispetto ad altre lingue non golf, il rubino sembra funzionare bene con la sua grande libreria standard.

->t{l=[2,3]
t.times{a,b=l.sample 2
a.equal?(b)?l.map!{|x|x*2+rand(2)}:l<<(a^b)}
l}

Esempio di output per t = 101010:

[9, 15, 6, 13, 5, 12, 10, 11, 5, 4, 15, 13, 2, 7, 11, 9, 3, 3, 8, 6, 3, 13, 13, 12, 10, 9, 2, 4, 14, 9, 9, 14, 15, 7, 10, 4, 10, 14, 13, 7, 15, 7]
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.