움직임을 말해줘


28

Jack과 Jane은 시간이 지날 때까지 체스 게임을하기로 결정했습니다. 불행히도 Jack은 시각화에 다소 나쁩니다. 그는 물론 폰 이외의 특정 조각에 대해 가능한 움직임을 파악하기가 어렵다는 것을 알게되었습니다!

당신의 도전은 Jack이 주어진 부분 (폰이 아닌)에 가능한 옵션을 찾는 것을 돕는 것입니다.

하나를 잊어 버린 경우 다양한 조각이 다음과 같이 표시됩니다.

  • 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
나는 이것이 코드 골프처럼 잘 작동한다고 믿는다
John Dvorak

3
코드 골프가 더 나은 선택입니다. 함수 나 프로그램을 제출할 수 있고 입력 / 출력이 stdin / stout 또는 매개 변수 / 반환 값일 수 있음을 알고 있습니다. 나는 여왕에게 재귀가 유용 할 것이라고 생각 f(x)... case "Q": {f("B");f("R")}합니다. 함수가 #include를 요구하면 이것들은 바이트 수의 일부 여야합니다.
Level River St

4
해당 그래픽의 글꼴 xD
cjfaure

1
가능한 이동이 공백으로 분리되어야합니까, 아니면 개행 문자도 괜찮습니까?
Dennis

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

Claudiu의 답변처럼 보일 수 있습니다. 왜냐하면 그의 답변과 (제출되지 않은) C 솔루션을 참조하면서 내 것을 만들었 기 때문입니다. 그는 (상대적으로) 복잡하고 작동하는 GolfScript 프로그램의 훌륭한 표본을 제공했으며 언어에 대해 많은 것을 배우는 데 도움이되었습니다. 감사합니다, Claudiu!

GolfScript를 처음 사용하는 동안 의견이 있으시면 들려주세요.


대박! 좋은 일 =). 나는 당신이 내 것보다 40 문자가 짧은 것을 알기 위해 나중에 그것을 더 자세히 살펴볼 것입니다. Golfscript가 재미 있지 않습니까?
Claudiu

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

이 인수 튜플을 사용하여 문자열 문자를 추출하는 것이 좋습니다. 파이썬 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"}

ungolfed 버전은 전체 보드를 생성하고로 정확한 위치를 선택 Cases하는 반면, golfed 버전 Table은을 발행 하여 명령 에서 즉시 유효하지 않은 동작을 삭제 ##&[]합니다.


입력에 대해 궁금한 N4d가요? Nd4대신 해서는 안 됩니까?
devnull

@devnull은 오타입니다. 이어야합니다 Nd4.
Martin Ender

오늘 ChessboardDistance
알려진

Mathematica / Wolfram 언어 문서에 따르면, "ChessboardDistance [u, v]는 Max [Abs [uv]]와 같습니다." 특히 Abs [uv]를 | uv |로 바꾸는 경우 후자를 사용하여 문자를 저장할 수 있습니다.
Michael Stern

@MichaelStern 그것이 정확히 골프 버전에서하는 일입니다.). 불행히도 AbsMathematica에서는 세로 막대가 작동하지 않습니다 . 왜냐하면 패턴의 대안을 나타 내기 때문입니다.
Martin Ender

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를 다루기가 어려울 것입니다. : 롤시 : (잘 연주 했습니다. 매스 매 티카를 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.

ungolfed 버전도 게시 할 수 있습니까? (당신은 물론 한 경우)

@swish 나는하지 않지만 그것을 쓰는 것은 마음에 들지 않습니다.
bazzargh

@swish 완료. 더 이해하기를 바랍니다. 분명한 것이 필요한지 물어보십시오.
bazzargh

잘 했어! 패턴 일치에 사용하지 않는 경우 왜 piece목록에 추가해야 [piece,newfile, newrank]합니까? 일부 문자를 저장할 수 있습니까?
Swish

출력을 위해 존재합니다. '... 각각의 이동 ...'에서 패턴 패턴이 일치하지 않는 것을 볼 수 있습니다. 원래 나는 이것을 가지고 있지 않았습니다-체스 움직임에는 필요하지 않습니다. 그러나 질문이 그것을 원한다는 것을 알았고 다른 모든 사람들이 그것을 했으므로 공평합니다.
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

    이제 주교의 가능한 움직임은 같은 양의 스텝 업 (+20)과 왼쪽 (-1) 또는 21 – 같은 스텝 업 (+20)의 19의 (양수 또는 음수) 배수로 나타낼 수 있습니다. ) 및 오른쪽 (+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

골프 스크립트, 144 135 자

파이썬 솔루션 을 계속 골프화 하는 대신 골프 스크립트로 번역했습니다.

{}/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쓴 문자 수를 반환하므로이 경우 항상 0이 아닙니다.) 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
지금은 줄 바꿈을 계산하지 않는 것 같습니다. 하지만 일부 중 제거 할 수 있고, 다른 사람은 할 수 없습니다. 필수 줄 바꿈은 바이트 수에 확실히 기여해야합니다.
Dennis

3

하스켈, 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"]

(위생 검사를 요구하지 않았습니다!)


구문 공백을 제거 할 수 있습니다. 내 대답을 here 참조하십시오 : 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

하스켈 (가설), 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 컴파일러에는 유니 코드 문자열 리터럴에 문제가 있습니다. 실제로 작동하는 (더 긴) 버전은 다음과 같습니다.

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.