棋盘迷宫


14

棋子(国王,皇后,新人,主教和骑士)和棋子在板上,但不在a1h8广场上。您的任务是从空的a1到空的h8正方形,仅通过空正方形。行动规则如下:

  1. 您可以从任何空白方块继续到其旁边的空白方块(相同等级,下一个或上一个文件;或相同文件,下一个或上一个文件)。
  2. 您可以从任何一个空方块到对角线旁边的任何一个空方块(下一个或上一个等级,下一个或上一个文件),条件是每斤角方块包含(a)两个棋子或(b)相反的棋子/棋子颜色。(两个颜色相同的非典当棋子,或一个非典当棋子与典当棋子的强度足以阻止您过弯,但两个典当棋子都不行;相反颜色的棋子/棋子在例如,如果您在c4上并且d5为空,则可以继续进行下去,前提是c5d4包含典当或包含相反颜色的棋子/棋子。有关图片,请参见下面的“对角线示例”部分。

输入值

FEN的板说明。即:输入将是一个字符串,其中包含等级8的描述,斜杠(/),等级7的描述,斜杠…和等级1的描述。每个等级的描述都包含数字和字母,从文件a到文件h,其中字母表示棋子和棋子(黑色的棋子是p= pawn,n= knight,b= bishop,r= rook,q= queen,k= king和白色1是相同的大写形式),数字表示连续的空方块数。例如,rnbqkbnr/pppppppp/8/8/4P3/8/PPPP1PPP/RNBQKBN移动一层后的木板(国王的棋子到e4)在国际象棋游戏中。

输入中a1h8为空;即,第一个斜杠前面有一个数字,最后一个斜杠后面有一个数字。

输出量

真假,表明是否有可能成功传递到h8

如果输入不是有效的FEN板描述(即与我上面的解释相符的描述),或者如果a1h8被占用,则输出可以是任何东西或什么都不是。(换句话说:您可以假设输入满足以上要求。)

计分

这就是代码高尔夫:最少的字节数获胜。

输入和输出示例

请注意,您的代码必须适用于所有有效输入,而不仅仅是示例。

w在每个FEN之后添加一个空格和一个以使其可视化http://www.dhtmlgoodies.com/scripts/chess-fen/chess-fen-3.html。(请注意,其他一些在线FEN可视化工具不允许使用棋类中非法的棋盘,例如,棋子的等级为18,因此不能用于我们的目的。)

真实的例子

  • 8/8/8/8/8/8/8/8 —空板
  • 1p1Q4/2p1Q3/2p1Q3/2p1Q3/2p1Q3/2p1Q3/Q1p1Q3/1q3q2—有一条路径a1b2b3b4b5b6b7c8d7,(不是 e8,但被遮挡了)d6d5d4 d3d2d1e1f2f3f4f5f6f7f8g8h8
  • 8/8/KKKKK3/K3K3/K1K1p3/Kp1K4/K1KK4/2KK4 —一个示例,其中稍后必须通过在某个点被遮挡的正方形(以确保您不会将正方形设置为不可通过)
  • K1k1K1K1/1K1k1K1k/K1K1k1K1/1k1K1K1k/K1k1K1k1/1K1k1k1K/K1K1k1K1/1k1k1K1k—只有一条路可以走(只要顺着鼻子走:每一步只有一个正方形,除非向后走一步);这也是一个正方形在某个点被阻塞但稍后需要的示例

虚假的例子

  • 6Q1/5N2/4Q3/3N4/2Q5/1N6/2Q5/1N6 —任何尝试在路径上的操作都必须穿过两个对角线放置的相同颜色的片段
  • N1q1K1P1/1R1b1p1n/r1B1B1Q1/1p1Q1p1b/B1P1R1N1/1B1P1Q1R/k1k1K1q1/1K1R1P1r-穿过a8-h1对角线的唯一方法是在f2-g3处,但这将需要穿过e1-d2f2-e3,这都是不可能的。
  • 4Q3/4q3/4Q3/5Q2/6Q1/3QqP2/2Q5/1Q6
  • 4q3/4Q3/4q3/5q2/6q1/3qQp2/2q5/1q6

对角线示例

如果上面的散文不清楚,这里有一些图片。

可通过对角线

相同颜色的棋子 相反颜色的棋子 颜色相反的车

不可逾越的对角线

相同颜色的车子和棋子 相同颜色的车


对不起,我不确定标准高尔夫球规则:如果插入非法的String会发生什么情况?会发生任何行为吗?
亚历克斯·伯恩,2016年

@alexberne我相信这涵盖了它:“您的代码必须对所有有效输入都有效 ”。
Rainbolt

@alexberne,我已编辑。现在清楚了吗?
msh210 '16

是啊谢谢。我是新来的,所以这可能对高尔夫球手来说很普通,但对我来说尚不清楚:)
Alex berne

