Một máy nạc, có nghĩa là


26

Một ví dụ kinh điển để giới thiệu cho mọi người khái niệm phân phối xác suất rời rạc là máy đậu . Cỗ máy này có một lượng lớn viên bi rơi từ một lối đi hẹp ở phía trên, sau đó chúng chạm vào các hàng của các chân xen kẽ, trong đó tại mỗi pin, viên bi chạm vào nó có thể rơi sang bên trái hoặc bên phải của pin. Cuối cùng, các chân được thu thập trong các thùng dọc ở dưới cùng của máy. Một sơ đồ đơn giản của máy này trông như thế này:

|     O     |
|     ^     |
|    ^ ^    |
|   ^ ^ ^   |
|  ^ ^ ^ ^  |
| ^ ^ ^ ^ ^ |
|_|_|_|_|_|_|

Trong sơ đồ này, Obiểu thị vị trí mà các viên bi rơi xuống. Mỗi cái ^là một cái ghim mà tại đó viên bi có 50% cơ hội di chuyển đến hình vuông ở bên trái hoặc bên phải của chiếc ghim. Các viên bi sau đó tập hợp tại các thùng dưới đáy thiết bị và với số lượng viên bi đủ lớn, chiều cao của các ngăn đá cẩm thạch trong các thùng sẽ giống như một phân phối nhị thức rời rạc.

Thử thách

Đối với thử thách này, bạn sẽ tính toán phân phối xác suất kết quả của máy đậu dựa trên sơ đồ như trên. Các sơ đồ được hiểu là một "chương trình" hai chiều mà các viên bi đi qua, hướng tới các trường ở bên cạnh hoặc các trường bên dưới trường hiện tại. Khi các viên bi chạm đến đáy của máy, chúng được tính để phân phối xác suất. Để giữ cho nó thú vị, các sơ đồ này sẽ chứa một vài trường hơn là chỉ các nguồn và chân đơn giản. Một sơ đồ ví dụ là:

|     O     |
|     ^     |
|    ^ /    |
|   ^ | ^   |
|  <^- =  v |
| ^ ^ ^ ^ ^ |

Hơn nữa, các viên bi bây giờ đều có hướng xoay. Hướng này được đặt bởi một số trường và xác định trường tiếp theo mà viên bi di chuyển trong một số trường khác.

Các trường sau được định nghĩa:

  • O: Nguồn. Sinh ra viên bi ngay bên dưới nó. Hướng của những viên bi này là 50% trái, 50% phải. Mỗi nguồn tạo ra cùng một lượng bi.
  • U: Bồn rửa. Bất kỳ viên bi nào vào trường này đều được gỡ bỏ khỏi máy đậu.
  • : Không gian trống. Nếu một viên bi đến trường này, nó sẽ di chuyển đến trường bên dưới.
  • -: Sàn nhà. Nếu một viên bi đến trường này, nó sẽ di chuyển sang trường bên trái hoặc trường bên phải, tùy thuộc vào hướng hiện tại của nó.
  • ^: Bộ chia. Nếu một viên bi đến trường này, nó có 50% di chuyển đến trường bên phải hoặc trường bên trái của bộ chia. Điều này cũng xác định hướng của đá cẩm thạch.
  • v: Tham gia. Nếu một viên bi đến trường này, nó sẽ di chuyển đến trường bên dưới.
  • /: Miếng đệm nghiêng. Nếu một viên bi đến trường này, nó sẽ di chuyển đến trường bên trái của miếng đệm, đặt hướng của viên bi.
  • \: Tương tự như trước, nhưng bên phải.
  • |: Phản xạ. Nếu một viên bi đến trường này, nó sẽ đảo ngược hướng của viên bi, và di chuyển viên bi sang trường bên phải hoặc bên trái, dựa trên hướng đảo ngược này.
  • =: Pháo. Nếu một viên bi đến trường này, nó sẽ di chuyển nó sang bên phải hoặc bên trái theo hướng hiện tại, cho đến khi viên bi gặp một trường không , -hoặc O.
  • <: Tương tự như trước, nhưng sẽ luôn đặt hướng và di chuyển về bên trái.
  • >: Tương tự như trước, nhưng bên phải.

