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.