Fizyka bitów


21

tło

Tak, fizyka bitstrów to prawdziwa rzecz . Chodzi o to, aby skonstruować nową teorię fizyki przy użyciu tylko ciągów bitów, które ewoluują zgodnie z regułą probabilistyczną ... Pomimo przeczytania kilku artykułów na ten temat, nadal jestem dość zdezorientowany. Jednak wszechświat bitstrowy tworzy fajny mały golf.

Program Universe

Fizyka bitów ma miejsce w tak zwanym wszechświecie programowym . Na każdym etapie ewolucji wszechświata istnieje skończona lista Lciągów bitów o pewnej długości k, zaczynająca się od dwuelementowej listy [10,11]gdzie k = 2. Jeden timepep jest przetwarzany w następujący sposób (w pseudokodzie podobnym do Pythona).

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

Wszystkie losowe wybory są jednakowo losowe i niezależne od siebie.

Przykład

Przykładowa ewolucja 4 kroków może wyglądać następująco. Zacznij od początkowej listy L:

10
11

Losowo wybieramy A := 10i B := 10, które są tym samym rzędem, co oznacza, że ​​musimy rozszerzyć każdy ciąg Lo losowy bit:

101
110

Następnie możemy wybrać A := 101i B := 110, a ponieważ nie są one równe, dodamy ich do XOR L:

101
110
011

Następnie możemy wybrać A := 011i B := 110, i ponownie dołączyć ich XOR:

101
110
011
101

Na koniec wybieramy A := 101(ostatni wiersz) i B := 101(pierwszy wiersz), które są równe, dlatego rozszerzamy losowymi bitami:

1010
1100
0111
1010

Zadanie

Twoim zadaniem jest przyjęcie nieujemnej liczby całkowitej tjako danych wejściowych, symulacja wszechświata programu pod kątem tkroków czasowych i zwrócenie lub wydrukowanie wynikowej listy L. Zauważ, że t = 0wynikiem jest początkowa lista [10,11]. Możesz wyprowadzać Ljako listę list liczb całkowitych, listę wartości boolowskich lub listę ciągów; jeśli wyjście przechodzi do STDOUT, możesz także wydrukować ciągi bitów po jednym w wierszu w rozsądnym formacie. Kolejność ciągów bitów jest znacząca; w szczególności, początkowa lista nie może być [11,10], [01,11]lub coś podobnego. Zarówno funkcje, jak i pełne programy są dopuszczalne, standardowe luki są niedozwolone, a wygrywa najmniejsza liczba bajtów.


Czy możemy ograniczyć długość łańcucha bitowego (to znaczy: czy mogę używać 32-bitowych liczb i operacji bitowych)?
edc65

1
@ edc65 Nie, długość łańcuchów może być dowolnie wysoka.
Zgarb,

3
@ edc65 Oczekiwany czas i wymagania dotyczące pamięci dla uzyskania ponad 32 bitów są astronomiczne, ale to po prostu pasuje, ponieważ symulujemy wszechświat. ;)
Zgarb

5
Czy ta fizyka bitów to pomysł na crackpot? Nie przeczytałem całego artykułu, ale fraza Użyliśmy fizyki bitów-strun, aby dostarczyć teorię, w której przybliżenie hbar c / e2 = 22-1 + 23-1 + 27-1 = 137 ma sens pod względem algorytm komputerowy i teoria informacji wydają mi się trochę ... numerologiczne.
xebtl

1
@xebtl To też wydaje mi się szalone. Pamiętam, że czytałem gdzieś uzasadnienie algorytmu i brzmiało to bardziej jak zła pseudo-filozofia niż fizyka. Ponadto twój opis algorytmu wydaje się pasować do mojej wersji, być może w jakiś sposób cię źle rozumiem.
Zgarb,

Odpowiedzi:


7

Pyth, 27 26 bajtów

u?+RO2GqFKmOG2aGxVFKQ*]1U2

Wypróbuj online: demonstracja

Wyjaśnienie:

                              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

xVFKjest równoważne z xMK.
isaacg

@isaacg Nie, xVFKodpowiada tej xMCKsamej liczbie bajtów.
Jakube,

11

CJam, 42 40 38 37 bajtów

1 bajt zapisany przez Sp3000.

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

Wyjaśnienie

Utwórz stan początkowy jako liczbę podstawową 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]]

Następnie wykonaj główną pętlę i wydrukuj wynik na końcu:

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.

Sprawdź to tutaj.


6

Julia, 141 129 bajtów

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)

Nic sprytnego. Tworzy nienazwaną funkcję, która przyjmuje liczbę całkowitą jako dane wejściowe i zwraca tablicę tablic. Aby to nazwać, nadaj mu nazwę, np f=t->....

Niegolfowane + wyjaśnienie:

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

Przykłady:

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]

Zaoszczędź 12 bajtów dzięki ML!


Możesz go ogolić do 133 znaków, jeśli użyjesz operatora ternay zamiast if / else i zmienisz 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: Fajnie, dziękuję. Nie myślałem o użyciu operatora trójskładnikowego. Ale tak naprawdę nie potrzebujesz nawiasów w trójce, co oszczędza kolejne 4 nad twoją sugestią. Przypisywanie Ai Bosobno jest w rzeczywistości tej samej długości co przypisywanie ich razem, więc zostawiłem tę część taką, jaka jest. Jeszcze raz dziękuję za sugestię!
Alex A.

Nie ma za co. O, rozumiem. Tak, nawiasy nie są konieczne.
ML

4

Python 2, 141

