เครื่องทำถั่วที่มีความหมายและผอม


26

ตัวอย่างคลาสสิกที่จะแนะนำคนกับแนวคิดของการกระจายความน่าจะเป็นที่ไม่ต่อเนื่องเป็นเครื่องถั่ว เครื่องนี้มีลูกหินจำนวนมากตกลงมาจากทางเดินแคบ ๆ ที่ด้านบนหลังจากนั้นพวกเขาก็ตีพินอินเทอร์เลซเป็นแถวซึ่งในแต่ละครั้งที่หินอ่อนพุ่งชนมันอาจตกไปทางซ้ายหรือทางขวาของพิน ในที่สุดหมุดจะถูกรวบรวมในถังขยะแนวตั้งที่ด้านล่างของเครื่อง แผนภาพง่าย ๆ ของเครื่องนี้มีลักษณะดังนี้:

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

ในแผนภาพนี้Oหมายถึงตำแหน่งที่หินอ่อนตกลงมา แต่ละอัน^คือพินที่หินอ่อนมีโอกาส 50% ที่จะย้ายไปที่จตุรัสไม่ว่าจะทางซ้ายหรือทางขวาของพิน จากนั้นหินอ่อนจะรวมตัวกันที่ถังขยะที่ด้านล่างของอุปกรณ์และสำหรับหินอ่อนจำนวนมากพอความสูงของกองหินอ่อนในถังขยะจะมีลักษณะคล้ายกับการแจกแจงแบบทวินาม

ท้าทาย

สำหรับความท้าทายนี้คุณจะคำนวณการกระจายความน่าจะเป็นที่ได้รับของเครื่องทำถั่วตามแผนภาพดังกล่าวข้างต้น ไดอะแกรมถูกตีความว่าเป็น 'โปรแกรม' สองมิติที่หินอ่อนผ่านไปไม่ว่าจะทางด้านข้างหรือด้านล่างของเขตข้อมูลปัจจุบัน เมื่อลูกหินมาถึงด้านล่างของเครื่องพวกเขาจะถูกนับสำหรับการแจกแจงความน่าจะเป็น เพื่อให้มันน่าสนใจไดอะแกรมเหล่านี้จะมีฟิลด์เพิ่มเติมอีกสองสามรายการมากกว่าเพียงแค่แหล่งข้อมูลและพินที่เรียบง่าย แผนภาพตัวอย่างคือ:

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

ยิ่งไปกว่านั้นหินอ่อนในขณะนี้มีทิศทางการหมุน ทิศทางนี้ถูกกำหนดโดยบางฟิลด์และกำหนดว่าฟิลด์ใดที่หินอ่อนจะย้ายในฟิลด์อื่น ๆ

มีการกำหนดฟิลด์ต่อไปนี้:

  • O: ที่มา วางไข่หินอ่อนด้านล่างโดยตรง ทิศทางของหินอ่อนเหล่านี้คือ 50% ที่เหลือ, 50% ที่ถูกต้อง แหล่งที่มาแต่ละแห่งสร้างหินอ่อนจำนวนเท่ากัน
  • U: อ่างล้างจาน หินอ่อนใด ๆ ที่เข้าสู่ฟิลด์นี้จะถูกลบออกจากเครื่องถั่ว
  • : พื้นที่ว่าง. หากหินอ่อนมาถึงที่นี่มันจะย้ายไปที่สนามด้านล่าง
  • -: ชั้น หากหินอ่อนมาถึงที่สนามนี้มันจะย้ายไปที่สนามด้านซ้ายหรือด้านขวาโดยขึ้นอยู่กับทิศทางปัจจุบัน
  • ^: ตัวแยก หากหินอ่อนมาถึงที่สนามนี้จะมี 50% ของการเคลื่อนที่ไปที่สนามทางด้านขวาหรือด้านซ้ายของตัวแยก นอกจากนี้ยังกำหนดทิศทางของหินอ่อน
  • v: เข้าร่วม หากหินอ่อนมาถึงที่นี่มันจะย้ายไปที่สนามด้านล่าง
  • /: แผ่นเอียง หากหินอ่อนมาถึงที่สนามนี้มันจะย้ายไปที่สนามทางด้านซ้ายของแผ่นโดยกำหนดทิศทางของหินอ่อน
  • \: เหมือนกับก่อนหน้า แต่ไปทางขวา
  • |: ตัวสะท้อนแสง หากหินอ่อนมาถึงที่สนามนี้ก็จะกลับทิศทางของหินอ่อนและย้ายหินอ่อนไปที่สนามไปทางขวาหรือซ้ายตามทิศทางที่ตรงกันข้ามนี้
  • =: ปืนใหญ่ หากหินอ่อนมาถึงที่สนามนี้ก็จะย้ายไปทางขวาหรือทางซ้ายในทิศทางที่ปัจจุบันจนกระทั่งหินอ่อนพบข้อมูลที่ไม่ได้เป็น, หรือ-O
  • <: เหมือนกับก่อนหน้า แต่จะกำหนดทิศทางและเลื่อนไปทางซ้ายเสมอ
  • >: เหมือนกับก่อนหน้า แต่ไปทางขวา

