告诉我动作


28

杰克和简决定在下班前下棋。不幸的是,杰克很不擅长可视化。他发现很难找到除了典当之外的给定部件可能的移动!

您的挑战是帮助杰克找到给定棋子(典当除外)的可能选项。

万一忘记了,各个部分用以下符号表示:

  • K:国王
  • 问:女王
  • N:骑士
  • B:主教
  • R:白嘴鸦

作为一个例子,下面的图像中的奈特位于d4和能够移动到c2,b3,b5,c6,e6,f5,f3,e2。对于给定的输入:

Nd4

您将产生:

Nc2 Nb3 Nb5 Nc6 Ne6 Nf5 Nf3 Ne2

在此处输入图片说明

规则:

  • 只要列出了所有可能的动作,输出的顺序就无关紧要
  • 可能的动作可以用空格,换行符或任何其他定界符分隔
  • 输入可以作为参数传递给程序,也可以通过 STDIN
  • 程序中的空格应计算在内,因此请充分利用它

这是代码高尔夫。(请避免使用专门为此目的设计的任何工具/实用程序。)答案最短者为准!


1
我相信这会工作得很好作为代码高尔夫
— 约翰·德沃夏克

3
代码高尔夫球是更好的选择。显而易见的事情总是被遗忘:我知道我们可以提交函数或程序,并且输入/输出可以是stdin / stout或参数/返回值。我认为递归对于女王来说可能有用:f(x)... case "Q": {f("B");f("R")}如果函数需要任何#include,则这些应该是字节数的一部分。
— 级圣河

4
该图形中的字体。xD
— cjfaure 2014年

1
可能的动作必须用空格隔开还是换行符也可以吗?
— 丹尼斯

1
典当的合法举动比其他任何棋子都要复杂(被动,对角线捕捉和2平方的初始举动)。所以我认为杰克还记住了训练规则吗?
— ardnew

Answers:


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
}/];

可能看起来像Claudiu的答案,这是因为在制作我的产品时,我引用了他的答案以及我(未提交的)C解决方案。他提供了一个(相对)复杂,有效的GolfScript程序的很好的样本,它帮助我学习了很多有关该语言的知识。所以,谢谢克劳迪!

仍然是GolfScript的新手,如果您有任何反馈意见,我将不胜感激!


太棒了!做得好=)。稍后,我将不得不更仔细地研究它,以了解您比我的短40个字符。Golfscript不好玩吗?
— Claudiu 2014年

12

Python中,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 2014年

@devnull肯定是错字。应该是Nd4。
— Martin Ender 2014年

今天学会了一种已知的功能ChessboardDistance
— 2014年

根据Mathematica / Wolfram语言文档,“ ChessboardDistance [u,v]等效于Max [Abs [uv]]”。也许可以使用后一种形式保存字符,尤其是如果将| Abs [uv]替换为| uv |。
— 2014年

@MichaelStern正是我在高尔夫版本中所做的;)。不幸的是,竖线Abs在Mathematica中不起作用,因为竖线表示模式中的替代项。
— Martin Ender 2014年

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击败Mathematica!

最新编辑:用函数替换大小写,将过滤器内联到理解中,以击败R;)

用法:

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

Ungolfed(对应于内联'u'之前的208 char版本):

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.

您也可以发布非高尔夫版本吗?(如果您有课程的话)
— 2014年

@swish我不知道,但我不介意写下来。
— bazzargh 2014年

@swish完成了。希望这更有意义。询问是否需要澄清。
— bazzargh 2014年

做得好!如果不将其用于模式匹配,为什么需要添加piece到列表[piece,newfile, newrank],可以节省一些字符?
— 2013年

它在那里输出。您会在“ ...可能的动作...”中看到我没有在其上进行图案匹配。最初我没有这个功能-棋步不需要它-但后来我注意到这个问题想要它,而其他所有人都这样做了,所以这很公平。
— bazzargh 2014年

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向右或向上移动7步将导致板位置无效。

  • 线

    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

Golfscript,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}/;;}/

无需打高尔夫球即可直接进行平移,因此很可能会被进一步淘汰。从标准输入中获取输入而没有换行符,请在此处尝试(第一行是模仿标准输入)。


似乎运作良好!我希望有人也能提出脑力激荡的解决方案。
— devnull 2014年

6

Ç 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 2014年

记住也要更新字符数!
— devnull 2014年

@devnull是否计算必要的空格?
— calccrypto 2014年

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;}。A小调编辑:有一个额外的空间M后if,你可以删除。
— user12205 2014年

1
目前,您似乎没有在计算任何换行符。尽管其中一些可以删除,但其他不能删除。必需的换行符肯定会增加字节数。
— 丹尼斯2014年

3

Haskell,300 269个字符

感谢bazzargh帮助我们解决了丢失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 [ 311262个字符]

有可能减少更多字符。我将在下一个迭代中减少它。

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

Haskell(假设),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个字符的字符串中的字符编号。这消除了对“ case”语句或等效语句的需要。

我现在不打算在此方面做进一步的工作。看看是否有人可以使用更简洁的语言中的哈希函数来缩短解决方案的时间会很有趣。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.