Bir yağsız, ortalama fasulye makinesi


26

İnsanlara ayrık bir olasılık dağılımı kavramını tanıtmanın klasik bir örneği, fasulye makinesidir . Bu makinenin üstündeki dar bir geçitten düşen büyük miktarda mermer vardır, ardından her bir pimde mermer vuruşlarının pimin soluna veya sağına düşebileceği, pimli sıralara çarptıkları görülmektedir. Son olarak, pimler makinenin altındaki dikey kutularda toplanmaktadır. Bu makinenin basit bir şeması şöyle görünür:

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

Bu şemada, Omermerlerin düştüğü yeri gösterir. Her biri ^, mermerin pimin soluna veya sağına kareye gitme şansının% 50 olduğu bir pimdir. Daha sonra, mermerler, cihazın altındaki kutularda toplanır ve yeterince büyük sayıda mermer için, kutulardaki mermer yığınlarının yüksekliği, ayrı bir binom dağılımına benzer.

Meydan okuma

Bu zorluk için, yukarıdaki gibi diyagramlara göre fasulye makinelerinin sonuçta ortaya çıkan olasılık dağılımını hesaplayacaksınız. Diyagramlar, mermerlerin yandaki alanlara veya mevcut alanın altındaki alanlara doğru geçtiği iki boyutlu bir 'program' olarak yorumlanır. Mermerler makinenin dibine ulaştığında, olasılık dağılımı için sayılır. İlginç olması için, bu diyagramlar sadece basit kaynak ve pimlerden daha fazla alan içerecektir. Örnek bir şema:

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

Ayrıca, şimdi her bir mermerin dönme yönü vardır. Bu yön, bazı alanlar tarafından belirlenir ve mermerin başka hangi alanlarda başka hangi alanda hareket edeceğini belirler.

Aşağıdaki alanlar tanımlanmıştır:

  • O: Kaynak. Doğrudan altındaki mermerleri yumurtlar. Bu mermerlerin yönü% 50 sol,% 50 sağdır. Her kaynak aynı miktarda mermer üretir.
  • U: Lavabo. Bu alana giren tüm mermerler, fasülye makinesinden çıkarılır.
  • : Boş alan. Bu alana bir mermer gelirse, aşağıdaki alana geçecektir.
  • -: Kat. Bu alana bir mermer gelirse, geçerli yönüne bağlı olarak sola veya sağdaki alana hareket edecektir.
  • ^: Ayırıcı. Bu alana bir mermer gelirse, sağa ya da ayırıcının solundaki alana doğru hareket edenlerin% 50'sine sahiptir. Bu aynı zamanda mermerin yönünü de belirler.
  • v: Katılmak. Bu alana bir mermer gelirse, aşağıdaki alana geçecektir.
  • /: Eğimli ped. Bu alana bir mermer gelirse, pedin solundaki alana hareket ederek mermerin yönünü belirleyecektir.
  • \: Önceki ile aynı, ancak sağa.
  • |: Reflektör. Bu alana bir mermer gelirse, mermerin yönünü tersine çevirir ve bu ters yöne göre mermeri sağa veya sola doğru hareket ettirir.
  • =: Cannon. Mermer bu alanda ulaşır, bu mermer olmayan bir alanı saptadığı kadar geçerli yönde soldan sağa veya taşımak olacaktır , -ya da O.
  • <: Bir öncekiyle aynı, ancak daima yönü ayarlayıp sola doğru hareket edecektir.
  • >: Önceki ile aynı, ancak sağa.

Şema için aşağıdaki garantiler verilmiştir.

  • Her giriş satırının alanlarla tam olarak aynı uzunluğu olacaktır.
  • Her satırın en sol ve en sağdaki alanı her zaman a olacaktır |.
  • Diyagram, \/veya gibi belirsiz miktarda tekrarlama için mermerlerin makineye sıkışabileceği olası yolları içermeyecektir ^^.
  • Diyagram sadece yukarıda belirtilen alanları içerecektir.
  • Bir veya daha fazla kaynak var

Sonuç

Göreviniz, mermerlerin grafiğin alt kısmından çıktığı olasılık dağılımının 16 satırlık bir ASCII çubuk grafiğini oluşturmak olacak ve ölçeklendirilerek en büyük olasılık tüm 16 karakteri kapsayacak. Yani aşağıdaki problem için:

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