รับประกันดังต่อไปนี้จะได้รับเกี่ยวกับแผนภาพ

  • แต่ละแถวอินพุตจะมีความยาวเท่ากันในฟิลด์
  • |สนามซ้ายสุดและขวาสุดของแต่ละแถวจะเป็น
  • แผนภาพจะไม่ประกอบด้วยเส้นทางที่เป็นไปได้ใด ๆ ผ่านที่หินอ่อนจะได้รับการติดอยู่ในเครื่องสำหรับจำนวนเงินที่ไม่แน่นอนของการทำซ้ำเช่นหรือ\/^^
  • แผนภาพจะมีฟิลด์ที่กล่าวถึงข้างต้นเท่านั้น
  • มีอย่างน้อยหนึ่งแหล่ง

ผล

งานของคุณคือการสร้างกราฟแท่ง ASCII สูง 16 บรรทัดของการแจกแจงความน่าจะเป็นซึ่งหินอ่อนออกจากด้านล่างของกราฟปรับสัดส่วนเพื่อให้ความน่าจะเป็นที่ใหญ่ที่สุดครอบคลุมทั้ง 16 ตัวอักษร ดังนั้นสำหรับปัญหาต่อไปนี้:

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

โปรแกรมของคุณควรสร้างโซลูชันต่อไปนี้ (โปรดทราบว่าควรมีความกว้างเท่ากับโปรแกรมอินพุตรวมถึงท่อไปทางด้านข้าง:

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

ตัวอย่าง

ต่อไปนี้เป็นตัวอย่างที่ควรทดสอบการทำงานของฟิลด์ประเภทต่าง ๆ :

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

มันควรส่งผลให้ผลลัพธ์ต่อไปนี้:

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

กฎระเบียบ

ทั้งฟังก์ชั่นและโปรแกรมเต็มรูปแบบเป็นคำตอบที่ถูกต้องสำหรับความท้าทายนี้ คุณจะได้รับแผนภาพเป็นสตริงที่คั่นด้วยการขึ้นบรรทัดใหม่และคุณควรส่งคืนกราฟเอาต์พุตในรูปแบบที่กำหนด ใช้กฎอินพุต / เอาต์พุตเริ่มต้น ในขณะที่การขึ้นบรรทัดใหม่และนำขึ้นบรรทัดใหม่ได้รับอนุญาตในเอาต์พุตแต่ละแถวควรมีความกว้างเท่ากับอินพุต

ในการอนุญาตโซลูชันที่สร้างสรรค์มากขึ้นโปรแกรมของคุณจำเป็นต้องให้ผลลัพธ์ที่ถูกต้องมากกว่า 90% ของเวลาสำหรับไดอะแกรมเดียวกัน มันเป็นการจำลองความน่าจะเป็นหลังจากทั้งหมด

เกณฑ์การให้คะแนน

นี่คือดังนั้นคะแนนต่ำสุดเป็นไบต์ชนะ


ง่ายกว่ามาก แต่เกี่ยวข้องกัน
Peter Taylor

ความคิดเห็นไม่ได้มีไว้สำหรับการอภิปรายเพิ่มเติม การสนทนานี้ได้รับการย้ายไปแชท
Dennis

ดังนั้นv= [space]?
l4m2

@ l4m2 vและ[space]แตกต่างกันว่าปืนโต้ตอบกันอย่างไร
CensoredUsername

คำตอบ:


8

Python 3 , 431 429 410 ไบต์

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

ลองออนไลน์!

คำตอบนี้เป็นความพยายามร่วมกันระหว่าง Wheat Wizard และ CensoredUsername สำหรับการอ้างอิงนี่เป็นอัลกอริทึมที่ไม่ได้รับการดัดแปลง

-2 bytes จาก Mr. Xcoder

-19 ไบต์จาก CensoredUsername


-2 bytes ถ้าคุณเปลี่ยนไปใช้ Python 2 (print statement)?
caird coinheringaahing

1
จากที่กล่าวมานี้: but I can confirm it's doable in 519 characters of python 3 code ;) I don't think I can golf mine much more- ตรวจสอบชื่อผู้ใช้
Stephen

ฉันไร้เดียงสาอย่างไร้ความหวังเมื่อฉันพูดแบบนั้น ที่กล่าวว่าการแข่งขันกอล์ฟสร้างความมั่นใจค่อนข้างสนุก นอกจากนี้ @cairdcoinheringaahing คำสั่งการพิมพ์ของ python 2 เป็นคำสั่งไม่ใช่นิพจน์และไม่สามารถใช้ในรายการความเข้าใจได้ นี่หมายความว่า oneliner ที่ด้านบนจะต้องถูกแยกออกเป็นหลายบรรทัดที่เยื้องซึ่งจะทำให้ 2 ไบต์ได้ประโยชน์จากการลบมันเป็นโมฆะ
CensoredUsername

4

Python 2 , 731 ไบต์

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

ลองออนไลน์!

ไบต์ -17 ขอบคุณขอบคุณที่หยอดเหรียญ

-12 ไบต์ขอบคุณ Nathan Shiraini

-56 ไบต์โดยสลับเป็นการผสมการเยื้อง (Python 2)

-28 ขอบคุณ CensoredUsername เนื่องจากความน่าจะเป็นปกติในตอนท้ายดังนั้นจึงไม่จำเป็นที่ความน่าจะเป็นสุดท้ายจะรวมกันเป็น 1

-7 ไบต์ต้องขอบคุณเครื่องคิดเลขแมวโดยใช้elifคำสั่งสิ้นสุดที่สั้นกว่า

-218 ไบต์โดยรวมทั้งสองฟังก์ชั่น



@cairdcoinheringaahing ใช่ไหมขอบคุณ
HyperNeutrino

2
ในการโทรถึงRและกดLชอบR(r+1-N,C+N,P,N=N)(โทรครั้งแรกถึงR) คุณไม่จำเป็นต้องวางN=สาย มันควรจะเป็นR(r+1-N,C+N,P,N)แทน
Nathan.Eilisha Shiraini

@NathanShiraini ใช่ขอบคุณ
HyperNeutrino

... คุณลืมบางอย่าง 2 บรรทัดสุดท้ายของทั้งสองLและR^^ นอกจากนี้การเยื้องระดับที่สองของคุณคือ 4 ช่องว่างทุกที่ฉันคิดว่าคุณสามารถทำได้ 2
นาธานอีลิชาชิราอิ

3

C, 569 568 556 ไบต์

แข็งแรงเล่นกอล์ฟ

#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));}

Ungolfed

//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));
}

การแก้ไข

บันทึก 12 ไบต์ด้วยการเปลี่ยนมาโครเคสของฉัน

หมายเหตุ

รหัสของฉันใช้ระบบจำนวนเต็มฐาน 3 เพื่อกำหนดว่าหินอ่อนจะมุ่งหน้าไปที่ใดและจะมุ่งหน้าไปทางใด (สำหรับปืนใหญ่และสิ่งของ)

ฉันพยายามดังนั้นจึงต้องเอาชนะโซลูชันงูหลามที่ฉันทำจริงๆ


1
ฉันนับ 568 ไบต์ คุณอาจนับการขึ้นบรรทัดใหม่หรือไม่ และฉันก็รู้สึกแย่ outgolfed ใน Python โดย C? Jeez ... : P
HyperNeutrino

คุณถูกต้องฉันทิ้ง newling ต่อท้ายในไฟล์ ขอบคุณ!
dj0wns
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.