Jakie jest prawdopodobieństwo, że rycerz zostanie na szachownicy?

16

Biorąc pod uwagę rozmiar szachownicy i początkową pozycję rycerza, oblicz prawdopodobieństwo, że po kruchach rycerz znajdzie się na szachownicy.

Uwaga:

  • Rycerz wykonuje wszystkie 8 możliwych ruchów z jednakowym prawdopodobieństwem.

  • Gdy rycerz znajdzie się poza szachownicą, nie może wrócić do środka.

wprowadź opis zdjęcia tutaj

Wejście

Dane wejściowe są oddzielone przecinkami w postaci:

l,k,x,y

gdzie ljest długość i szerokość szachownicy, kliczba ruchów, które wykona rycerz, xpozycja x pozycji początkowej rycerza i ypozycja y pozycji początkowej rycerza. Zauważ, że 0,0jest to lewy dolny róg planszy i l-1,l-1prawy górny róg planszy.

Algorytm:

Zacznij od początkowych współrzędnych rycerza. Wykonaj wszystkie możliwe ruchy dla tej pozycji i pomnóż je z prawdopodobieństwem, dla każdego ruchu rekurencyjnie wywołaj funkcję kontynuuj ten proces do momentu spełnienia warunku zakończenia. Warunkiem zakończenia jest sytuacja, gdy rycerz znajduje się poza szachownicą, w tym przypadku zwróć 0 lub pożądana liczba ruchów zostanie wyczerpana, w tym przypadku zwróć 1.

Jak widzimy, aktualny stan rekurencji zależy tylko od bieżących współrzędnych i liczby wykonanych do tej pory kroków. Dlatego możemy zapamiętać te informacje w formie tabelarycznej.

Kredyt

Wyzwanie to pochodzi z postu na blogu crazyforceode.com opublikowanego na licencji CC BY-NC-ND 2.5 IN . Został nieco zmodyfikowany, aby uczynić go nieco trudniejszym.

Szczupły
źródło
14
Dlaczego przepisujesz dokładny algorytm? Nie jestem pewien, czy rzeczywiście istnieje bardziej elegancka alternatywa, ale wymaganie określonego algorytmu mogłoby potencjalnie zapobiec innym sprytnym podejściom. Nie sądzę też, byś musiał szczegółowo określać układ współrzędnych - nie ma to żadnego wpływu na prawdopodobieństwo.
Martin Ender
2
„Dane wejściowe są oddzielone przecinkami w postaci: l, k, x, y” - więc dane wejściowe to ciąg, który musimy przeanalizować? Czy nie jest dopuszczalne napisanie funkcji, która przyjmuje 4 parametry?
Cristian Lupascu
3
@Edi Nie oznaczaj odpowiedzi jako „zaakceptowanej”, jeśli inni nie mieli czasu, aby spróbować - oznaczenie czegoś jako zaakceptowanego, oznacza w zasadzie „wyzwanie zakończone” - podczas gdy większość świata prawdopodobnie nie nawet miałem czas na to spojrzeć!
Sanchises
3
@Edi Przestań publikować losowe wyzwania, które znajdziesz w sieci. Społeczność plagiatowa jest źle oceniana. Wyzwania związane z trwającymi konkursami programistycznymi nie mają tu żadnego interesu, ponieważ mogą pomóc komuś wygrać ten konkurs. Wyzwania, które są omówione w poście na blogu, takie jak to wyzwanie szachowe ( oryginalne źródło ), nie zostaną tutaj dobrze przyjęte. Jednym z powodów jest to, że oryginalne źródło może mieć jakieś prawa autorskie.
Jakube
2
@Edi Na przykład źródło tego wyzwania pozwala na kopiowanie i redystrybucję, ale tylko pod warunkiem odpowiedniego uznania.
Jakube

Odpowiedzi:

10

Pyth, 38 bajtów

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

Wypróbuj online: demonstracja

Wyjaśnienie:

                                        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
Jakube
źródło
Wydaje mi się, że jeśli zamierzamy stworzyć super-zwięzłe języki wyłącznie w celu gry w golfa, równie dobrze moglibyśmy zaimplementować wymagany algorytm jako prymitywne.
mc0e
3
@ mc0e Nie, to byłaby standardowa zabroniona luka. Zobacz tutaj .
Jakube
czy możemy dostać kod do gry w golfa?
YaSh Chaudhary
1
@YaShChaudhary Czy masz na myśli wersję z 39 bajtami, czy wersję z 40 bajtami. :-P Obawiam się, że nigdy nie istniała wersja prawdziwie nie golfowa. Napisałem ten kod bezpośrednio w Pyth, a programy w Pyth są zawsze krótkie.
Jakube,
@Jakube ohk np :)
YaSh Chaudhary
8

Ruby 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(:+)}

Wypróbuj online: http://ideone.com/ZIjOmP

Odpowiednik kodu nie golfowego:

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
Cristian Lupascu
źródło
5

Haskell - 235

Implementuje funkcję fz parametramil 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)
jhwcb
źródło
5

Matlab, 124 119

Dokładnie implementuje opisany algorytm.

Byłem w stanie skrócić go o 5 bajtów przy pomocy @sanchises, dzięki!

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(:))

Rozszerzony:

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(:))

Stara wersja

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(:));
wada
źródło
Jedna wskazówka: sjest inicjowana przez MATLAB, więc możesz to zrobić s(l,l)=0; Szkoda, że ​​MATLAB nie ma wbudowanej funkcji fibonnaci, co byłoby świetną optymalizacją m.
Sanchises
To niesamowita sztuczka, dzięki! Wciąż próbuję znaleźć krótszy sposób tworzenia mprzez rozkład macierzy ...
flawr
Tak, też przez chwilę na to patrzyłem. Być może jakieś inteligentne indeksowanie logiczne, ale nic nie mogę wymyślić. m+m'+fliplr(m+m')wydaje się być wzrostem liczby bajtów, podobnie jak wszystkie inne moje opcje.
Sanchises
5

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

Stosowanie:

g[5,5,1,2]

Wynik:

9/64
Zestawienie
źródło
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)

Poprawiono rozwiązanie @ flawr, ponieważ jest bardziej MATLAB-y.

Rozszerzony:

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)
Jared
źródło
1

> <> - 620 (nie licząc białych znaków)

Początkowy stos powinien być 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;

Przetestuj to

JNF
źródło