슈도 랜덤 셀룰러 오토 마톤


14

소개

이 도전에서, 우리는 매우 나쁜 의사 난수를 사용하여 특정 확률 적 세포 오토 마톤 을 시뮬레이션 할 것 입니다. 셀룰러 오토 마톤은 다음 로컬 규칙에 따라 이진 문자열에 정의됩니다. 셀의 왼쪽 이웃과 셀 자체에 상태 a와 가 있다고 가정합니다 b.

  • 인 경우 min(a,b) == 0새로운 상태는 b입니다 max(a,b).
  • 인 경우 min(a,b) == 1의 새로운 상태 b가에서 임의로 선택됩니다 {0,1}.

다음 그림은 하나의 가능한 10 단계 진화를 보여줍니다 1.

1
11
101
1111
11001
101011
1111111
10001001
110011011
1010111101

인접한 두 방법 주 1의는 때때로 진화 1하고, 때때로 0, 국경 가장 비트는 항상1 s입니다. 당신의 임무는이 형태의 세포 자동 진화를 생산하는 것입니다.

입력

입력은 양의 정수로 n, 표시 할 행 수와 비어 있지 않은 비트 목록을 L나타내며 무작위 소스로 사용됩니다.

산출

출력에서 하나의 진화를 묘사리스트 또는 비트의 2 차원 배열의 목록 1을 위해 n상기 도면에서와 같이, 시간 단계. 원하는 경우 출력을 0s로 채워 길이가 같은 행을 얻을 수 있지만 선행 0s 가 없어야합니다 .

셀룰러 오토 마톤의 무작위 선택은 목록 L에서 가져와야하고 소진되면 처음으로 되돌아 가야합니다. 보다 명확하게, 출력이 위에서 아래로, 왼쪽에서 오른쪽으로 한 행씩 순회하는 경우, 연속적인 무작위 선택 L은 필요한만큼 반복 하여 목록을 형성해야 합니다.

입력이 n = 7and 라고 가정합니다 L = [0,1,0]. 그런 다음 셀룰러 오토 마톤은 7 단계에서 다음과 같이 진화 v합니다.

[1]

[1,1]
   v
[1,0,1]

[1,1,1,1]
   v v v
[1,1,0,0,1]
   v
[1,1,1,0,1,1]
   v v   v
[1,0,0,1,1,1,1]

우리가 표시된 모든 비트를 읽어 보면 v, 우리가 얻을 01001001,하는 L2.66 회 반복. 다음 임의의 비트는입니다 0.

규칙과 채점

전체 프로그램 또는 함수를 작성할 수 있습니다. 가장 낮은 바이트 수가 이기고 표준 허점은 허용되지 않습니다. 입력 및 출력의 정확한 형식은 중요하지 않습니다 (이유 내에서).

테스트 사례

결정적 버전, 모든 임의의 비트는 0다음과 같습니다.

Inputs: 10 [0]
Output:
1
11
101
1111
10001
110011
1010101
11111111
100000001
1100000011

모든 임의의 비트는 1다음과 같습니다.

Inputs: 6 [1,1]
Output:
1
11
111
1111
11111
111111

의사 난수 버전 :

Inputs: 10 [0,0,1]
Output:
1
11
101
1111
10101
111111
1010011
11110101
101011111
1111101001

Inputs: 10 [1,0,0,1]
Output:
1
11
111
1001
11011
111111
1001101
11010111
111111101
1011001111

Inputs: 15 [1,1,1,0,0,0]
Output:
1
11
111
1111
10001
110011
1110111
11011001
111111011
1100011111
11100100011
111101100101
1001111101111
11011000111111
101101001011101

답변:


3

Pyth, 33 바이트

jjLk.u++1m?hSde=.<Q1sd.:N2 1tvz]1

온라인으로 사용해보십시오 : 데모 또는 테스트 스위트

설명:

jjLk.u++1m?hSde=.<Q1sd.:N2 1tvz]1  implicit: Q = input list
    .u                      tvz]1  reduce N=[1] input-1 times by applying
                      .:N2           all substrings of length 2
         m                           map each d of ^ to:
          ?hSd                         if min(d) = 0 then:
               =.<Q1                     rotate Q by one
              e                          and use the last element
                    sd                 else use sum(d) (=max(d))
      ++1                  1         add a 1 at the front and the back
                                   .u gives all intermediate results
 jLk                               join these lists to strings
j                                  print each string on a line

7

레티 나 139 바이트

^.
1

 00:0 01:1 10:1 11:
(m`^(..)((\S*)(?<=0) .*)
$1$3#$1!$2
+m`(?<=^(?<-2>.)*(..).*?#(.)*.)\d!(.)(.*\1:)(.)(\d*)
$5$3!$4$6$5
)`!0
0
 .+
<empty>

Where <empty>는 빈 줄이 끝에 있음을 나타냅니다. 각 줄은 별도의 파일에 들어가고 #줄 바꿈 (0x0A)으로 바꿔야합니다.

입력이있을 것으로 기대 n에서 단항 (같이 제로 이루어지는 단항 )은 "의사 - 랜덤"문자열 뒤에 공간이어서, 예를 10, [1, 0, 0, 1]같이 판독 될

0000000000 1001

출력은 챌린지에서와 같지만 0으로 채워집니다 (예 :

1000000000
1100000000
1110000000
1001000000
1101100000
1111110000
1001101000
1101011100
1111111010
1011001111

이것은 내가 예상했던 것보다 훨씬 까다 롭습니다 ...


3

파이썬 142 135 132 131 바이트

133 132 131 바이트 버전

f=input;n=f();L=f()*n*n;r=[1];i=1
while i<=n:print r;r=[L.pop(0)if r[x-1]&r[x]else r[x-1]+r[x]for x in range(1,i)];r=[1]+r+[1];i+=1

r[x-1]+r[x]>1의해 대체r[x-1]&r[x]비트 연산자 최소값을 산출합니다.(r[x-1],r[x])

n*n대신 제안 하는 @ThomasKwa에게 감사합니다.n**21 바이트를 절약하는 !

-1 바이트를위한 @Shebang에게 감사합니다

135 바이트 버전

f=input;n=f();L=f()*n**2;r=[1];i=1
while i<=n:print r;r=[L.pop(0)if r[x-1]+r[x]>1 else r[x-1]+r[x]for x in range(1,i)];r=[1]+r+[1];i+=1

-7 바이트에 대한 @Cole 덕분에 :

min(r[x-1],r[x])->r[x-1]+r[x]>1

max(r[x-1],r[x])->r[x-1]+r[x]

142 바이트 버전

f=input;n=f();L=f()*n**2;r=[1];i=1
while i<=n:print r;r=[L.pop(0)if min(r[x-1],r[x])else max(r[x-1],r[x])for x in range(1,i)];r=[1]+r+[1];i+=1

@Jakube의 대답에 가깝지는 않지만이 재미있는 코딩과 골프를 많이했습니다.

두 개의 입력이 필요합니다. 첫 번째 입력은 행 수 이고 두 번째 입력은 의사 난수 소스 목록입니다. 입니다. 콘솔에서 한 줄씩 하나씩 인쇄합니다. 각 줄은 새 줄로 표시됩니다.

예로서:

10 # This is input
[0] # This is input
[1] <- First output row
[1, 1]
[1, 0, 1]
[1, 1, 1, 1]
[1, 0, 0, 0, 1]
[1, 1, 0, 0, 1, 1]
[1, 0, 1, 0, 1, 0, 1]
[1, 1, 1, 1, 1, 1, 1, 1]
[1, 0, 0, 0, 0, 0, 0, 0, 1]
[1, 1, 0, 0, 0, 0, 0, 0, 1, 1]

작동 방식에 대한 간단한 설명은 다음과 같습니다.

f=input;n=f();L=f()*n*n;r=[1];i=1 First we define the input() function as f 
                                   for saving bytes as we have to call it twice.
                                   Then L is defined as a list made of the 
                                   pseudorandom numbers in their order *many* times 
                                   (were *many* is an upperbound of the canges that 
                                   could be done); r as the first row and i as the row 
                                   counter.

while i<=n:print r                 A while loop that exits when the nth row has been 
                                   calculated and the printing of the actual row.

r=[L.pop(0)if r[x-1]&r[x] else r[x-1]+r[x] for x in range(1,i)];r=[1]+r+[1];i+=1
     ^           ^                 ^                         ^
     |           |                 |Same as max(r[x-1],r[x]) | from 2nd to last element
     |           | Same as min(r[x-1],r[x]) (0->False;1->True)                
     | get random bit from pseudorandom list    

여기서 비결 1은 첫 번째 요소와 마지막 요소가 사양으로 인해 수정되지 않기 때문에 비트리스트가 항상 a로 시작하고 끝나는다는 것을 알고 있습니다. 질문의. 그것이 진술의 이유입니다 [1]+r+[1].

그러나 r로 초기화 [1]되면 첫 번째 행에 변경 사항이 없으며 [1]+r+[1]두 번째 행이 아닌 방법 을 추가 합니다 [1,1,1].

이는 첫 번째 반복에 있다는 사실이다 i=1그래서 range(1,i)의 결과로, 빈리스트를 반환하고for 를 반복 할 필요 r가 없기 때문에 빈 목록이되기 때문 [1]+r+[1]=[1,1]입니다. 이것은 우리에게 이상적인 첫 번째 반복에서 발생합니다!

추신 : 골프를 더하는 방법에 대한 제안을 자유롭게하십시오.


1
나의 사과는 내가 정확하게 문제를 이해하지 않는 경우,하지만 당신은 대체 할 수 min(a,b)a+b>1max(a,b)함께 a+b? 나는 당신이 아마의 가장 첫 번째 경우 처리하기 위해 뭔가를해야 할 것 실현 1> - 11(나는 당신이 할 수 있다고 생각 L=[1]+f()..., 또는의 앞에 1을 삽입 할 수있는 방법 찾을 L것을 항상 두 번째 라인 1을 나타 때문에)를
콜을

@Cole 운 좋게도 변경은 한 쌍의 비트의 최소값과 최대 값을 아는 방법에만 영향을주기 때문에 나머지 프로그램을 변경할 필요가 없습니다.
Ioannes

1
당신은 여기에서 공간을 제거 할 수 있다는 것을 놓쳤습니다 : r[x-1]&r[x] else:)
Kade

n ** 2-> n * n이 작동합니까?
lirtosiast

@Thomas 당신이 맞아요!
Ioannes

2

MATLAB, 146 (143) 138

(Octave 온라인에서도 작동하지만 기능을 파일로 저장하려면 로그인해야합니다).

function o=c(n,L);o=zeros(n);o(:,1)=1;for i=2:n;for j=2:i;a=o(i-1,j-1);b=o(i-1,j);c=a|b;d=a&b;c(d)=L(d);L=circshift(L,-d);o(i,j)=c;end;end

이 함수는 입력을받습니다 n 하고 L그리고 배열 반환 o출력을 포함한다.

입력 값의 경우 n 경우 스칼라입니다.L 형식으로 지정할 수있는 열 벡터입니다 [;;;]. 당신이 보여주는 것은 아니지만, 당신은 그것이 이유 내에서 융통성이 있다고 말합니다.

출력은 n x n 0과 1을 포함 배열 .

그리고 설명 :

function o=c(n,L)
%Create the initial array - an n x n square with the first column made of 1's
o=zeros(n);o(:,1)=1;
%For each row (starting with the second, as the first is done already)
for i=2:n;
    %For each column in that row, again starting with the second as the first is done
    for j=2:i;
        %Extract the current and previous elements in the row above
        a=o(i-1,j-1); %(previous)
        b=o(i-1,j);   %(current)
        %Assume that min()==0, so set c to max();
        c=a|b;
        %Now check if min()==1
        d=a&b;
        %If so, set c to L(1)
        c(d)=L(d);
        %Rotate L around only if min()==1
        L=circshift(L,-d);
        %And store c back to the output matrix
        o(i,j)=c;
    end;
end

업데이트 : if-else 문을 최적화하여 몇 바이트를 절약했습니다. 입력 형식이 다시 한 번 열 벡터로 변경되었습니다.


1

하스켈, 153 149 바이트

j[_]o l=(l,o)
j(a:u@(b:c))o q@(l:m)|a*b==0=j u(o++[a+b])q|1<2=j u(o++[l])m
k(r,a)=fmap((1:).(++[1]))$j a[]r
n%l=map snd$take n$iterate k(cycle l,[1])

%비트리스트의리스트를 돌려줍니다. 사용 예 :

> 10 % [1,0,0,1] 
[[1],[1,1],[1,1,1],[1,0,0,1],[1,1,0,1,1],[1,1,1,1,1,1],[1,0,0,1,1,0,1],[1,1,0,1,0,1,1,1],[1,1,1,1,1,1,1,0,1],[1,0,1,1,0,0,1,1,1,1]]

이런! 무작위 목록을 가지고 L다니는 것은 순수한 고통입니다. 이것이 더 짧을 수 있는지 봅시다.


1

C #, 152 바이트

여기에는 특별한 것이 없습니다. 이 함수는 첫 번째 순위가 선이고 두 번째가 열인 2D 배열을 반환합니다.

명확성을 위해 들여 쓰기 및 줄 바꿈 :

int[,]F(int n,int[]l){
    var o=new int[n,n];
    for(int y=0,x,i=0,m;y<n;y++)
        for(o[y,x=0]=1;x++<y;)
            o[y,x]=(m=o[y-1,x-1]+o[y-1,x])<2?m:l[i++%l.Length];
    return o;
}

1

TI-BASIC, 106 94 87 86 87 바이트

Prompt N,B
"∟B(1+remainder(𝑛,dim(∟B→u
{1
For(I,1,N
Disp Ans
augment({0},Ans)+augment(Ans,{0
Ans and Ans≠2+seq(u(𝑛-(Ans(X)<2)+2dim(∟B)),X,1,dim(Ans
End

TI-BASIC에는 증분 연산자가 없습니다. 글쎄요. 방정식 변수u일반적으로 시퀀스와 함께 사용되는 에는 모호한 기능이 있습니다. u인수와 함께 호출하면 변수𝑛 가 해당 인수보다 하나 크게 설정됩니다. 조건부 증분은 이것에 달려 있습니다. (오랫동안 사용하기를 기다리고있었습니다.)

목록 색인 작성이 제대로 작동하려면 𝑛기본값 0이어야합니다.𝑛Min 이어야하며 기본값 1이어야합니다. 따라서 계산기의 RAM을 지우거나이 값을 수동으로 설정하여 실행하십시오.

augment({0},Ans)+augment(Ans,{0인접한 두 요소의 합계 목록을 계산하므로 0, 1 및 2의 목록을 반환합니다. 그런 다음 마술은이 줄에 있습니다.

Ans and Ans≠2+seq(u(𝑛-(Ans(X)≠2)+dim(∟B)),X,1,dim(Ans

Ans and                 ;set 0s to 0
Ans≠                    ;set to 0 all sums that equal...
2+
  seq(...,X,1,dim(Ans   ;execute for each element of the list
      u(                ;return this element in list of bits (looping)        
        𝑛               ;current location in the list
        -(Ans(X)≠2)+    ;subtract 1 if the element isn't 2
        2dim(∟B)        ;Add twice the dimension of the list
                           ;(because n<nMin on the first iteration, it's out of the domain
                           ;this prevents an error)
       )                      ;set n to one greater than that value
                              ;i.e. increment if element≠2
                        ;Will equal Ans(X) iff Ans(X)=2 and the bit read false

이 행의 결과는 목록 요소가 0이거나 2이고 비트 읽기가 0 인 경우 목록 요소는 0입니다.

Result of above line
n \ u |  0  |  1
0        0     0

테스트 사례 :

N=?7
B=?{0,1,0
             {1}
           {1 1}
         {1 0 1}
       {1 1 1 1}
     {1 1 0 0 1}
   {1 1 1 0 1 1}
 {1 0 0 1 1 1 1}
            Done
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.