Wypróbowałem kilka różnych metod, ale najlepsze, co mogłem uzyskać, było stosunkowo proste. Dzięki @ Sp3000 za około 15 znaków (i za nauczenie mnie o istnieniu 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

Oto 141: link
Sp3000,

4

Python 2, 127 122

Zakładając, że ciągi bitów python formularza '0b1'itp. Są 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)

Jedynym łagodnym niuansem jest wykorzystanie faktu, że XOR (A, B) = 0 iff A = B.

Dzięki @ Sp300 za skrócenie zamykającej forpętli


Patrząc na komentarze, myślę, że należy zachować wiodące zera
Sp3000,

Nie mogę teraz przetestować tej odpowiedzi, ale jeśli nie zachowuje ona zer wiodących, jest to niestety niepoprawna.
Zgarb,


2

K, 46 53 46 bajtów

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

Spora część tego rozmiaru (około 7 bajtów) ma związek z faktem, że K nie ma xoroperatora, więc musiałem go zaimplementować. Początkowo użyłem listy ciągów, po czym zdałem sobie sprawę, że to było szalenie głupie. Więc teraz ponownie odciąłem 7 bajtów!

Przed:

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

@JohnE zauważył w komentarzach, że stan początkowy miał być zakodowany na stałe, co kosztuje 7 dodatkowych bajtów. : /


Według mojej specyfikacji problemu zawsze musisz zaczynać od zakodowanego „wszechświata” (1 0;1 1)- twój program przyjmuje to jako dane wejściowe.
JohnE

@JohnE Naprawiono. Nie ma jednak gwarancji, że to zadziała, ponieważ nie przetestowałem zmian; Właśnie próbowałem końcowej części w twojej
replice

Wygląda na to, że dobrze działa również w Kona.
JohnE

2

JavaScript ( ES6 ) 152

Funkcja wykorzystująca ciągi znaków (z liczbami powinna być krótsza, ale w bitach javascript operacje bitowe są ograniczone do 32-bitowych liczb całkowitych).

Przetestuj w Firefoksie za pomocą poniższego fragmentu.

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 bajtów

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

Struktura mojej odpowiedzi jest dość podobna do @ kirbyfan64sos, ale zamiast łańcuchów użyłem wektorów 1/0 i unikam potrzeby warunkowej ( :[ ; ; ]), zamiast indeksowania do listy.

Kilka biegów:

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

Edytować:

Zaoszczędzono cztery bajty w bardziej kompaktowy sposób na zbudowanie początkowego wszechświata:

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

Edycja2:

Zapomniałem, że „wybierz” może przyjąć listę jako swój właściwy argument:

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

Mogę uprościć część tego. Kredyt tam, gdzie jest to należne, Kirby dostała tę sztuczkę, zanim to zrobiłem.

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

1
Cholera, czasami myślę, że znam K, a potem widzę twoje odpowiedzi ...: O
kirbyfan64sos

Myślę, że to rozwiązanie zdecydowanie liczy się jako wysiłek zespołu!
JohnE

1

JavaScript, 241 233 bajtów

To trochę długo.

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"));

Kompilator zamknięcia skompresował go oszczędzając 8 bajtów.
Gustavo Rodrigues

216 bajtów:, 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"))generuje pożądane wyjście 3/5 czasu.
Ismael Miguel

217 bajtów: 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"))działa 90% czasu.
Ismael Miguel

1

T-SQL (2012+), 1019

Naprawdę przepraszam, że nie jest to zbyt konkurencyjne, ale szczerze mówiąc, nie sądziłem, że uda mi się to uruchomić i musiałem to opublikować. Próbowałem trochę zagrać w golfa :)

Aby obsłużyć konwersje binarne / całkowite musiałem stworzyć kilka funkcji skalarnych (513 bajtów). Aprzechodzi z liczby całkowitej na ciąg bitowy.Brobi odwrotnie.

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

Następnie jest procedura. @Cto liczba kroków

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 @

Dziesięć tysięcy iteracji zajęło około 2 minut i zwróciło 9991 wierszy

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

0

Pyth - 37 bajtów

Oczywiście, po prostu postępuje zgodnie z psuedocode. Prawdopodobnie dużo gra w golfa.

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

Wypróbuj tutaj online .


3
Potrzebujesz O2zamiast O1. O1daje losową liczbę z zakresu U1 = [0].
Jakube,

2
Więc zawsze dołączasz 0.
Jakube,

0

Mathematica, 106 bajtów

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"

Spróbuj mnie .


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

Nic magicznego tutaj. Wprowadź wartość dla tw konsoli R. Uruchom skrypt. Kod R jest trudny do „golfa”, ale oto bardziej czytelna wersja:

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

Możesz zapisać liczbę znaków, przypisując sampledo zmiennej. np. s=samplenastępnie użyj s zamiast próbki. Niestety myślę, że twoja metoda dodawania losowego bitu lapplyzakończy się dodaniem jednej losowej próbki do wszystkich pozycji na liście. lapply(L,function(x)append(x,sample(0:1,1)))wydaje się działać, ale kosztuje. Można zastąpić cię as.numericz 1*co powinno trochę plecy.
MickyT,

Dobry chwyt w obu punktach i niezła sztuczka przymusu
shadowtalker

Zauważyłem też, że nie ma twojej liczby. Robię to 168 używając tego
MickyT,

0

Ruby, 82

Niemal proste. W porównaniu z innymi językami nie golfowymi, ruby ​​wydaje się dobrze sobie radzić z dużą standardową biblioteką.

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

Przykładowe dane wyjściowe dla 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]
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.