Các đảm bảo sau đây được đưa ra liên quan đến sơ đồ.

  • Mỗi hàng đầu vào sẽ có cùng độ dài trong các trường.
  • Trường ngoài cùng bên phải và bên phải của mỗi hàng sẽ luôn là a |.
  • Sơ đồ sẽ không chứa bất kỳ đường dẫn có thể nào mà qua đó các viên bi có thể bị mắc kẹt trong máy với số lần lặp không xác định, như \/hoặc^^ .
  • Sơ đồ sẽ chỉ chứa các trường được đề cập ở trên.
  • Có một hoặc nhiều nguồn

Kết quả

Nhiệm vụ của bạn sẽ là tạo một biểu đồ thanh ASCII cao 16 dòng phân phối xác suất trong đó các viên bi thoát ra phía dưới cùng của biểu đồ, được chia tỷ lệ sao cho xác suất lớn nhất bao gồm tất cả 16 ký tự. Vì vậy, đối với vấn đề sau:

|     O     |
|     ^     |
|    ^ ^    |
|   ^ ^ ^   |
|  ^ ^ ^ ^  |
| ^ ^ ^ ^ ^ |

Chương trình của bạn sẽ tạo ra giải pháp sau (lưu ý rằng nó phải có cùng chiều rộng với chương trình đầu vào, bao gồm các đường ống ở bên cạnh:

     # #     
     # #     
     # #     
     # #     
     # #     
     # #     
     # #     
     # #     
   # # # #  
   # # # #  
   # # # #  
   # # # #  
   # # # #  
   # # # #  
 # # # # # #
 # # # # # # 

Ví dụ

Sau đây là một ví dụ cần kiểm tra chức năng của tất cả các loại trường khác nhau:

|     O     O         |
|  O  ^ /  <^\\\      |
|    ^ >            ^ |
|   ^ ^ ^            =|
|  ^ ^ | ^    <^   O  |
| ^ > ^ | ^   O ^> v  |
||  ^U  ^  |  =    ^\ |
|  ^ ^ ^ ^U ^\ ---^   |
| = ^   ^     =    v  |

Nó sẽ dẫn đến kết quả đầu ra sau đây:

                     # 
                     # 
                     # 
                     # 
                   # # 
                   # # 
                   # # 
       # #         # # 
       # #         # # 
       # #         # # 
       # #         # # 
      ## #         # # 
      ## # #       # # 
   # ### # #       # # 
 # # ### # #       # # 
 # # ### # #       # # 

Quy tắc

Cả hai chức năng và chương trình đầy đủ tạo thành câu trả lời hợp lệ cho thách thức này. Bạn sẽ nhận được sơ đồ dưới dạng một chuỗi phân tách dòng mới và bạn sẽ trả về biểu đồ đầu ra theo định dạng đã cho. Quy tắc đầu vào / đầu ra mặc định áp dụng. Mặc dù theo dõi và các dòng mới hàng đầu được cho phép trong đầu ra, mỗi hàng phải có cùng chiều rộng với đầu vào.

Để cho phép các giải pháp sáng tạo hơn, chỉ yêu cầu chương trình của bạn đưa ra kết quả chính xác hơn 90% thời gian cho cùng một sơ đồ. Nó là một mô phỏng xác suất sau khi tất cả.

Chấm điểm

Đây là , vì vậy điểm số thấp nhất tính bằng byte sẽ thắng.


Đơn giản hơn nhiều nhưng có liên quan .
Peter Taylor

Bình luận không dành cho thảo luận mở rộng; cuộc trò chuyện này đã được chuyển sang trò chuyện .
Dennis

vậy v= [space]?
l4m2

@ l4m2 v[space]khác nhau về cách các khẩu pháo tương tác xung quanh chúng.
Kiểm duyệt tên người dùng

Câu trả lời:


8

Python 3 , 431 429 410 byte

def t(a):e=enumerate;p=a.split("\n");o=[0]*len(p[0]);{m(i,j,p,o,1):m(i,j,p,o,-1)for i,r in e(p)for j,c in e(r)if"O"==c};[print("".join(" #"[round(16*r/max(o)+i)>15]for r in o))for i in range(16)]
def m(r,k,p,o,l,x=1):
 while r<len(p):
  c=p[r][k]
  if"^"==c:x/=2;m(r,k-l,p,o,l,x)
  if"U"==c:return
  if c in" vO":r+=1;continue
  l=[1,l,-1,l,-l,1][ord(c)%6];k-=l
  while";"<c<"?"and p[r][k]in" O-":k-=l
 o[k]+=x

Hãy thử trực tuyến!

Câu trả lời này là một nỗ lực hợp tác giữa Wheat Wizard và CensoredUsername. Để tham khảo, đây là thuật toán vô căn cứ.

-2 byte từ Mr. Xcoder

-19 byte từ CensoredUsername


-2 byte nếu bạn chuyển sang Python 2 (câu lệnh in)?
caird coinheringaahing

1
Trong số này đã được nói: but I can confirm it's doable in 519 characters of python 3 code ;) I don't think I can golf mine much more- Tên người dùng bị kiểm duyệt
Stephen

Tôi đã vô vọng ngây thơ khi tôi nói điều đó. Điều đó nói rằng, cuộc thi golf đảm bảo khá thú vị. Ngoài ra @cairdcoinheringaahing, câu lệnh in của python 2 là một câu lệnh, không phải là một biểu thức và do đó nó không thể được sử dụng trong việc hiểu danh sách. Điều này có nghĩa là oneliner ở trên cùng phải được chia thành nhiều dòng thụt vào, điều này sẽ làm cho mức tăng 2 byte từ việc loại bỏ nó.
Kiểm duyệt Tên người dùng

4

Python 2 , 731 byte

i=raw_input
l=i()
c=[]
while l:c,l=c+[l],i()
p=[[0]*len(l)for l in c]+[[0]*max(map(len,c))]
S=lambda r,C,p:r>=0and C>=0and r<len(p)and C<len(p[r])
def U(r,C,P,D,N=0):
 if S(r,C,p):p[r][C]+=P
 if S(r,C,c):
	K=c[r][C]
	if K in' O':U(r+1-N,C+D*N,P,D,N)
	elif'v'==K:U(r+1,C,P,D)
	elif'-'==K:U(r,C+D,P,D,N)
	elif'^'==K:U(r,C-1,P/2,-1);U(r,C+1,P/2,1)
	elif'/'==K:U(r,C-1,P,-1)
	elif'\\'==K:U(r,C+1,P,1)
	elif'='==K:U(r,C+D,P,D,1)
	elif'>'==K:U(r,C+1,P,1,1)
	elif'<'==K:U(r,C-1,P,-1,1)
	elif'|'==K:U(r,C-D,P,-D)
for r in range(len(c)):
 for C in range(len(c[r])):
	if'O'==c[r][C]:U(r+1,C,1.,1);U(r+1,C,1.,-1)
p=p[-1][::-1]
s=16/max(p)
f=['#'*min(int(n*s),16)+' '*min(int(16-n*s),16)for n in p]
print('\n'.join(map(''.join,zip(*f)))[::-1])

Hãy thử trực tuyến!

-17 byte nhờ caird coinheringaahing

-12 byte nhờ có Nathan Shiraini

-56 byte bằng cách chuyển sang thụt lề hỗn hợp (Python 2)

-28 cảm ơn CensoredUsername vì cuối cùng các xác suất được chuẩn hóa, do đó, không cần thiết rằng các xác suất cuối luôn luôn có tới 1.

-7 byte nhờ Máy tính Feline bằng cách sử dụng elifcâu lệnh kết thúc ngắn hơn .

-218 byte bằng cách hợp nhất hai hàm



@cairdcoinheringaahing Phải, cảm ơn.
HyperNeutrino

2
Trong các cuộc gọi đến RLthích R(r+1-N,C+N,P,N=N)(cuộc gọi đầu tiên đến R), bạn không cần N=kết thúc; nó nên được R(r+1-N,C+N,P,N)thay thế
Nathan.Eilisha Shiraini

@NathanShiraini Phải, cảm ơn.
HyperNeutrino

... bạn đã quên một số. Hai dòng cuối cùng của cả hai LR^^ Ngoài ra, mức độ thụt thứ hai của bạn là 4 khoảng trống ở mọi nơi, tôi nghĩ bạn có thể làm được 2.
Nathan.Eilisha Shiraini

3

C, 569 568 556 byte

Chơi gôn

#define A s[1]
#define c(i,j,k) break;case i:x=j;y=k;
w,S,i,j,d,x,y,z;main(int*a,char**s){w=strchr(&A[1],'|')+2-A;a=calloc(w,4);for(;i++<'~~';j=0){for(;A[j];){if(A[z=j++]==79){d=rand()%2;x=4;y=7;z+=w;for(;z<strlen(A);){z+=x%3-1+(y%3-1)*w;switch(A[z]){case 85:goto e;c(32,x/3*(3+1),y/3*(3+1))c(45,d*2+3,7)c(94,(d=rand()%2)*2+3,7)c(118,4,8)c(47,3,7)d=0;c(92,5,7)d=1;c(124,(d=!d)*2+3,7)c(60,x,y)case 62:d=A[z]/2%2;case 61:x=d*8;y=4;}}a[z%w]++;e:;}}}for(i=-1;++i<w;S=a[i]>S?a[i]:S);for(j=17;j-->1;puts(""))for(i=0;i<w-1;printf("%c",a[i++]*16./S+0.6<j?32:35));}

Bị đánh cắp

//Variable Definitions
//direction - marbles current direction, 0 -> left, 1-> right
//arrwidth - width of array
//x - change in x of marble in base 3 - 0 -> Left, 1 -> stay, 2-> right
//y - change in y of marble in base 3 - 0 -> Up, 1 -> stay, 2-> Down
//z - position of marble
//i - iterator on runs of program
//j - iterator on string
//k - iterator on outputstring
//argc - array holding all buckets

#define c(i,j,k) break;case i:x=j;y=k;

arrwidth,scale,i,j,direction,x,y,z;

main(int *argc, char**argv){
  arrwidth=strchr(&A[1],'|')+2 - A; //get width
  argc=calloc(arrwidth,4);
  for(;i++<'~~';j=0){
    for(;A[j];){
      if(A[z=j++] == 79){ //if it finds an O, start sim
        direction=rand()%2;
        x=4;
        y=7;
        z+=arrwidth;
        for(;z<strlen(A);){
          z+=x%3-1 + (y%3-1)*arrwidth;
          switch (A[z]){
            case 85://marble dies dont record
              goto e;
            c(32,x/3*(3+1),y/3*(3+1)) //case ' '
            c(45,direction*2+3,7)    //case -
            c(94,(direction=rand()%2)*2+3,7)    //case ^
            c(118,4,8)    //case v
            c(47,3,7)    //case /
              direction=0;
            c(92,5,7)   //case '\'
              direction=1;
            c(124,(direction=!direction)*2+3,7)
            c(60,x,y)    //case <
            case 62:    //case >
              direction=A[z]/2%2;
            case 61:  //case =
              x=direction*8;
              y=4;
          }
        }
        argc[z%arrwidth]++;
        e:;
      }
    }
  }
  //get output answer in terms of '#'
  for(i=-1;++i<arrwidth;scale=argc[i]>scale?argc[i]:scale);
  for(j=17;j-->1;puts(""))
    for(i=0; i < arrwidth-1;printf("%c",argc[i++]*16./scale+0.6<j?32:35));
}

Chỉnh sửa

Đã lưu 12 byte bằng cách thay đổi macro trường hợp của tôi.

Ghi chú

Mã của tôi sử dụng một hệ thống gồm 3 số nguyên cơ sở để xác định vị trí của viên bi và sẽ được dẫn đầu (đối với pháo và các thứ).

Tôi đã cố gắng để đánh bại giải pháp trăn đó, tôi thực sự đã làm.


1
Tôi đếm 568 byte; có lẽ bạn đã đếm dòng mới? Và tôi cảm thấy tồi tệ; vượt trội trong Python bởi C? Trời ...: P
HyperNeutrino

Bạn đã đúng, tôi để lại một dấu vết mới trong tập tin. cảm ơn!
dj0wns
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.