Скажи мені ходи


28

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

Ваше завдання полягає в тому, щоб допомогти знайти Джеку можливі варіанти для певного твору (крім пішака).

Якщо хтось забув, різні шматки позначаються:

  • К: Король
  • З: Королева
  • Н: Лицар
  • Б: Єпископ
  • Р: Ладья

В якості прикладу, на наступному зображенні кінь розташований на d4і може перейти до c2, b3, b5, c6, e6, f5, f3, e2. Для даного вводу:

Nd4

Ви б виробляли:

Nc2 Nb3 Nb5 Nc6 Ne6 Nf5 Nf3 Ne2

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

Правила:

  • Порядок виводу не має значення, доки перераховані всі можливі ходи
  • Можливі рухи можна розділити пробілами, новими рядками або будь-яким іншим роздільником
  • Вхід може бути переданий програмі як параметр або через STDIN
  • Пробіли в програмі повинні бути враховані, тому оптимально використовуйте її

Це код гольфу. (Будь ласка, уникайте використання будь-яких інструментів / утиліт, спеціально розроблених для цієї мети.) Найкоротший відповідь виграє!


1
Я вважаю, що це спрацювало б чудово, як кодовий гольф
Джон Дворак

3
Код гольфу - кращий вибір. Очевидне завжди забувається: я розумію, що ми можемо подати або функцію, або програму, і що введення / вихід може бути або stdin / stout, або параметрами / return value. Я думаю, що рекурсія може бути корисною для королеви: f(x)... case "Q": {f("B");f("R")}Якщо функція вимагає будь-якого #includes, вони повинні бути частиною кількості байтів.
Річка рівня Св.

4
Шрифт у цій графіці. xD
cjfaure

1
Чи потрібно розділяти пробіли можливі рухи чи також нормальні нові лінії?
Денніс

1
легальні ходи пішака більш складні, ніж будь-який інший твір (в прохідному, діагональному захопленні та 2-квадратному початковому ході). тож я припускаю, що у Джека також запам’ятовуються правила лиття?
ardnew

Відповіді:


7

GolfScript, 94 93 символи

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

Повністю гольф :

{}/8,{97+.3$-.*:>8,{49+.4$-.*:^2$+.[3<>^*4=>^=>^*!.2$|]"KNBRQ"8$?=*{[5$3$@]""+p}{;}if}/;;}/];

Прокоментував і приємніше джерело :

{}/              # tIn fIn rIn
8,{97+           #             fTst
  .3$-.*:>       #                  fDif^2 : >
  8,{49+         #                         rTst 
    .4$-.*:^     #                              rDif^2 : ^
    2$+.         #                                     ^>+
    [3<          # These    #                              [validK
     >^*4=       # checks   #                                      validN
     >^=         # do not   #                                             validB
     >^*!        # account  #                                                    validR
     .2$|]       # for null #                                                           validQ]
    "KNBRQ"8$?=  # move;    #                          valid
    *            # * does.  #                          validNotNull
    {[5$3$@]""+p}{;}if  # print? #  fDif^2
  }/;;           #        rIn
}/];

Це може виглядати як відповідь Клавдіу, тому що я посилався на його відповідь, а також на моє (неподане) рішення C, роблячи мою. Він надав хороший зразок (відносно) складної, робочої програми GolfScript, і це допомогло мені дізнатися багато про мову. Тож дякую, Клавдіу!

Будучи новинкою у GolfScript, якщо у вас є відгуки, я буду вдячний почути це!


Дивовижно! Приємна робота =). Мені доведеться пізніше придивитись до цього, щоб побачити, як у тебе на 40 символів коротше мого. Хіба Гольфскрип не веселий?
Клавдіу

12

Пітон, 217 212 220 217 213 символів

Зв'язали 213-байтне рішення Mathematica

R=range(8)
def f((p,x,y)):
 for a in R:
    for b in R:
     A,B=abs(a-ord(x)+97),abs(b-ord(y)+49);C=max(A,B);r=(A+B==3and C<3,C<2,A*B<1,A==B,0)
     if(r['NKRBQ'.index(p)],any(r[1:]))[p=='Q']*C:print p+chr(a+97)+chr(b+49)

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

>>> f("Nd4")
Nb3
Nb5
Nc2
Nc6
Ne2
Ne6
Nf3
Nf5
>>> f("Qa1")
Qa2
Qa3
Qa4
Qa5
Qa6
Qa7
Qa8
Qb1
Qb2
Qc1
Qc3
Qd1
Qd4
Qe1
Qe5
Qf1
Qf6
Qg1
Qg7
Qh1
Qh8

