Яка ймовірність того, що лицар залишається на шаховій дошці?


16

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

Примітка:

  • Рицар робить усі 8 можливих рухів з однаковою ймовірністю.

  • Як тільки лицар знаходиться поза шаховою дошкою, він не може повернутися всередину.

введіть тут опис зображення

Вхідні дані

Введення розділяються комами у формі:

l,k,x,y

де lдовжина та ширина шахової дошки k- це кількість рухів, які зробить лицар, xє х-положення початкової позиції лицаря та yє y-положення початкового положення лицаря. Зауважте, що 0,0це лівий нижній кут дошки та l-1,l-1є верхній правий кут дошки.

Алгоритм:

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

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

Кредит

Цей виклик походить із публікації в блозі crazyforcode.com, опублікованої під ліцензією CC BY-NC-ND 2.5 IN . Він був трохи змінений, щоб зробити його трохи складніше.


14
Чому ви призначаєте точний алгоритм? Я не впевнений, чи є насправді більш елегантна альтернатива, але вимагаючи конкретного алгоритму, потенційно може завадити інші розумні підходи. Крім того, я не думаю, що вам потрібно настільки детально вказувати систему координат - це зовсім не впливає на ймовірність.
Мартін Ендер

2
"Введення розділені комами у формі: l, k, x, y" - значить, вхід - це рядок, який ми маємо проаналізувати? Чи не прийнятно писати функцію, яка приймає 4 параметри?
Крістіан Лупаску,

3
@Edi Не позначайте відповідь як "прийняту", якщо не було часу, щоб інші люди спробували це - позначити щось прийнятим, так в основному говорять "Проблема закінчена" - хоча більшість країн світу, мабуть, не навіть встиг поглянути на це!
Санчіз

3
@Edi Будь ласка, перестаньте публікувати випадкові виклики в Інтернеті. Плагіат нахмуриться нашою громадою. Проблеми, що виникають на змаганнях з програмування, тут взагалі не мають жодної справи, оскільки вони можуть допомогти комусь виграти цей конкурс. І чи проблеми, які обговорюються в публікації в блозі, як цей шаховий виклик ( оригінальне джерело ), тут не будуть сприйняті добре. Однією з причин є те, що первісне джерело може мати якесь авторське право.
Якубе

2
@Edi Наприклад, джерело цього виклику дозволяє копіювати та перерозподіляти, але тільки якщо ви надаєте відповідний кредит.
Якубе

Відповіді:


10

Pyth, 38 байт

M?smcgtGd8fq5sm^-Fk2C,TH^UhQ2G1g@Q1>Q2

Спробуйте в Інтернеті: Демонстрація

Пояснення:

                                        implicit: Q = evaluated input
M                                       define a function g(G,H): //G=depth, H=current cell
                         UhQ              the list [0,1,...,Q[0]-1]
                        ^   2             Cartesian product, gives all cells
          f                               filter for numbers numbers T, which satisfy:
                    C,TH                    zip(T,H)
              m                             map the two pairs k to:
                -Fk                           their difference
               ^   2                          squared
             s                              sum (distance squared)
           q5                               == 5           
   m                                      map each valid cell d to:
     gtHd                                   g(G-1,d)
    c    8                                  divided by 8
  s                                       return sum
 ?                           G          if G > 0 else
                              1           return 1

                               g@Q1>Q2  call g(Q[1],Q[2:]) and print

Мені здається, що якщо ми збираємось створювати надто стислі мови з єдиною метою гольфу, ми можемо також застосувати необхідний алгоритм як примітив.
mc0e

3
@ mc0e Ні, це була б стандартна заборонена лазівка. Дивіться тут .
Якубе

чи можемо ми отримати не-гольф код pls?
YaSh Chaudhary

1
@YaShChaudhary Ви маєте на увазі версію з 39 байтами або версію з 40 байтами. :-П Боюсь, ніколи не існувало справді не гольф-версії. Я написав цей код прямо в Pyth, і програми Pyth завжди короткі.
Якубе

@Jakube ohk np :)
YaSh Chaudhary

8

Рубін 134

->l,m,x,y{!((r=0...l)===x&&r===y)?0:m<1?1:(0..7).map{|i|a,b=[1,2].rotate i[2]
P[l,m-1,x+a*(i[0]*2-1),y+b*(i[1]*2-1)]/8.0}.inject(:+)}

Спробуйте в Інтернеті: http://ideone.com/ZIjOmP

Еквівалентний код без гольфу:

def probability_to_stay_on_board(board_size, move_count, x, y)
  range = 0...board_size
  return 0 unless range===x && range===y
  return 1 if move_count < 1

  possible_new_locations = (0..7).map do |i|
    dx, dy = [1,2].rotate i[2]
    dx *= i[0]*2-1
    dy *= i[1]*2-1

    [x+dx, y+dy]
  end

  possible_new_locations.map do |new_x, new_y| 
    probability_to_stay_on_board(board_size, move_count-1, new_x, new_y) / 8.0 
  end.inject :+
