動きを教えて


28

ジャックとジェーンは、時間を空けてチェスをすることにしました。残念ながら、ジャックは視覚化がかなり苦手です。もちろん、ポーン以外の特定の駒で可能な動きを把握するのは難しいと思います!

あなたの挑戦は、ジャックが特定のピース(ポーン以外)の可能なオプションを見つけるのを助けることです。

忘れてしまった場合、さまざまな部分は次のように示されます。

  • K:キング
  • Q:クイーン
  • N:ナイト
  • B:ビショップ
  • R:ルーク

一例として、次の画像にナイトに位置しているd4とに移動することができc2、b3、b5、c6、e6、f5、f3、e2。与えられた入力に対して:

Nd4

あなたが生成します:

Nc2 Nb3 Nb5 Nc6 Ne6 Nf5 Nf3 Ne2

ここに画像の説明を入力してください

ルール:

  • すべての可能な動きがリストされている限り、出力の順序は関係ありません
  • 可能な移動は、空白、改行、またはその他の区切り文字で区切ることができます
  • 入力は、パラメータとして、または経由でプログラムに渡すことができます STDIN
  • プログラム内の空白はカウントされるので、それを最適に使用してください

これはコードゴルフです。(その目的のために特別に設計されたツール/ユーティリティを使用しないでください。)最短の答えが勝ちです!


1
これはコードゴルフとしてうまく機能すると思います
— ジョンドヴォルザーク14年

3
コードゴルフがより良い選択です。明らかなことは常に忘れられています。関数またはプログラムのいずれかを送信できること、および入出力がstdin / stoutまたはparameters / return valueのいずれかであることを理解しています。ここでは、女王にとって再帰が役立つと考えています。f(x)... case "Q": {f("B");f("R")}関数が#includeを必要とする場合、これらはバイトカウントの一部である必要があります。
— レベルリバーセント14年

4
そのグラフィックのフォント。xD
— cjfaure 14年

1
考えられる移動はスペースで区切る必要がありますか、それとも改行も問題ありませんか?
— デニス14年

1
ポーンの合法的な動きは、他のどの部分よりも複雑です(パッサント、対角線キャプチャ、および2正方形の初期移動)。だから、ジャックにはキャスティングルールも記憶されていると思いますか?
— ardnew 14年

回答:


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は楽しくありませんか?
— クラウディ14

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

Mathematicaの、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 |に置き換える場合は、後者の形式を使用して文字を保存できます。
— マイケルスターン14

@MichaelSternそれはまさにゴルフバージョンでやっていることです;)。残念ながらAbs、Mathematicaでは垂直バーは機能しません。これは、垂直バーがパターン内の代替を示すためです。
— マーティンエンダー14

10

ハスケル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(「u」がインライン化される前の208文字バージョンに対応):

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 14年

@swish私はそうしませんが、それを書くことを気にしません。
— bazzargh

@swish done。もっと理にかなっていることを願っています。明確化する必要があるかどうかを尋ねます。
— bazzargh

よくやった!パターンマッチングで使用しない場合piece、リストに追加する必要があるのはなぜ[piece,newfile, newrank]ですか?
— スウィッシュ

出力用にあります。「... each each move ...」でパターンマッチングを行わないことがわかります。もともと私はこれを持っていませんでした-チェスの動きはそれを必要としません-しかし、その後、私は質問がそれを望んでいることに気づき、他のみんながそれをやったので、それは公正です。
— バザーグ14年

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)の2倍を超えるため、合計はボードを囲むことができません。たとえば、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と文字に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}/;;}/

あまりゴルフをしない簡単な翻訳なので、さらに削ることができます。改行なしでstdinから入力を取得し、ここで試してください(最初の2行は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}}

これを改善する方法に関する提案はありますか?回答を提出するのは初めてです。


コードゴルフへようこそ!まず、コード内の空白を削除できます。これはコードゴルフであり、最短のコードが勝つことを意味します。したがって、プログラムのサイズを小さくしてください。
— devnull

文字数も忘れずに更新してください!
— devnull

@devnullは必要なスペースがカウントされますか?
— calccrypto

1
もう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削除できる余分なスペースがあります。
— user12205

1
今、あなたは改行を数えていないようです。一方で、いくつかのそれらのを除去することができる、他の人がすることはできません。必要な改行は、バイトカウントに確実に寄与するはずです。
— デニス14年

3

Haskell、300 269文字

31文字を失うのを助けてくれたbazzarghに感謝します...

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/…(より具体的には、let {h = d(x !! 1)(y !! 1); ...})
— bazzargh

1

ハスケル、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

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」ステートメントまたは同等のものの必要性がなくなります。

私は今これについてさらに作業するつもりはありません。誰かがより簡潔な言語でハッシュ関数を使用して、より短いソリューションを作成できるかどうかを確認するのは楽しいでしょう。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.