비트 스트링 물리학


21

배경

예, 비트 스트링 물리학은 실제입니다 . 아이디어는 확률 론적 규칙이나 다른 것 아래에서 진화하는 비트 열만 사용하여 새로운 물리 이론을 구성하는 것입니다. 그것에 관한 몇 가지 논문을 읽었음에도 불구하고 여전히 혼란 스럽습니다. 그러나 비트 스트링 유니버스는 멋진 코드 골프를 만듭니다.

프로그램 우주

비트 스트링 물리학은 소위 프로그램 세계에서 발생 합니다. 우주 진화의 각 단계 에는 두 개의 요소 목록 where로 시작하여 L길이 가 한정된 유한 한 비트 열 k목록 [10,11]k = 2있습니다. 한 단계는 다음과 같이 처리됩니다 (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

모든 무작위 선택은 균일하게 무작위이며 서로 독립적입니다.

4 단계의 진화 예는 다음과 같습니다. 초기 목록으로 시작하십시오 L.

10
11

우리는 무작위로 선택 A := 10하고 B := 10우리가 각각의 문자열을 확장 할 필요가 의미 같은 행,있는, L임의의 비트 :

101
110

다음으로,를 선택 A := 101하고 B := 110같지 않기 때문에 XOR을 L다음에 추가합니다 .

101
110
011

그런 다음 A := 011and 를 선택 하고 B := 110XOR을 다시 추가하십시오.

101
110
011
101

마지막으로 A := 101(마지막 행)과 B := 101(첫 번째 행) 을 선택 하여 임의의 비트로 확장합니다.

1010
1100
0111
1010

작업

당신의 임무는 음수가 아닌 정수 t를 입력 으로 취하고, t시간 간격을 위해 프로그램 유니버스를 시뮬레이션하고 , 결과 목록을 반환하거나 인쇄하는 것 L입니다. 참고 t = 0초기 목록에서 결과를 [10,11]. L정수 목록, 부울 값 목록 또는 문자열 목록으로 출력 할 수 있습니다 . 출력이 STDOUT으로 이동하면 비트 스트링을 한 줄에 하나씩 적당한 형식으로 인쇄 할 수도 있습니다. 비트 스트링의 순서는 중요합니다. 특히, 초기 목록이 될 수 없습니다 [11,10], [01,11]또는 같은 것을. 기능과 전체 프로그램이 모두 허용되고 표준 허점이 허용되지 않으며 가장 적은 바이트 수가 승리합니다.


비트 문자열 길이를 제한 할 수 있습니까 (즉, 32 비트 숫자와 비트 연산을 사용할 수 있습니까)?
edc65

1
@ edc65 아니요, 문자열 길이가 임의로 높아질 수 있습니다.
Zgarb

3
@ edc65 32 비트 이상을 얻는 데 필요한 시간과 메모리 요구 사항은 천문학적이지만, 우주를 시뮬레이션하고 있기 때문에 적합합니다. ;)
Zgarb 2016 년

5
비트 스트링 물리학 은 크랙 팟 아이디어입니까? 나는 전체 논문을 읽지는 않았지만 우리는 근사 물리학을 사용하여 근사 hbar c / e2 = 22-1 + 23-1 + 27-1 = 137이라는 이론을 제공했습니다. 컴퓨터 알고리즘과 정보 이론 은 나를 조금 수비 학적으로 생각합니다.
xebtl

1
@xebtl 그것은 나에게 미친 것 같습니다. 나는 어딘가에 알고리즘에 대한 정당성을 읽은 것을 기억하고 물리보다 의사 철학이 더 나쁜 것처럼 들렸다. 또한 알고리즘에 대한 설명이 내 버전과 일치하는 것 같습니다. 어쩌면 내가 당신을 오해하고있을 것입니다.
Zgarb

답변:


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 2016 년

@isaacg No xVFKxMCK동일한 바이트 수와 같습니다.
Jakube

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

