Bitstring Physics

21

fundo

Sim, a física da cadeia de bits é uma coisa real . A idéia é construir uma nova teoria da física usando apenas cadeias de bits que evoluem sob uma regra probabilística ... ou algo assim. Apesar de ler alguns artigos sobre isso, ainda estou bastante confusa. No entanto, o universo bitstring contribui para um bom código de golfe.

Program Universe

A física da cadeia de bits ocorre no chamado universo do programa . Em cada etapa da evolução do universo, há uma lista finita Lde cadeias de bits de algum comprimento k, começando pela lista de dois elementos em [10,11]que k = 2. Um timestep é processado da seguinte maneira (no pseudocódigo do tipo 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

Todas as escolhas aleatórias são uniformemente aleatórias e independentes uma da outra.

Exemplo

Um exemplo de evolução de 4 etapas pode parecer com o seguinte. Comece com a lista inicial L:

10
11

Escolhemos aleatoriamente A := 10e B := 10, que são a mesma linha, o que significa que precisamos estender cada sequência Lcom um bit aleatório:

101
110

Em seguida, escolhemos A := 101e B := 110, como eles não são iguais, adicionamos seu XOR a L:

101
110
011

Em seguida, escolhemos A := 011e B := 110, novamente, anexamos seu XOR:

101
110
011
101

Finalmente, escolhemos A := 101(última linha) e B := 101(primeira linha), que são iguais, portanto, estendemos com bits aleatórios:

1010
1100
0111
1010

A tarefa

Sua tarefa é pegar um número inteiro não negativo tcomo entrada, simular o universo do programa para ttimesteps e retornar ou imprimir a lista resultante L. Observe que t = 0resulta na lista inicial [10,11]. Você pode imprimir Lcomo uma lista de listas de números inteiros, lista de listas de valores booleanos ou uma lista de strings; se a saída for STDOUT, você também poderá imprimir as cadeias de bits uma por linha em algum formato razoável. A ordem das seqüências de bits é significativa; em particular, a lista inicial não pode ser [11,10], [01,11]ou algo assim. Ambas as funções e programas completos são aceitáveis, brechas padrão não são permitidas e a menor contagem de bytes vence.

Zgarb
fonte
Podemos limitar o comprimento da sequência de bits (ou seja: posso usar números de 32 bits e operações de bits)?
Edc65
11
@ edc65 Não, o comprimento das strings pode ficar arbitrariamente alto.
Zgarb
3
@ edc65 Os requisitos de tempo e memória esperados para obter mais de 32 bits são astronômicos, mas isso é adequado, pois estamos simulando um universo. ;)
Zgarb 16/06
5
Essa física de cadeia de bits é uma idéia maluca? Não li o artigo inteiro, mas a frase Usamos a física de cadeia de bits para fornecer uma teoria na qual a aproximação hbar c / e2 = 22 - 1 + 23 - 1 + 27 - 1 = 137 faz sentido em termos de um algoritmo de computador e teoria da informação me parece um pouco ... numerológico.
xebtl
11
@xebtl Parece louco para mim também. Lembro-me de ler uma justificativa para o algoritmo em algum lugar, e parecia mais uma pseudo-filosofia ruim do que física. Além disso, sua descrição do algoritmo parece corresponder à minha versão, talvez eu esteja entendendo mal você de alguma forma.
Zgarb

Respostas:

7

Pitão, 27 26 bytes

u?+RO2GqFKmOG2aGxVFKQ*]1U2

Experimente online: Demonstração

Explicação:

                              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
Jakube
fonte
xVFKé equivalente a xMK.
Isaacg
@isaacg Não, xVFKé equivalente à xMCKmesma contagem de bytes.
Jakube 16/06
11

CJam, 42 40 38 37 bytes

1 byte salvo pelo Sp3000.

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

Explicação

Crie o estado inicial como um número de 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]]

E, em seguida, execute o loop principal e imprima o resultado no final:

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.

Teste aqui.

Martin Ender
fonte
6

Julia, 141 129 bytes

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)

Nada inteligente. Cria uma função sem nome que aceita um número inteiro como entrada e retorna uma matriz de matrizes. Para chamá-lo, dê um nome, por exemplo f=t->....

Ungolfed + explicação:

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

Exemplos:

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]

Economizou 12 bytes graças ao ML!

Alex A.
fonte
Você pode reduzir para 133 caracteres se usar o operador ternay em vez de if / else e se alterar 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: Bom, obrigado. Eu não tinha pensado em usar o operador ternário. Mas na verdade você não precisa dos parênteses no ternário, o que economiza outros 4 em relação à sua sugestão. Atribuir Ae Bseparadamente é na verdade o mesmo comprimento que atribuí-los juntos, então deixei essa parte como está. Obrigado novamente por sua sugestão!
Alex A.
De nada. Ah entendo. Sim, os parênteses não são necessários.
ML
4

Python 2, 141

Tentei alguns métodos diferentes, mas o melhor que pude obter foi relativamente simples. Agradeço ao @ Sp3000 por 15 caracteres ou mais (e por me ensinar sobre a existência de 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
KSab
fonte
Aqui está 141: link
Sp3000
4

Python 2, 127 122

Supondo que cadeias de bits python do formulário '0b1'etc. estejam 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)

