Pseudorandom Cellular Automaton


14

Giới thiệu

Trong thử thách này, chúng tôi sẽ mô phỏng một máy tự động di động xác suất nhất định bằng cách sử dụng số giả ngẫu nhiên rất xấu. Máy tự động di động được xác định trên chuỗi nhị phân theo quy tắc cục bộ sau. Giả sử rằng hàng xóm bên trái của một tế bào và chính tế bào đó có trạng thái ab.

  • Nếu min(a,b) == 0, sau đó trạng thái mới bmax(a,b).
  • Nếu min(a,b) == 1, sau đó trạng thái mới bđược chọn ngẫu nhiên từ {0,1}.

Hình ảnh sau đây cho thấy một sự tiến hóa 10 bước có thể của một lần duy nhất 1.

1
11
101
1111
11001
101011
1111111
10001001
110011011
1010111101

Lưu ý cách hai 1s liền kề đôi khi tiến hóa 1và đôi khi đến 0và hầu hết các bit luôn luôn 1là s. Nhiệm vụ của bạn là tạo ra một sự tiến hóa tự động di động của hình thức này.

Đầu vào

Đầu vào của bạn là một số nguyên dương n, biểu thị số lượng hàng cần hiển thị và danh sách các bit không trống L, mà chúng tôi sử dụng làm nguồn ngẫu nhiên.

Đầu ra

Đầu ra của bạn là một danh sách liệt kê hoặc mảng 2D bit, miêu tả sự phát triển của một đơn 1cho nbước thời gian, như trong hình trên. Bạn có thể đệm đầu ra với 0s để có được các hàng có độ dài bằng nhau, nếu muốn, nhưng không được có 0s dẫn .

Các lựa chọn ngẫu nhiên trong thiết bị tự động di động phải được rút ra từ danh sách L, nhảy trở lại từ đầu khi nó cạn kiệt. Rõ ràng hơn, nếu đầu ra đi qua một hàng tại một thời điểm từ trên xuống dưới, từ trái sang phải, thì các lựa chọn ngẫu nhiên liên tiếp sẽ tạo thành danh sách Llặp đi lặp lại nhiều lần nếu cần.

Thí dụ

Giả sử các đầu vào là n = 7L = [0,1,0]. Sau đó, thiết bị tự động di động phát triển như sau trong 7 bước, trong đó chúng tôi đã đặt một vquyền trên mỗi lựa chọn ngẫu nhiên:

[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]

Nếu chúng ta đọc tất cả các bit được đánh dấu bằng a v, chúng ta sẽ nhận 01001001được Llặp lại 2,66 lần. Các bit ngẫu nhiên tiếp theo sẽ là 0.

Quy tắc và chấm điểm

Bạn có thể viết một chương trình đầy đủ hoặc một chức năng. Số byte thấp nhất sẽ thắng và các sơ hở tiêu chuẩn không được phép. Định dạng chính xác của đầu vào và đầu ra là không quan trọng (trong lý do).

Các trường hợp thử nghiệm

Phiên bản xác định, mỗi bit ngẫu nhiên là 0:

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

Mỗi bit ngẫu nhiên là 1:

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

Phiên bản giả danh:

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

Câu trả lời:


3

Bình thường, 33 byte

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

Dùng thử trực tuyến: Trình diễn hoặc Test Suite

Giải trình:

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

Võng mạc , 139 byte

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

Trường hợp <empty>chỉ ra rằng có một dòng trống. Mỗi dòng đi trong một tệp riêng biệt và #nên được thay thế bằng nguồn cấp dữ liệu (0x0A).

Yêu cầu đầu vào nở dạng đơn nguyên (được tạo từ số 0, như trong Unary ), theo sau là khoảng trắng , theo sau là chuỗi "giả ngẫu nhiên", ví dụ: 10, [1, 0, 0, 1]sẽ được đọc là

0000000000 1001

Đầu ra giống như trong thử thách, nhưng được đệm bằng số không, vd

1000000000
1100000000
1110000000
1001000000
1101100000
1111110000
1001101000
1101011100
1111111010
1011001111

Đây là cách khó khăn hơn tôi mong đợi ...


3

Python, 142 135 132 131 byte

Phiên bản 133 132 131 byte

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

được thay thế r[x-1]+r[x]>1bằng r[x-1]&r[x]toán tử bitwise & mang lại giá trị tối thiểu trong(r[x-1],r[x])

Cảm ơn @ThomasKwa đã đề xuất n*nthay vì n**2tiết kiệm 1 byte!

Cảm ơn @Shebang cho byte -1

Phiên bản 135 byte

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

Cảm ơn @Cole cho -7 byte:

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

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

Phiên bản 142 byte

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

Thậm chí không gần với câu trả lời của @ Jakube nhưng tôi đã có rất nhiều niềm vui khi viết mã và chơi gôn này.

