Тонка, середня машина для квасолі


26

Класичний приклад ознайомлення людей з поняттям дискретного розподілу ймовірностей - машина бобових . Ця машина має велику кількість мармуру, що падає з вузького проходу вгорі, після чого вони потрапляють рядами переплетених штифтів, де на кожен штифт мармур потрапляє, він може впасти ліворуч або праворуч від штифта. Нарешті, шпильки збирають у вертикальні бункери в нижній частині машини. Проста схема цієї машини виглядає приблизно так:

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

На цій діаграмі Oозначає місце, з якого падає мармур. Кожен ^- це шпилька, на якій мармур має 50% шансу переміститися на квадрат або зліва, або справа від шпильки. Потім мармур збирається в бункерах в нижній частині пристрою, і для достатньо великої кількості мармуру висота штампів мармуру в бункерах буде нагадувати дискретний біноміальний розподіл.

Виклик

Для цього завдання ви будете обчислювати отриманий розподіл ймовірності машин для бобів на основі діаграм, подібних до вище. Діаграми трактуються як двовимірна «програма», через яку проходить мармур, або до полів збоку, або до полів нижче поточного поля. Коли мармур досягає дна машини, вони враховуються для розподілу ймовірностей. Щоб це було цікаво, ці діаграми будуть містити ще кілька полів, ніж просто просте джерело та шпильки. Приклад діаграми:

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

Крім того, кожен з мармурів має напрямок обертання. Цей напрямок задається деякими полями і визначає, до якого наступного поля мармур рухається в кількох інших полях.

Визначаються наступні поля:

  • O: Джерело. Породжує мармур прямо під ним. Напрямок цих мармурів - 50% зліва, 50% праворуч. Кожне джерело виробляє однакову кількість мармуру.
  • U: Мийка. Будь-який мармур, який потрапляє в це поле, видаляється з бобової машини.
  • : Порожній простір. Якщо мармур прибуде до цього поля, він переміститься в поле нижче.
  • -: Поверх. Якщо мармур прибуде до цього поля, він переміститься або в поле зліва, або в поле праворуч, залежно від поточного напрямку.
  • ^: Спліттер. Якщо мармур потрапляє на це поле, він має 50% переміщення в поле праворуч або поле ліворуч від спліттера. Це також визначає напрямок мармуру.
  • v: Приєднуйтесь. Якщо мармур прибуде до цього поля, він переміститься в поле нижче.
  • /: Нахилена накладка. Якщо мармур потрапить до цього поля, він переміститься до поля зліва від колодки, встановивши напрямок мармуру.
  • \: Те саме, що і попереднє, але праворуч.
  • |: Рефлектор. Якщо мармур потрапить до цього поля, він змінить напрямок мармуру і перемістить мармур в поле вправо або вліво, виходячи з цього зворотного напрямку.
  • =: Гармата. Якщо мармур потрапить до цього поля, він перемістить його вправо або вліво в поточному напрямку, поки мармур не зустріне поле, якого немає , -або O.
  • <: Те саме, що і попереднє, але завжди встановлюватиме напрямок і рухатиметься вліво.
  • >: Те саме, що і попереднє, але праворуч.

Наведені нижче гарантії щодо діаграми.

  • Кожен рядок введення матиме абсолютно однакову довжину в полях.
  • Найменше ліве і праворучне поле кожного ряду завжди буде а |.
  • Діаграма не буде містити жодних можливих шляхів, через які мармур може застрягнути в машині для невизначеної кількості ітерацій, як-от \/або ^^.
  • Діаграма містить лише вищезазначені поля.
  • Є одне або кілька джерел

Результат

Вашим завданням буде генерувати 16-рядковий високий графік ASCII розподілу ймовірностей, при якому мармур виходить з нижньої сторони графіка, масштабується так, що найбільша ймовірність охоплює всі 16 символів. Отже, для наступної проблеми:

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

Ваша програма повинна створити таке рішення (зауважте, що вона повинна мати ту саму ширину, що і вхідна програма, включаючи труби збоку:

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

Приклади

Нижче наведено приклад, який повинен перевірити функціональність усіх різних типів полів:

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

Це має призвести до такого результату:

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

Правила

Як функції, так і повні програми складають вагомі відповіді на це завдання. Ви отримаєте діаграму у вигляді рядка, розділеного рядком, і ви повинні повернути вихідний графік у заданому форматі. Застосовуються правила вводу / виводу за замовчуванням . Незважаючи на те, що у вихідному дозволеному рядку допускаються останні та нові рядки, кожен рядок повинен мати точно таку ж ширину, що і вхідний.

Що стосується більш творчих рішень, потрібно лише, щоб ваша програма виводила правильний результат більше 90% часу для тієї ж діаграми. Адже це вірогідне моделювання.

Оцінка балів

Це , тому найнижча оцінка в байтах виграє.


Набагато простіший, але пов'язаний .
Пітер Тейлор

Коментарі не для розширеного обговорення; ця розмова переміщена до чату .
Денніс

так 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 байти від містера Xcoder

-19 байт від CensoredUsername


-2 байти, якщо ви перейдете на Python 2 (друкована заява)?
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- CensoredUsername
Стівен

Я був безнадійно наївним, коли сказав це. Однак, забезпечення змагань з гольфу було дуже кумедним. Також @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 байт завдяки Натану Шираїні

-56 байт шляхом переходу на змішане відступ (Python 2)

-28 завдяки CensoredUsername, оскільки ймовірності нормалізуються в кінцевому підсумку, тому не обов'язково, щоб кінцеві ймовірності завжди дорівнювали 1.

-7 байт завдяки калькулятору Feline, використовуючи коротший закінчення 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

С, 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));}

Безумовно

//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 байт, змінивши мій макрос регістру.

Примітки

Мій код використовує систему базових цілих чисел, щоб визначити, куди прямує мармур і куди подаватиметься (для гармат та ін.).

Я намагався так перемогти це рішення пітона, я дійсно так і робив.


1
Я рахую 568 байт; можливо, ви порахували зворотний новий рядок? І чорт, мені погано; перевершив C в Python? Jeez ...: P
HyperNeutrino

Ви маєте рацію, я залишив у файлі слід нового новобранця. Спасибі!
dj0wns
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.