Programınız aşağıdaki çözümü üretmelidir (taraftaki borular da dahil olmak üzere girdi programla aynı genişliğe sahip olması gerektiğini unutmayın:

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

Örnekler

Aşağıdaki, tüm farklı alan türlerinin işlevselliğini test etmesi gereken bir örnek:

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

Aşağıdaki çıktıya yol açmalıdır:

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

kurallar

Hem işlevler hem de tam programlar bu zorluk için geçerli cevaplar oluşturmaktadır. Diyagramı yeni satırlarla ayrılmış bir dize olarak alırsınız ve çıktı grafiğini verilen biçimde döndürmeniz gerekir. Varsayılan giriş / çıkış kuralları geçerlidir. Çıktıda izleyen ve önde gelen yeni satırlara izin verilirken, her satır girişle tam olarak aynı genişliğe sahip olmalıdır.

Daha yaratıcı çözümlere izin vermek için, yalnızca programınızın aynı diyagram için zamanın% 90'ından fazlasını doğru sonuç vermesi gerekir. Sonuçta bir olasılık simülasyonu.

puanlama

Bu , yani bayt cinsinden en düşük puan kazanır.


Çok daha basit ama ilgili .
Peter Taylor

Yorumlar uzun tartışmalar için değildir; bu konuşma sohbete taşındı .
Dennis

yani v= [space]?
l4m2

@ L4m2 vve [space]topların etraflarında nasıl etkileşimde bulundukları konusunda farklılıklar gösterir.
Sansürlü Kullanıcı

Yanıtlar:


8

Python 3 , 431 429 410 bayt

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

Çevrimiçi deneyin!

Bu cevap, Wheat Wizard ve CensoredUsername arasındaki ortak bir çabadır. Başvuru için, bu asılsız algoritmadır.

Bay Xcoder'dan -2 bayt

-Sansız Kullanıcı Adı'ndan 19 bayt


Python 2'ye geçerseniz -2 bayt (print cümlesi)?
caird coinheringaahing

1
Bunun söylendi: but I can confirm it's doable in 519 characters of python 3 code ;) I don't think I can golf mine much more- Sansürlü Kullanıcı
Stephen,

Bunu söylediğimde umutsuzca saftım. Bu, golf rekabeti sağlanması oldukça eğlenceli olduğunu belirtti. Ayrıca @cairdcoinheringaahing, python 2'nin print ifadesi bir ifadedir, bir ifade değildir ve bu nedenle bir liste kavramada kullanılamaz. Bu, en üstteki onelinerin 2 baytlık boşluğu kaldırmasını sağlayacak şekilde girintili birkaç satıra bölünmesi gerektiği anlamına gelir.
Sansürlü Kullanıcı Adı

4

Python 2 , 731 bayt

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

Çevrimiçi deneyin!

Caird coinheringaahing sayesinde -17 bayt

Nathan Shiraini sayesinde -12 bayt

Karışık girintiye geçerek -56 bayt (Python 2)

-28 Sansürlü Kullanıcı Adı sayesinde, olasılıklar sonunda normalize edilmiş olduğundan, dolayısıyla olasılıkların her zaman 1'e yükselmesi gerekli değildir.

-7 bayt Hesap Makinesi Feline sayesinde daha kısa bir bitiş elififadesi kullanarak .

İki işlevi birleştirerek -218 bayt



@cairdcoinheringaahing Doğru, teşekkürler.
HyperNeutrino,

2
RVe Lbenzeri çağrılar R(r+1-N,C+N,P,N=N)(ilk çağrı R), N=sonunda; bunun R(r+1-N,C+N,P,N)yerine olmalı .
Nathan.Eilisha Shiraini

@ NathanShiraini Doğru, teşekkürler.
HyperNeutrino

... biraz unuttun. Her ikisinin de son 2 satırı Lve R^^ Ayrıca, ikinci girinti seviyeniz her yerde 4
boşluktur, sanırım

3

C, 569 568 556 Bayt

golfed

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

Düzenlemeler

Benim vaka makro değiştirerek 12 bayt kurtardı.

notlar

Kodum, mermerin nereye yönlendiğini ve bundan sonra nereye (toplar ve eşyalar için) gidileceğini belirlemek için bir taban 3 tamsayı sistemi kullanıyor.

Bu yüzden o python çözümünü yenmek zorunda kaldım, gerçekten yaptım.


1
568 bayt sayıyorum; belki takip eden yeni hattı saydın? Ve kahretsin, kendimi kötü hissediyorum; Python'da C tarafından aşıldı mı? Tanrım ...: P
HyperNeutrino

Haklısın, dosyada takip eden bir yeniyi bıraktım. Teşekkürler!
dj0wns
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.