Yêu cầu hai đầu vào: đầu vào đầu tiên là số lượng hàng và đầu vào thứ hai là danh sách nguồn giả ngẫu nhiên . Nó in trên bàn điều khiển hết hàng này đến hàng khác, mỗi dòng trên một dòng mới.

Ví dụ:

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]

Bây giờ cho một lời giải thích ngắn về cách nó hoạt động:

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    

Mẹo ở đây là chúng ta biết rằng danh sách bit sẽ luôn bắt đầu và kết thúc bằng một 1vì các phần tử đầu tiên và cuối cùng không bao giờ được sửa đổi do thông số kỹ thuật. của câu hỏi Đó là lý do cho tuyên bố [1]+r+[1].

Nhưng nếu rđược khởi tạo là [1], không có thay đổi nào ở hàng đầu tiên và sau đó chúng tôi thêm [1]+r+[1]làm thế nào đến hàng thứ hai không [1,1,1]?

Đây là do thực tế rằng trên phiên đầu tiên i=1để range(1,i)trở về một danh sách trống, và như một kết quả của sự fortrong danh sách hiểu có gì để lặp qua rtrở thành một danh sách trống nên [1]+r+[1]=[1,1]. Điều này chỉ xảy ra ở lần lặp đầu tiên rất lý tưởng cho chúng ta!

Tái bút: Hãy thoải mái đưa ra bất kỳ đề xuất nào về cách chơi gôn nhiều hơn.


1
Tôi xin lỗi nếu tôi không hiểu chính xác thử thách, nhưng bạn không thể thay thế min(a,b)bằng a+b>1max(a,b)bằng a+b? Tôi nhận ra rằng bạn có thể phải làm gì đó để xử lý trường hợp đầu tiên của 1-> 11(Tôi nghĩ bạn có thể làm L=[1]+f()...hoặc tìm cách nào đó để chèn 1 vào trước Lvì điều đó sẽ luôn bật 1 cho dòng thứ hai)
cole

@Cole May mắn thay, không có thay đổi nào được thực hiện cho phần còn lại của chương trình vì những thay đổi chỉ ảnh hưởng đến cách nhận biết giá trị tối thiểu và tối đa của một cặp bit.
Ioannes

1
Bạn đã bỏ lỡ rằng bạn có thể xóa một khoảng trắng ở đây: r[x-1]&r[x] else:)
Kade

N ** 2 -> n * n có hoạt động không?
lirtosiast

@Thomas Bạn nói đúng!
Ioannes

2

MATLAB, 146 143 138

(Cũng hoạt động trên Octave trực tuyến, nhưng bạn cần đăng nhập để lưu chức năng trong một tệp).

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

Hàm lấy một đầu vào nL, và trả về một mảng ochứa đầu ra.

Đối với các giá trị đầu vào, n là một vô hướng và Llà một vectơ cột, có thể được chỉ định trong định dạng [;;;]. Không hoàn toàn những gì bạn thể hiện, nhưng bạn nói nó linh hoạt trong lý do và điều này có vẻ như vậy.

Đầu ra được định dạng là một n x nmảng chứa 0 và 1.

Và một lời giải thích:

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

Cập nhật: Tôi đã quản lý để tối ưu hóa câu lệnh if-other để lưu một vài byte. Định dạng đầu vào đã một lần nữa thay đổi trở lại vectơ cột.


1

Haskell, 153 149 byte

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

%trả về một danh sách các danh sách bit. Ví dụ sử dụng:

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

Trời ơi! Mang theo danh sách ngẫu nhiên Lxung quanh là nỗi đau thuần túy. Hãy xem nếu điều này có thể ngắn hơn.


1

C #, 152 byte

Không có gì đặc biệt ở đây. Hàm trả về một mảng 2D trong đó thứ hạng đầu tiên là dòng và thứ hai là cột.

Dòng thụt lề và mới cho rõ ràng:

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 byte

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 không có toán tử gia tăng, phải không? Vâng, nó là loại không. Biến phương trình u, thường được sử dụng với các chuỗi, có một tính năng tối nghĩa: khi uđược gọi với một đối số, biến𝑛 được đặt thành một lớn hơn đối số đó. Sự gia tăng có điều kiện phụ thuộc vào điều này. (Tôi đã chờ đợi để sử dụng nó trong một thời gian dài.)

Để lập chỉ mục danh sách hoạt động chính xác, 𝑛phải là giá trị mặc định là 0 và 𝑛Minphải là mặc định 1, vì vậy hãy xóa RAM máy tính của bạn hoặc đặt các giá trị đó theo cách thủ công trước khi chạy.

augment({0},Ans)+augment(Ans,{0tính toán một danh sách các tổng của hai phần tử liền kề, vì vậy nó sẽ trả về một danh sách 0, 1 và 2. Sau đó, phép thuật là trên dòng này:

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

Kết quả của dòng này sẽ là các phần tử danh sách là 0 nếu chúng là 0 hoặc nếu chúng là 2 và bit đọc là 0.

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

Trường hợp thử nghiệm:

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
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.