只是想对@ msh210这个伟大的难题表示感谢。我不明白为什么没有更多答案。
乔芬

Answers:


6

VBA 668 666 633 622 548 510 489 435 331 322 319 315字节

Function Z(F):Dim X(7,7):While Q<64:R=R+1:V=Asc(Mid(F,R))-48:If V>9 Then X(Q\8,Q Mod 8)=(3+(V\8=V/8))*Sgn(48-V):V=1
Q=Q-V*(V>0):Wend:X(7,0)=1:For W=0 To 2E3:Q=W Mod 8:P=W\8 Mod 8:For T=Q+(Q>0) To Q-(Q<7):For S=P+(P>0) To P-(P<7):If X(S,T)=0 Then X(S,T)=(1=X(P,Q))*(6>X(P,T)*X(S,Q))
Next S,T,W:Z=X(0,7):End Function

读取输入字符串最多占用“ Wend”。很好的副作用-板[X]完全编码后,它会放弃输入字符串,因此您可以在最后留下描述。

在棋盘编码中,棋子为2,其他棋子为3,黑色为负。典当通过字符代码被8整除的'P'和'p'识别。

设置检查为a1的 'X(7,0)= 1' 是路径检查的起点。这将反复扫描电路板,以尝试从到目前为止标记为可访问(1)的正方形中添加可访问正方形。对角访问和占用情况在IF +逻辑计算中进行了检查,该运算符曾经存在于函数中,但现在位于嵌套的邻居循环中。对角线检查取决于两个小猫咪角方块的乘积,如果块具有相同的颜色并且至少一个是棋子而不是棋子,则该乘积仅等于或大于6。

呼叫电子表格;返回X(0,7)中的值-如果h8可访问,则返回1;否则,则返回0-Excel 将该值识别为“真/假”。= IF(Z(C2),“是”,“否”)

在此处输入图片说明

上面我可能不喜欢压缩代码,所以这里是一个半未注释的注释版本:

Function MazeAssess(F)  'input string F (FEN)
Dim X(7, 7)             'size/clear the board; also, implicitly, Q = 0: R = 0
'Interpret string for 8 rows of chessboard
While Q < 64
    R = R + 1           ' next char
    V = Asc(Mid(F, R)) - 48  ' adjust so numerals are correct
    If V > 9 Then X(Q \ 8, Q Mod 8) = (3 + (V \ 8 = V / 8)) * Sgn(48 - V): V = 1 ' get piece type (2/3) and colour (+/-); set for single column step
    Q = Q - V * (V > 0) ' increment column (unless slash)
Wend
'Evaluate maze
X(7, 0) = 1             ' a1 is accessible
For W = 0 To 2000       ' 1920 = 30 passes x 8 rows x 8 columns, golfed to 2E3
    Q = W Mod 8         ' extracting column
    P = W \ 8 Mod 8     ' extracting row
    For T = Q + (Q > 0) To Q - (Q < 7)     ' loop on nearby columns Q-1 to Q+1 with edge awareness
        For S = P + (P > 0) To P - (P < 7) ' loop on nearby rows (as above)
            If X(S, T) = 0 Then X(S, T) = (1 = X(P, Q)) * (6 > X(P, T) * X(S, Q)) ' approve nearby empty squares if current square approved and access is possible
        Next 'S
    Next 'T
Next 'W
MazeAssess = X(0, 7)    ' report result for h8
End Function

进度记录

编辑 1:现在的代码不是666-devilish :-D了,并且失去了功能。我发现编写它们的一种简便方法可以避免开销。

编辑 2:又一次重大飞跃,有效地完成了删除inc / dec函数的工作,叹了口气,并使用了几个全局变量。我可能最终会明白这一点。

块和正方形的编码已更改。对代码长度没有影响。

编辑 3 :(伪)函数的返回,删除所有那些烦人的Call字节,以及其他一些调整。

编辑 4:突破大500,呜呼-将3个For循环压缩为1个。

编辑 5:Jiminy板球,这是我一起压缩两个功能时的另一大下降-对角线访问检查始终会通过相邻的正方形,所以...

编辑 6:神圣的niblicks,另一个巨大的下降。再见了外部功能,也就是全局变量。我已经不到原来发布的长度的一半了。

编辑 7:添加非高尔夫版本

