ビットストリング物理学


21

バックグラウンド

はい、ビットストリング物理学は本物です。アイデアは、確率論的ルール...または何かの下で進化するビット列のみを使用して、物理学の新しい理論を構築することです。それについていくつかの論文を読んだにもかかわらず、私はまだかなり混乱しています。ただし、ビットストリングユニバースは、素敵な小さなコードゴルフを実現します。

プログラムユニバース

ビットストリング物理学は、いわゆるプログラムユニバースで行われます。宇宙の進化の各ステップには、2要素のリストで始まる、L長さのあるビット文字列の有限リストがあります。1つのタイムステップは、次のように処理されます(Pythonのような擬似コード)。k[10,11]k = 2

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

すべてのランダムな選択は、一様にランダムであり、互いに独立しています。

4ステップの進化の例は次のようになります。最初のリストから始めますL

10
11

同じ行であるA := 10とをランダムに選択しますB := 10。つまり、各文字列をLランダムビットで拡張する必要があります。

101
110

次に、我々は選択A := 101してB := 110、それらが等しくないので、我々は彼らのXORを追加しますL

101
110
011

次に、とを選択A := 011B := 110、再びXORを追加します。

101
110
011
101

最後に、A := 101(最後の行)とB := 101(最初の行)を選択します。これらは等しいため、ランダムビットで拡張します。

1010
1100
0111
1010

タスク

あなたの仕事はt、入力として負でない整数を取り、tタイムステップのプログラムユニバースをシミュレートし、結果のリストを返すか印刷することLです。その注意t = 0初期リストに結果を[10,11]L整数のリストのリスト、ブール値のリストのリスト、または文字列のリストとして出力できます。出力がSTDOUTに送られた場合、ビットストリングを適切な形式で1行に1つずつ印刷することもできます。ビット列の順序は重要です。特に、最初のリストを[11,10][01,11]またはそのようなものにすることはできません。関数と完全なプログラムの両方が許容され、標準の抜け穴は許可されず、最小のバイト数が優先されます。


ビット文字列の長さを制限できますか(つまり、32ビットの数値とビット操作を使用できますか)。
edc65

1
@ edc65いいえ、文字列の長さは任意に大きくすることができます。
ズガルブ

3
@ edc65 32ビットを超えるために予想される時間とメモリ要件は天文学的なものですが、宇宙をシミュレートしているので、それはちょうど適切です。;)
ズガルブ

5
このビット列物理学はクラックポットのアイデアですか?論文全体を読んだわけではありませんが、 ビット列物理学を使用して、近似hbar c / e2 = 22-1 + 23-1 + 27-1 = 137が理にかなっているという理論を提供しました。コンピューターアルゴリズムと情報理論は、ちょっと数秘術的だと思います。
xebtl

1
@xebtlそれは私にとってもクレイジーなようです。私はどこかでアルゴリズムの正当性を読んだことを覚えていますが、それは物理学というよりも悪い擬似哲学のように聞こえました。また、アルゴリズムの説明は私のバージョンと一致しているようです。おそらく、何らかの形で誤解しています。
ズガーブ

回答:


7

Pyth、27 26バイト

u?+RO2GqFKmOG2aGxVFKQ*]1U2

オンラインで試す:デモンストレーション

説明:

                              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はと同等xMKです。
isaacg

@isaacgいいえ、同じバイト数xVFKと同等xMCKです。
寂部

11

CJam、42 40 38 37バイト

Sp3000で1バイト節約。

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

説明

初期状態をベース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]]

そして、メインループを実行し、最後に結果をきれいに出力します。

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.

ここでテストしてください。


6

ジュリア、141 129バイト

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)

何も賢い。入力として整数を受け入れ、配列の配列を返す名前のない関数を作成します。呼び出すには、名前を付けf=t->...ます。

Ungolfed +説明:

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

例:

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]

MLのおかげで12バイト節約できました!