end

5

Хаскелл - 235

Реалізує функцію fз параметрамиl k x y

import Data.List
g[]=[]
g((a,b):r)=[(a+c,b+d)|(c,d)<-zip[-2,-1,1,2,-2,-1,1,2][1,2,-2,-1,-1,-2,2,1]]++g r
h _ 0 a=a
h l a b=h l(a-1)$filter(\(a,b)->(elem a[0..l])&&(elem b[0..l]))$g b
f l k x y=(sum$map(\x->1.0) (h l k [(x,y)]))/(8**k)

5

Матлаб, 124 119

Точно реалізується описаний алгоритм.

Мені вдалося скоротити його на 5 байт за допомогою @sanchises, дякую!

function s=c(l,k,x,y);m=zeros(5);m([2,4,10,20])=1/8;s(l,l)=0;s(l-y,x+1)=1;for i=1:k;s=conv2(s,m+m','s');end;s=sum(s(:))

Розширено:

function s=c(l,k,x,y);
    m=zeros(5);
    m([2,4,10,20])=1/8;
    s(l,l)=0;s(l-y,x+1)=1;
    for i=1:k;
        s=conv2(s,m+m','s');
    end;
    s=sum(s(:))

Стара версія

function s=c(l,k,x,y);
    m =zeros(5);m([1:3,5,8,10:12]*2)=1/8;
    s=zeros(l);
    s(l-y,x+1)=1;
    for i=1:k
        s=conv2(s,m,'s');
    end
    s=sum(s(:));

Один натяк: sініціалізується MATLAB, так що ви можете просто зробити s(l,l)=0; Шкода, що MATLAB не має фібоначок як вбудованої функції, це було б чудовою оптимізацією m.
Санчіз

Це супер дивовижний трюк, дякую! Я все ще намагаюся знайти коротший спосіб створення mза допомогою матричного розкладання ...
flawr

Так, я на це теж дивився деякий час. Можливо, якась розумна логічна індексація, але я нічого не можу придумати. m+m'+fliplr(m+m')Здається, збільшення кількості рахунків, як і всі інші мої варіанти.
Санчіз

5

Математика - 137

q = # {1, 2} & /@ Tuples[{-1, 1}, 2]
q = Reverse /@ q~Union~q
g[l_, k_, x_, y_] :=

 Which[
  k < 1,
  1,

  !0 <= x < l || ! 0 <= y < l,
  0,

  0<1,
  Mean[g[l, k - 1, x + #[[1]], y + #[[2]]] & /@ q]
]

Використання:

g[5,5,1,2]

Вихід:

9/64

2

MATLAB - 106

function s=c(l,k,x,y);m(5,5)=0;m([2,4,10,20])=1/8;s=ones(l);for i=1:k;s=conv2(s,m+m','s');end;s=s(l-y,x+1)

Вдосконалює рішення @ flawr, будучи більш MATLAB-y.

Розширено:

function s=c(l,k,x,y)
    m(5,5)=0;
    m([2,4,10,20])=1/8;
    s=ones(l);
    for i=1:k
        s=conv2(s,m+m','s');
    end
    s=s(l-y,x+1)

1

> <> - 620 (без урахування пробілів)

Початковий стек повинен бути l,k,x,y

{:a2*0p   v
vp0*3a*}:{<
>{1+&a3*0g}v                   >          >       >          >~~01-01-v             >          >       >          >~~01-01-v             >          >       >          >~~01-01-v             >          >       >          >~~01-01-v
           >&1-:&?!v>:@@:@@:0(?^:a2*0g1-)?^2-$:0(?^:a2*0g1-)?^1-      >}}$:@@:@@:0(?^:a2*0g1-)?^2-$:0(?^:a2*0g1-)?^1+      >}}$:@@:@@:0(?^:a2*0g1-)?^2+$:0(?^:a2*0g1-)?^1-      >}}$:@@:@@:0(?^:a2*0g1-)?^2+$:0(?^:a2*0g1-)?^1+      >}}$:@@:@v
v1         ^}       ^!?=g0*3a:~~}}<      +2v?)-1g0*2a:v?(0:$+1v?)-1g0*2a:v?(0:@@:@@:$}}<      -2v?)-1g0*2a:v?(0:$+1v?)-1g0*2a:v?(0:@@:@@:$}}<      +2v?)-1g0*2a:v?(0:$-1v?)-1g0*2a:v?(0:@@:@@:$}}<-2      v?)-1g0*2a:v?(0:$-1v?)-1g0*2a:v?(0:@<
>a3*0g=   ?^\      &              ^-10-10~~<          <       <          <             ^-10-10~~<          <       <          <             ^-10-10~~<          <       <          <             ^-10-10~~<          <       <          <
\         :{/      
v                  >~{~l2,&0
>@:0(?v:a2*0g1-)?v$:0(?v:a2*0g1-)?v1>@~~+l1=?v
      >          >     >          >0^        >&,n;

Перевірте це

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