编辑 8:修改了阅读过程,仅需花费几美元

编辑 9:压缩了最后几滴血的几个表情

编辑 10:Compund Next语句减少了几个字节


出于兴趣,可访问性分析(代码编号已过时,但...)之后的电路板图形为绿色,不可访问的正方形为白色,其他颜色为碎片或棋子。

3个成功的董事会 3块木板

几个挑战板:在以下两种情况下均可访问h8

  • P1Pq2p1 / 1P1R1R1p / 1K2R1R1 / 1p1p1p2 / p1b1b1np / 1B1B1N1k / Q1P1P1N1 / 1r1r1n2-10次求解
  • P1P3r1 / 1P1R2r1 / 1N1R1N2 / 1P1P1P2 / 1n1p1ppp / 1B1B4 / 1b1pppp1 / 1P6-绕组路径

1
非常好,并且+1,但是:(1)您确定960步就足够了吗?(2)可以通过颠倒看板来节省一些字节吗?If V>9 Then X(7-P,C)=我想(不是我知道VBA)会成为If V>9 Then X(P,C)=
msh210 '16

实际上,该技术节省了初始化P的时间,因此感谢您提出:-)。是的,我敢肯定,董事会15次通过就足够了。我做了很多检查。实际上,实际上我还不能将其推入10个通行证,但是640和960的字符数相同,所以我会放心地使用它。但是,如果我将板颠倒,则可能需要十次以上,甚至可能超过15遍-除非我也颠倒穿过板,否则会产生开销。
乔芬2013年

@ msh210 1个额外的观察- 最坏的情况是15个循环足以分析整个电路板,但是10个循环就足以获取h8的状态,所以我确实有很大的余地。原因是在评估方向上查找路径的速度要快得多,增加行号和列号-只要路径向上或向右,它就会在一次通过中完成。每次通过,向左或向下走只能走一步。
Joffan

@ msh210作为读取过程改进的一部分-狭义地保留了对FEN字符串末尾发表评论的功能-我添加了您建议的电路板反转-有些电路板现在占用了15遍(最多17遍),因此该功能已增加到板的30次通过。
乔芬

@Joffan您可以通过冷凝的所有实例下降3个字节[some non-letter character] To[some non-letter character]To
泰勒斯科特

3

Matlab,已保存636887字节(包括缩进)

这个解决方案不是很好,但是我想继续进行。

function[n] = h(x)
o=[];
for i=x
 b={blanks(str2num(i)),'K','k',i};o=[o b{~cellfun(@isempty,regexp(i,{'\d','[NBRQK]','[nbrqk]','p|P'}))}];
end
o=fliplr(reshape(o,8,8))
for i=1:64
 b=i-[-8,8,7,-1,-9,1,9,-7];
 if mod(i,8)==1
  b=b(1:5);
 elseif mod(i,8)==0
  b=b([1,2,6:8]);
 end
 b=b(b<65&b>0);c=o(b);dn=b(isspace(c)&ismember(b,i-[9,7,-9,-7]));
 for j=dn
  g=o(b(ismember(b,j-[-8,8,7,-1,-9,1,9,-7])));
  if ~isempty(regexp(g,'pk|kp|PK|KP|kk|KK'));c(b==j)='X';end;
 end
 Bc{i}=b(c==32);
end
n=Bc{1};
on=[];
while length(n)>length(on)
 on=n;
 for i=1:length(n)
  n=unique([n Bc{n(i)}]);
 end
end
any(n==64)
end

读取x上面指定的板子字符串,并将其转换成更完整的表示形式o,然后找到空格之间的所有移动(图形边缘),然后找出可能的移动(而不是填充的空间),然后找出哪些可能的移动具有“两扇门之间通过,然后找出门是打开的(棋子,相反的颜色)还是关闭的(相同的颜色,包括非棋子)。然后,它遍历以找到左下角的路径可以到达的位置,如果路径可以到达空间64,则为“是”板。


1
凉。您是否针对问题中的示例FEN进行了测试,以确保针对每个FEN返回正确的结果?同样,由于这是一个代码高尔夫球问题,因此您确实应该打高尔夫球。如果没有其他问题,您是否可以消除缩进(或使其成为单个空格或制表符而不是四个空格)?和/或删除=s 周围的空格?(我不知道MATLAB:也许这是不可能的。)
msh210 '16

是的,我可能在下一个休息时间做一些这样的事情。我确实针对您的所有示例以及某些示例进行了测试。我应该以某种方式指出吗?
sintax

不知道; 我只是想知道。
msh210 '16
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.