あなたはそれをダウン剃ることができます133文字あなたが変更した場合/場合は、他とあなたはテルネ演算子を使用する代わりの場合A=something;B=something else to A,B=something,something elset->(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:ありがとう、ありがとう。三項演算子を使用することは考えていませんでした。しかし、実際には3項に括弧は必要ないので、提案をさらに4つ節約できます。割り当てABなるように、私はその部分を残して、別々に実際にそれらを割り当てることと同じ長さです。ご提案ありがとうございます!
アレックスA.

どういたしまして。ああ、なるほど。はい、括弧は必要ありません。
ML

4

Python 2、141

いくつかの異なる方法を試しましたが、得られた最善の方法は比較的簡単でした。15文字程度の@ Sp3000に感謝します(およびの存在について教えてくれました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


4

Python 2、127 122

フォーム'0b1'などのpythonビット文字列は問題ないと仮定します。

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)

ここでの軽微なニュアンスは、A = Bの場合にXOR(A、B)= 0であるという事実の使用です。

囲みforループを短縮してくれた@ Sp300に感謝


コメントを見てみると、先行ゼロを保持する必要がある
-Sp3000

私は今、この答えをテストすることはできませんが、先行ゼロを保持しない場合、残念ながら間違っています。
ズガーブ


2

K、46 53 46バイト

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

このサイズのかなりの部分(約7バイト)は、Kにxor演算子がないためです。したがって、自分で1つ実装しなければなりませんでした。もともと、私は文字列のリストを使用し、それがめちゃくちゃばかげていることに気づきました。だから今、私は再び7バイトを切り取りました!

前:

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

@JohnEはコメントで、初期状態はハードコードされ、7バイト余分にかかることになっていると指摘しました。:/


問題の仕様を読むと、常にハードコードされた「ユニバース」から始めなければならないということです(1 0;1 1)。プログラムはこれを入力として受け入れます。
JohnE

@JohnE修正済み。ただし、変更をテストしなかったため、これが機能するという保証はありません。私はちょうどあなたの
ok

コナでもうまくいくようです。
JohnE

2

JavaScript(ES6)152

文字列を使用した関数(数字で短くする必要がありますが、javascriptではビット操作は32ビット整数に制限されます)。

以下のスニペットを使用してFirefoxでテストします。

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バイト

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

私の答えの構造は@ kirbyfan64sosの構造と非常に似ていますが、文字列の代わりに1/0ベクトルを使用:[ ; ; ]し、代わりにリストにインデックスを付けることで条件付き()の必要性を避けています。

いくつかの実行:

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

編集:

初期のユニバースを構築するためのよりコンパクトな方法で4バイトを節約しました。

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

編集2:

「選択」はリストを正しい引数として取ることができることを忘れていました。

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

そのため、この部分を簡略化できます。当然のことながら、カービィは私がやる前にこのトリックを得た。

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

1
ダン、時々私はKを知っていると思う、それからあなたの答えを見る...:O
kirbyfan64sos

このソリューションは間違いなくチームの努力としてカウントされると思います!
JohnE

1

Javascript、241 233バイト

それはちょっと長い。

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

Closure Compilerは、 8バイトを節約して圧縮しました。
グスタボロドリゲス

216バイト: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"))、3/5の時間で目的の出力を生成します。
イスマエルミゲル

217バイト: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"))、90%の時間で動作します。
イスマエルミゲル

1

T-SQL(2012 +)、1019

残念ながら、これは競争力に近いものではありませんが、正直なところ、これを機能させることができるとは思いませんでした。私はそれを少しゴルフしようとしました:)

バイナリ/整数変換を処理するには、2つのスカラー関数(513バイト)を作成する必要がありました。A整数からビット文字列になります。B逆を行います。

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

次に手順があります。 @Cはステップ数です

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 @

1万回の反復に約2分かかり、9991行を返しました

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


0

Mathematica、106バイト

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


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

ここには魔法のようなものは何もありません。tRコンソールに値を入力し、スクリプトを実行します。Rコードを「ゴルフ」することは困難ですが、より読みやすいバージョンを次に示します。

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

sample変数に割り当てることにより、多くの文字を保存できます。たとえばs=sample、サンプルではなくsを使用します。残念ながら、ランダムなビットを追加するあなたの方法はlapply、リスト内のすべてのアイテムにランダムなサンプルが追加されると思います。lapply(L,function(x)append(x,sample(0:1,1)))動作するように見えますが、コストがかかります。あなたは置き換えることができますas.numeric1*、いくつかのバックを取得する必要があります。
MickyT

両方の点で良いキャッチ、そして素晴らしい強制トリックもあります
シャドウトーカー

また、カウントが切れていることに気づきました。これ
-MickyT

0

ルビー、82

かなり簡単です。他の非ゴルフ言語と比較して、ルビーはその大きな標準ライブラリでうまくいくようです。

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

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]
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.