给定棋盘上的两个不同位置和棋子类型,输出棋盘从一个位置到另一个位置所需的最小移动次数。
给出的作品可以是国王,王后,鲁克,骑士和主教。(此输入可视为任意5个唯一字符)
这两个职位可以采取任何方便的形式,
Example:
a8 b8 c8 d8 ... h8
a7 b7 c7 d7 ... h7
...
...
a1 b1 c1 d1 ... h1如果该块无法到达,则输出正整数以外的任何内容。
i/p ---- o/p
King
a1,a4 3
a1,h6 7
b3,h5 6
Queen
a1,a4 1
a1,h6 2
b3,f7 1
Rook
a1,a4 1
a1,h6 2
h2,c7 2
Knight
a1,a4 3
a1,h6 4
b2,d3 1
b2,c3 2
b3,c3 3
a1,b2 4
Bishop
a1,a4 -1
a1,h6 2
b2,d3 -1
e1,h4 1发布于 2018-11-26 16:27:14
(p,a,b,c,d)->{c^=a/4*7;a^=a/4*7;d^=b/4*7;b^=b/4*7;int x=c<a?a-c:c-a,y=d<b?b-d:d-b,z=(x^=y^(y=y<x?y:x))-y;return p<1?x:p<2?z*y<1?1:2:p<3?2-z%2:p<4?x+y<2?3:(a<c?a+b:c+d)+x<2|x==2&z<1?4:z+2*Math.ceil((y-z)/(y>z?3:4.)):z<1?1:~z*2&2;}(p,a,b,c,d)->{ // double-returning lambda.
// p is the piece-type (0: king, 1: queen, 2: rook, 3: knight, 4: bishop)
// a is the origin-X
// b is the origin-Y
// c is the destination-X
// d is the destination-Y
c^=a/4*7;a^=a/4*7; // Mirror board if origin is in the top part of the board
d^=b/4*7;b^=b/4*7; // Mirror board if origin is in the left part of the board
int x=c<a?a-c:c-a, // x is the X-distance between a and c
y=d<b?b-d:d-b, // y is the Y-distance between b and d
z=(x^=y^(y=y<x?y:x))-y; // z is the delta between x and y
// also, swap x and y if necessary so that x is the greater value.
// At this point,
// x cannot be 0 (because the two positions are different)
// z<1 means the origin and destination are on the same diagonal
// y<1 means the origin and destination are on the same horizontal/vertical line
return
p<1?x: // For a king, just take the max distance.
p<2?z*y<1?1:2: // For a queen, just move once if in direct line, or twice.
p<3?2-z%2: // For a rook, just move once if on the same horizontal or vertical line, or twice
p<4? // For a knight,
x+y<2?3: // Hardcode 3 if moving to the next horizontal/vertical square
(a<c?a+b:c+d)+x<2|x==2&z<1?4: // Hardcode 4 if moving 2 cases in diagonal or one case in diagonal in a corner.
z+2*Math.ceil((y-z)/(y>z?3:4.)): // Compute the number of moves necessary for the usual cases
z<1?1: // For a bishop, hardcode 1 if they are on the same diagonal
~z*2&2; // Return 2 if they have the same parity else 0.
}发布于 2018-11-28 16:34:58
®ra
g[_rw}_â è}@=ã ü;@pUÌïVõ á ÈíaY})Ìde[TT]}a Ä}_è}_ra v *Zâ l}]gV这是一次很棒的经历。我从优秀的APL应答中学到了很多灵感。我怀疑有很多高尔夫仍然有可能,特别是在骑士的代码。
这些位置是[[x1,x2],[y1,y2]]格式的第一个输入。它在[[y1,y2],[x1,x2]]上也应该能很好地工作。作品选择是第二个输入,有0=king,1=queen,2=knight,3=rook,4=bishop。请注意,与APL答案相比,Knight和Rook是交换的。
解释:
®ra :Turn absolute positions into relative movement and store in U
® : For each of X and Y
ra : Get the absolute difference between the start position and the end position
g[...]gV :Apply the appropriate function
[...] : A list of functions
gV : Get the one indicated by the second input
g : Apply it to U
_rw} :King function
rw : Get the maximum of X and Y
_â è} :Queen function
â : Get unique elements
è : Count non-zero elements
@=ã ü;@pUÌï2õ á ÈíaY})Ìde[TT]}a Ä} :Knight function
=ã ü; : Wrap U twice (U -> [[U]])
@ }a Ä : Repeat until True; return number of tries:
UÌ : Get the previous positions
ï : Cartesian product with:
2õ : The range [1,2]
á : All permutations, i.e. [[1,2],[2,1]]
ÈíaY}) : Apply each move to each position
p : Store the new positions
Ìde[TT] : True if any are at the destination
_è} :Rook function
è : Count non-zero elements
_ra v *Zâ l} :Bishop function
ra : Absolute difference between X and Y
v : Is divisible by 2? (returns 1 or 0)
* : Times:
Zâ : Get the unique elements
l : Count them发布于 2018-11-27 19:12:51
F…β⁸F⁸⊞υ⁺ι⊕κ≔⟦⟦η⟧⟧δW¬№§δ±¹ζ⊞δΦυΦ§δ±¹⁼⁵ΣEμX⁻℅ξ℅§κπ²≔Eη↔⁻℅ι℅§ζκε≡θKI⌈εQI∨∨¬⌊ε⁼⊟ε⊟ε²RI∨¬⌊ε²BI∧¬﹪Σε²∨⁼⊟ε⊟ε²NI⊖Lδ在网上试试!链接是详细的代码版本。解释:
F…β⁸F⁸⊞υ⁺ι⊕κ将板的所有64方格列出到预定义的空列表变量中。
≔⟦⟦η⟧⟧δ列出第一个条目是包含开始位置的列表。
W¬№§δ±¹ζ重复,直到列表的最后一个条目包含结束位置。
⊞δΦυΦ§δ±¹⁼⁵ΣEμX⁻℅ξ℅§κπ²过滤所有的董事会立场,是一个骑士的移动,远离任何条目,在名单的最后一个条目,并将该名单的列表。这包括之前访问过的职位,但我们对它们并不感兴趣,所以我们最终首先搜索了董事会的最终位置。
≔Eη↔⁻℅ι℅§ζκε计算起始位置和结束位置之间的绝对坐标差异。
≡θ根据输入部分选择。
KI⌈ε如果是国王,则打印最大绝对坐标差。
QI∨∨¬⌊ε⁼⊟ε⊟ε²如果是皇后,那就打印2,除非这两个差值相等,或者1是零。
RI∨¬⌊ε²如果它是一辆车,那就打印2,除非其中一个差是零。
BI∧¬﹪Σε²∨⁼⊟ε⊟ε²如果它是一个主教,那么打印0,如果方格是相反的平价,否则打印2,除非两个差异是相等的。
NI⊖Lδ如果是骑士,那就打印出找到末端位置所需的循环数。
https://codegolf.stackexchange.com/questions/176567
复制相似问题