Приємне вилучення символів рядків за допомогою цього аргументу. Шкода, що це більше не працює в Python 3.
Evpok

10

Математика, 278 272 264 260 215 213 символів

f=(FromCharacterCode@Flatten[Table[c=Abs[#2-x];d=Abs[#3-y];b=c==d;r=#2==x||#3==y;If[Switch[#-75,0,c~Max~d<2,-9,b,7,r,6,b||r,3,!r&&c+d==3],{p,x,y},##&[]],{x,97,104},{y,49,56}]&@@ToCharacterCode@#,1]~DeleteCases~#)&

Безгольова версія:

f[pos_] := (
  {piece, u, v} = ToCharacterCode@pos;
  board = Flatten[Table[{piece, i + 96, j + 48}, {i, 8}, {j, 8}], 1];
  DeleteCases[
    FromCharacterCode[
      Cases[board, {_, x_, y_} /; Switch[p,
        75, (* K *)
        ChessboardDistance[{x, y}, {u, v}] < 2,
        66, (* B *)
        Abs[u - x] == Abs[v - y],
        82, (* R *)
        u == x || v == y,
        81, (* Q *)
        Abs[u - x] == Abs[v - y] || u == x || v == y,
        78, (* N *)
        u != x && v != y && ManhattanDistance[{x, y}, {u, v}] == 3
        ]
      ]
    ], 
    pos (* remove the input position *)
  ]
)&

Приклад використання:

f["Nd4"]
> {"Nb3", "Nb5", "Nc2", "Nc6", "Ne2", "Ne6", "Nf3", "Nf5"}

Версія без вогню створює повний пансіон, а потім вибирає правильні позиції за допомогою Cases, тоді як версія для гольфу опускає недійсні ходи негайно в Tableкоманді, видаючи ##&[], що просто зникає.


Просто цікаво про вхід, чи не так N4d? Чи не повинен бути Nd4натомість?
devnull

@devnull впевнений, це помилка друку. повинно бути Nd4.
Мартін Ендер

Навчився знаю функцію сьогодніChessboardDistance
швейцар

Згідно з документацією щодо мови Mathematica / Wolfram, "ChessboardDistance [u, v] еквівалентний Max [Abs [uv]]". Можливо, ви можете зберегти символи, скориставшись останньою формою, особливо якщо замінити Abs [uv] на | uv |.
Майкл Стерн

@MichaelStern це саме те, що я роблю у версії для гольфу;). І, на жаль, вертикальні смуги не працюють Absв Mathematica, оскільки вони позначають альтернативи в шаблоні.
Мартін Ендер

10

Haskell 225 220 208 205 200 182

f=fromEnum
m[p,a,b]=[[p,c,r]|c<-"abcdefgh",r<-"12345678",let{s=abs$f a-f c;t=abs$f b-f r;g"K"=s<2&&t<2;g"Q"=g"B"||g"R";g"N"=s+t==3&&(s-t)^2<2;g"B"=s==t;g"R"=s<1||t<1}in s+t>0&&g[p]]

Це буде важко доторкнутися до Mathematica, коли в цьому вбудовані шахові рухи: rollseyes: (добре зіграний m.buettner) Я все повертаю назад. Побиття Mathematica на 31!

Остання редакція: замінено регістр з функцією, вкладений фільтр на розуміння, щоб перемогти запис у R;)

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

ghci> m "Nd4"
["Nb3","Nb5","Nc2","Nc6","Ne2","Ne6","Nf3","Nf5"]

Ungolfed (відповідає 208 версіям char перед накресленням "u"):

f=fromEnum -- fromEnum is 'ord' but for all enum types,
           -- and it's in the prelude, so you don't need an extra import.
u piece dx dy= -- piece is the character eg 'K', dx/dy are absolute so >=0.
  dx+dy > 0 && -- the piece must move.
  case piece of
    'K'->dx<2&&dy<2         -- '<2' works because we already checked dx+dy>0
    'Q'->dx<1||dy<1||dx==dy -- rook or bishop move. see below.
    'N'->dx+dy == 3 &&      -- either 2+1 or 3+0. Exclude the other...
         (dx-dy)^2 < 2      -- 1^2 or 3^2, so valid move is '<2', ie '==1'
    'B'->dx==dy             -- if dx==dy, dx/=0 - we checked that. 
                            -- other moves with dx==dy are along diagonal
    _->dx<1||dy<1           -- use _ not 'R' to save space, default case is
                            -- the rook. '<1' saves chars over '==0'.
                            -- Again, dx==dy==0 edge case is excluded.
m[piece,file,rank]=       -- the move for a piece. 'parse' by pattern match.
 filter(                    -- filter...
  \[_,newfile,newrank]->    -- ...each possible move...
    u piece                 -- ...by, as everyone noticed, converting char..
      (abs$f file-f newfile) -- differences to absolute dx, dy differences,..
      (abs$f rank-f newrank)) -- and then using special routines per piece.
    [[piece,newfile, newrank] -- the output format requires these 3 things.
      |newfile<-"abcdefgh",newrank<-"12345678"] -- and this just generates moves.

Чи можете ви також розмістити версію, що не має волі? (якщо у вас є звичайно)
swish

@swish Я цього не роблю, але не проти цього написати.
bazzargh

@swish зроблено. Сподіваюся, що це має більше сенсу. Запитайте, чи потрібно щось уточнене.
bazzargh

Чудова робота! Чому вам потрібно додати pieceдо списку, [piece,newfile, newrank]якщо ви не використовуєте його для узгодження зразків, може зберегти вас кілька символів?
швейцарський

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

8

Баш, 238

B={19..133..19}\ {21..147..21};K=1\ {19..21};N='18 22 39 41';R={1..7}\ {2..14..2}0;Q=$B\ $R
a=${1%??};b=$[20#${1:1}-200];c=`eval{,} echo '$'$a`;d=({a..h})
for i in $c -${c// / -};do echo $a${d[$[(i+=b)/20]]}$[i%20];done|grep '[a-h][1-8]$'

Як це працює

  • Ідея полягає в тому, щоб зобразити кожне поле на дошці числовим значенням, прийнявши його координати як число-20 і віднімати 200. Таким чином, a1стає 20 * 10 + 1 - 200 = 1, h8стає 20 * 17 + 8 - 200 = 148тощо.

    Тепер можливі рухи Єпископа можуть бути представлені (позитивними чи негативними) кратними 19 - однаковою кількістю кроків вгору (+20) і ліворуч (-1) - або 21 - такою ж кількістю сходинок вгору (+20 ) і праворуч (+1).

    Розміщення фігури після руху - це просто сума її вихідної позиції та руху. Додавши ці числа, ми повинні перевірити, чи відповідає їх сума дійсному полі на дошці.

    Оскільки основа (20) більш ніж удвічі більша за максимально можливе число (8), сума не може обернутися навколо дошки, наприклад, переміщення Bh1 на сім кроків вправо і вгору призведе до недійсного положення дошки.

  • Лінія

    B={19..133..19}\ {21..147..21};K=1\ {19..21};N='18 22 39 41';R={1..7}\ {2..14..2}0;Q=$B\ $R
    

    перераховує всі можливі рухи фігур, які представлені додатними числами.

  • Команди

    a=${1%??};b=$[20#${1:1}-200];c=`eval{,} echo '$'$a`;d=({a..h})
    

    зберігає ідентифікатор елемента в змінній a , числове представлення вихідного положення в b та літери a до h у масиві d .

    Після розширення дужки eval{,} echo '$'$aстає eval eval echo '$'$a(подвійно злим), яке оцінює, наприклад, те eval echo $K, що оцінює echo 1 19 20 21.

  • for i in $c -${c// / -};do …; done петлі над усіма можливими рухами та їх негативними аналогами.

  • echo $a${d[$[(i+=b)/20]]}$[i%20] дає остаточне положення після руху.

  • grep '[a-h][1-8]$' гарантує, що ми маємо дійсне положення дошки.


7

Гольфскрипт, 144 135 символів

Замість того, щоб продовжувати пробувати моє рішення Python , я переклав його на Golfscript:

{}/49-:y;97-:x;:N;8,{.x-abs:A
8,{.y-abs:B@[\]$1=:C[B
A+3=\3<&2C>B
A*1<B
A=]81N={(;{|}*}{"NKRB"N?=}if
C*{[N
2$97+@49+]''+p}{;}if
A}/;;}/

Прямий переклад без особливого гольфу, так що його, швидше за все, можна буде вибити далі. Здійснюйте введення з stdin без нового рядка, спробуйте його тут (перші два рядки повинні імітувати stdin).


Здається, добре працює! Я сподіваюся, що хтось теж придумає рішення brainf * ck.
devnull

6

C 634 632 629 625 600 символів

#define F for(;i<4;i++){
#define B ;}break;
#define O x=X,y=Y,
P,X,Y,c,r,x,y,i=0, N[8][2]={{-2,1},{-1,2},{1,2},{2,1},{-2,-1},{-1,-2},{1,-2},{2,-1}},S[4][2]={{1,0},{0,1},{-1,0},{0,-1}},D[4][2]={{-1,1},{-1,-1},{1,1},{1,-1}};
C(){return((0<=c)&(c<8)&(0<r)&(r<9))?printf("%c%c%d ",P,c+'a',r):0;}
M(int*m){c=m[0]+x,r=m[1]+y;C()?x=c,y=r,M(m):0;}
main(int a,char**v){char*p=v[1];P=*p,X=p[1]-97,Y=p[2]-48; switch(P){case 75:F c=S[i][1]+X,r=S[i][0]+Y,C(),c=D[i][1]+X,r=D[i][0]+Y,C()B case 81:F O M(D[i]),O M(S[i])B case 78:for(;i<8;i++){c=N[i][1]+X,r=N[i][0]+Y,C()B case 66:F O M(D[i])B case 82:F O M(S[i])B}}

Будь-які пропозиції, як покращити це? Це я вперше подаю відповідь.


Ласкаво просимо в Code Golf! Для початку ви можете закреслити пробіл у коді. Пам'ятайте, що це код гольфу, який означає, що виграє найкоротший код. Тому намагайтеся зменшити розмір вашої програми.
devnull

Не забудьте також оновити кількість символів!
devnull

@devnull чи потрібні пробіли?
calccrypto

1
Ще одне: Cможна значно спростити, використовуючи потрійний оператор ?:і за допомогою зворотного значення printf. ( printfповертає кількість написаних символів, тому в цьому випадку вона завжди не дорівнює нулю.) C(P,c,r){return(0<=c)&(c<8)&(0<r)&(r<9)?printf("%c%c%d ",P,c+'a',r):0;}. Невелика редакція: Mпісля ifцього ви можете залишити додатковий простір .
користувач12205

1
Зараз ви, здається, не рахуєте жодних нових рядків. Хоча деякі з них можна видалити, інші не можуть. Обов’язкові нові рядки обов'язково повинні сприяти кількості байтів.
Денніс

3

Haskell, 300 269 ​​символів

Завдяки Базаргу за допомогу у втраті 31 символу ...

import Data.Char
f x=filter(x#)[x!!0:y|y<-[v:[w]|v<-"abcdefgh",w<-"12345678"],y/=tail x]
a%b=abs(ord a-ord b)
x#y=let{h=(x!!1)%(y!!1);v=(x!!2)%(y!!2);m=max h v;n=min h v}in case(x!!0)of{'N'->m==2&&n==1;'K'->m==1;'B'->h==v;'R'->n==0;'Q'->('R':tail x)#y||('B':tail x)#y}

Той самий алгоритм, що і версія Mathematica. Вибірка з ghci:

*Main> f "Nd4"
["Nb3","Nb5","Nc2","Nc6","Ne2","Ne6","Nf3","Nf5"]
*Main> f "Ni9"
["Ng8","Nh7"]

(Ви не просили перевірити обгрунтованість!)


Можна позбутися синтаксичного пробілу. Дивіться мою відповідь тут: codegolf.stackexchange.com/questions/19255/… (щоб бути більш конкретним, ви хочете, щоб {h = d (x !! 1) (y !! 1); ...})
bazzargh

1

Haskell, 446 символів

import Data.Char
a=[-2,-1,1,2]
b=[-1,1]
d=[1..8]
e=[-8..8]
g=[-1..1]
h 'N' c r=[(c+x,r+y)|x<-a,y<-a,3==(sum$map abs[x, y])]
h 'B' c r=[(c+x*z,r+y*z)|x<-b,y<-b,z<-d]
h 'R' c r=[(c+x,r)|x<-e]++[(c,r+y)|y<-e]
h 'Q' c r=h 'B' c r++h 'R' c r
h 'K' c r=[(c+x,r+y)|x<-g,y<-g]
l s=ord s-96
m n=chr$n+96
k ch (c,r)=ch:m c:[intToDigit r]
f (x,y)=all(`elem`[1..8])[x, y]
i n c r=map(k n).filter(/=(c,r)).filter f$h n c r
j s=i(s!!0)(l$s!!1)(digitToInt$s!!2)

Викликається за допомогою jфункції

j "Nd4"

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


1

q & k [ 311 262 символів]

Є можливість зменшити ще кілька символів. Я буду зменшувати його в наступній ітерації.

k)o:{n:#m:&(#x)##y;((),x)[m],'n#y}

k)a:`$"c"$(o/)c:+(97;49)+/:!8

k)r:{{|x@<x}'?,/{o[x]y}'[x](|"c"$c)}
k)k:{"c"$(6h$x)+/:(o/)2 3#-1 0 1}
k)n:{"c"$(6h$x)+/:(|:'t),t:o[-1 1;2 2]}
k)b:{"c"$(6h$x)+/:(n,'n),n,'|n:-8+!17}
k)q:{,/(r;b)@\:x}

d:{(`$("rknbq"!(r;k;n;b;q))[x]y)except`$y}
g:{a inter d[x 0]@1_x}

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

Ладья

g"ra1"
`a2`a3`a4`a5`a6`a7`a8`b1`c1`d1`e1`f1`g1`h1

Король

g"ka1"
`a2`b1`b2

Лицар

g"na1"
`b3`c2

Єпископ

g"ba1"
`b2`c3`d4`e5`f6`g7`h8

Королева

g"qa1"
`a2`a3`a4`a5`a6`a7`a8`b1`b2`c1`c3`d1`d4`e1`e5`f1`f6`g1`g7`h1`h8

0

R, 203 символів

f=function(p,x,y){x=which((l=letters)==x);X=rep(1:8,8);Y=rep(1:8,rep(8,8));A=abs(X-x);L=abs(Y-y);B=A==L;R=!A|!L;i=switch(p,N=A+L==3&A&L,R=R,B=B,Q=R|B,K=(R|B)&A<2&L<2)&A+L>0;paste(p,l[X[i]],Y[i],sep="")}

Безгольова версія:

f = function(p,x,y) {
  x = which(letters == x)  # Gives index between 1 and 8.
  X = rep(1:8, 8)          # 1,2,...,7,8,1,2,.... (8x8).
  Y = rep(1:8, rep(8,8))   # 1,1,...2,2,.....,8,8 (8x8).
  dx = abs(X-x)
  dy = abs(Y-y)
  B = (dx == dy)           # Bishop solutions
  R = (!dx | !dy)          # Rock solutions
  i = switch(p,
             N=dx+dy==3 & dx & dx,  # Sum of dist. is 3, dx and dy must be <> 0.
             R=R, 
             B=B, 
             Q=R|B,                 # Queen is merge of rock and bishop.
             K=(R|B) & dx<2 & dy<2  # King's distance is < 2.
             ) & (dx+dy > 0)        # Exclude start field.

  paste(p, letters[X[i]], Y[i], sep="")
}

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

> f('N', 'a', 3)
[1] "Nb1" "Nc2" "Nc4" "Nb5"

Рішення навіть добре читається. Однак я додав кілька круглих дужок та коментарів для читачів, незнайомих з кодом R (для версії, що не використовується для лідерів).


0

Хаскелл (гіпотетичний), 248 символів

import Data.Char
f x=filter(o x)[x!!0:y|y<-[v:[w]|v<-"abcdefgh",w<-"12345678"],y/=tail x]
d a b=abs(ord a-ord b)
h x y=(c*(d(x!!1)(y!!1))-(d(x!!2)(y!!2)))+200*c
 where c=d (x!!0)'A'
o x y=elem(chr(h x y))"ਲ਼ੁߏߚߙÈേെ൅ൄൃ൙൪ൻඌඝථ඿౿౾౽౼౻౺౹ಐಏಠಞರಭೀ಼೐ೋೠ೚೰೩"

На жаль, кожен компілятор Haskell, з яким я зараз можу отримати свої проблеми, має проблеми з літеральними рядками Unicode. Ось (довша) версія, яка насправді працює:

import Data.Char
f x=filter(o x)[x!!0:y|y<-[v:[w]|v<-"abcdefgh",w<-"12345678"],y/=tail x]
d a b=abs(ord a-ord b)
h x y=(c*(d(x!!1)(y!!1))-(d(x!!2)(y!!2)))+200*c
 where c=d (x!!0)'A'
o x y=elem(chr(h x y))"\2611\2625\1999\2010\2009\200\3399\3398\3397\3396\3395\3394\3393\3417\3434\3451\3468\3485\3502\3519\3199\3198\3197\3196\3195\3194\3193\3216\3215\3232\3230\3248\3245\3264\3260\3280\3275\3296\3290\3312\3305"

Визначення h x y=...- хеш-функція; дійсні переміщення будуть хешувати символьні числа, що знаходяться в рядку 41 символу. Це позбавляється від необхідності заяви "випадку" або його еквівалента.

Зараз я не планую більше працювати над цим. Було б весело побачити, чи може хтось використовувати хеш-функцію більш лаконічною мовою, щоб зробити коротше рішення.

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