Apenas uma nuance leve aqui é o uso de XOR (A, B) = 0 se A = B.

Agradecimentos ao @ Sp300 por diminuir o forloop fechado

joc
fonte
Dando uma olhada nos comentários porém, acho que zeros à esquerda precisam ser preservados
SP3000
Não posso testar esta resposta no momento, mas se ela não preservar os zeros à esquerda, é realmente incorreta.
Zgarb
3

Pyth, 34

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

Usa reduzir para aplicar cada iteração. Vou explicar quando terminar o golfe.

Experimente aqui

FryAmTheEggman
fonte
2

K, 46 53 46 bytes

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

Uma boa parte do tamanho (cerca de 7 bytes) disso se deve ao fato de K não ter xor operador, então eu mesmo tive que implementar um. Originalmente, eu usei uma lista de strings, seguida por perceber que era insanamente estúpido. Então agora eu cortei os 7 bytes novamente!

Antes:

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

@JohnE apontou nos comentários que o estado inicial deveria ser codificado, o que custou 7 bytes extras. : /

kirbyfan64sos
fonte
Minha leitura da especificação do problema é que você sempre deve começar com o "universo" codificado (1 0;1 1)- seu programa aceita isso como entrada.
Johne
@JohnE Fixed. No entanto, não há garantia de que isso funcione porque eu não testei as alterações; Eu apenas tentei a parte final em sua repl ok ...
kirbyfan64sos
Parece funcionar bem em Kona também.
Johne
2

JavaScript ( ES6 ) 152

Uma função que usa strings (com números deve ser menor, mas nas operações de javascript bit são limitadas a números inteiros de 32 bits).

Teste no Firefox usando o trecho de código abaixo.

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>

edc65
fonte
1

K, 45 41 38 bytes

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

A estrutura da minha resposta é bastante semelhante à do @ kirbyfan64sos, mas em vez de strings eu usei vetores 1/0 e evito a necessidade de um condicional (:[ ; ; ] ) indexando em uma lista.

Algumas execuções:

  {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)

Editar:

Salva quatro bytes com uma maneira mais compacta de construir o universo inicial:

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

Edit2:

Esqueci que "escolher" pode ter uma lista como argumento correto:

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

Para que eu possa simplificar parte disso. Crédito onde é devido, Kirby pegou esse truque antes de mim.

2?x    / new
x@2?#x / old
JohnE
fonte
11
Dang, às vezes acho que conheço K, então vejo suas respostas ...: O #
kirbyfan64sos 15/15/15
Eu acho que essa solução definitivamente conta como um esforço de equipe!
Johne
1

Javascript, 241 233 bytes

Isso é longo.

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"));
SuperJedi224
fonte
O compilador de fechamento o compactou , economizando 8 bytes.
Gustavo Rodrigues
216 bytes:, 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"))produz a saída desejada 3/5 do tempo.
Ismael Miguel
217 bytes:, 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"))funciona 90% do tempo.
Ismael Miguel
1

T-SQL (2012+), 1019

Lamento muito que isso não seja nem um pouco competitivo, mas, para ser sincero, não achei que conseguisse fazer isso funcionar e tive que publicá-lo uma vez. Eu tentei jogar um pouco de golfe :)

Para lidar com as conversões binárias / inteiras, tive que criar algumas funções escalares (513 dos bytes). Apassa de inteiro para uma sequência de bits. Bfaz o contrário.

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

Depois, há o procedimento. @Cé o número de etapas

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 @

Dez mil iterações levaram cerca de 2 minutos e retornaram 9991 linhas

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

Pitão - 37 bytes

Óbvio, apenas segue psuedocode. Provavelmente pode jogar muito golfe.

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

Experimente aqui online .

Maltysen
fonte
3
Você precisa em O2vez de O1. O1fornece um número aleatório do intervalo U1 = [0].
Jakube
2
Então você está sempre acrescentando a 0.
Jakube 15/06
0

Mathematica, 106 bytes

Nest[If[Equal@@#,Map[#~Append~RandomInteger[]&],Append[BitXor@@#]]&[#~RandomChoice~2]@#&,{{1,0},{1,1}},#]&
alefalpha
fonte
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"

Experimente- me .

nutki
fonte
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

Nada de mágico aqui. Digite o valor para tno console R e execute o script. É difícil "jogar golfe" no código R, mas aqui está uma versão mais legível:

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
shadowtalker
fonte
Você pode salvar um número de caracteres atribuindo samplea uma variável. por exemplo s=sample, use s em vez de amostra. Infelizmente, acho que seu método de anexar um bit aleatório no lapplyfinal terminará com uma amostra aleatória sendo adicionada a todos os itens da lista. lapply(L,function(x)append(x,sample(0:1,1)))parece funcionar, mas a um custo. Você pode substituí-lo as.numericpelo 1*que deve receber de volta.
MickyT
Boa captura em ambos os pontos, e um truque agradável coerção também
shadowtalker
Também notei que sua contagem está esgotada. Eu consegui 168 usando isso #
MickyT 17/06/2015
0

Ruby, 82

Praticamente direto. Comparado com outras línguas que não praticam golfe, o ruby ​​parece se dar bem com sua grande biblioteca padrão.

->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}

Saída de amostra para 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]
blutorange
fonte