언 골프 + 설명 :

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 개 문자 를 변경하는 경우 / 경우 다른 사람하고 ternay 연산자를 사용하는 대신의 경우 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 : 감사합니다. 삼항 연산자를 사용하려고 생각하지 않았습니다. 그러나 실제로는 삼항에 괄호가 필요하지 않으므로 제안보다 4를 더 절약 할 수 있습니다. 할당 AB개별 할당 은 실제로 함께 할당하는 길이와 동일하므로 해당 부분을 그대로 둡니다. 귀하의 제안에 다시 한번 감사드립니다!
Alex A.

천만에요. 아, 알겠습니다 괄호는 필요하지 않습니다.
ML

4

파이썬 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

141 회 : link
Sp3000

4

파이썬 2 127 122

다음과 같은 형식의 파이썬 비트 문자열 '0b1'이 정상 이라고 가정하십시오 .

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)

여기서 약간의 미묘한 차이 만 XOR (A, B) = 0 iff A = B라는 사실을 사용합니다.

엔 클로징 for루프 단축을위한 @ Sp300 덕분에


그러나 의견을 살펴보면 선행 제로를 보존해야
Sp3000

지금이 답변을 테스트 할 수는 없지만 선행 0을 유지하지 않으면 불행히도 잘못되었습니다.
Zgarb


2

K, 46 53 46 바이트

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

이것의 크기 (약 7 바이트)의 좋은 덩어리는 K에 xor연산자 가 없다는 것 입니다. 그래서 나는 스스로 구현해야했습니다. 원래, 나는 문자열 목록을 사용했고 그 다음은 어리석은 것을 깨달았습니다. 이제 7 바이트를 다시 차단했습니다!

전에:

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

@JohnE는 초기 상태가 하드 코딩 된 것으로 추정되는 의견에서 7 바이트 추가 비용이 들었습니다. : /


문제 사양에 대한 나의 독서는 항상 하드 코딩 된 "유니버스"로 시작해야한다는 것 (1 0;1 1)입니다. 프로그램은 이것을 입력으로 받아들입니다.
JohnE

@JohnE 고정. 그러나 변경 사항을 테스트하지 않았기 때문에 이것이 작동한다는 보장은 없습니다. 방금 당신의 oK repl에서 결말 부분을 시도했습니다 ...
kirbyfan64sos

코나에서도 잘 작동하는 것 같습니다.
JohnE

2

자바 스크립트 ( ES6 ) 152

문자열을 사용하는 함수 (숫자는 짧아야하지만 자바 스크립트 비트 연산은 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

자바 스크립트, 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 바이트를 절약했습니다.
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")), 3/5의 원하는 출력을 생성합니다.
Ismael Miguel

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 %를 작동합니다.
Ismael Miguel

1

T-SQL (2012+), 1019

나는 이것이 경쟁이 치열한 곳이 아니라는 것을 정말로 유감스럽게 생각하지만, 솔직히 말해서 이것이 작동하도록 할 수 있다고 생각하지 않았고 한 번 게시해야했습니다. 나는 그것을 약간 골프하려고했습니다 :)

이진 / 정수 변환을 처리하려면 몇 가지 스칼라 함수 (바이트 중 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 @

10,000 회 반복에 약 2 분이 걸렸으며 9991 행을 반환했습니다.

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


0

수학, 106 바이트

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

0

펄, 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"

저를 보십시오 .


0

제 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, sample 대신 s를 사용하십시오. 불행히도 난에 임의의 비트를 추가하는 방법은 lapply목록의 모든 항목에 하나의 임의 샘플이 추가되는 것으로 생각합니다. lapply(L,function(x)append(x,sample(0:1,1)))작동하지만 비용이 듭니다. 당신은 당신을 대체 할 수 있습니다as.numeric1*일부 다시 받아야합니다.
MickyT

두 지점 모두에서 잘 잡히고 강압 트릭도 좋습니다.
잡히고

또한 방금 계산이 끝났다는 것을 알았습니다. 내가 사용하여 168 수 있도록
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.