最可识别的滑动拼图是十五个拼图。它具有4 x 4网格,15个图块和一个空白网格空间。磁贴只能移动到空白区域,并且必须始终与网格对齐。
让我们定义一个广义的滑动拼图,它是一个二维的W宽度,高为H个高网格(W,H均为正整数),其中包含一些相同的未标记图块(在0到W × H之间),对齐到网格,排列为任何方式(不重叠),用空的网格空间填充其余区域。
例如,如果W和H为3,并且图块为T
,并且空白处E
为许多可能的侧板拼图布置之一,则
TTT
TET
EET
对于这些难题,有4种可能的举动:将所有事物推高,将所有事物推低,将所有事物推向左侧或将所有事物推向正确。沿某个方向“平移”会使所有图块尽可能沿该方向移动,直到它们碰到另一个图块或网格边界为止。有时推不会改变网格的布局,
如果将示例网格向右推,则结果为
TTT
ETT
EET
向左推的结果是
TTT
TTE
TEE
推倒结果是
EET
TET
TTT
(请注意,最左边T
的都已移动)
在这种情况下,推挤不会改变网格布局。
请注意,由于图块是无法区分的,因此这些难题没有“已解决”状态。还要注意,难题可能始于一旦做出推就不可能回到的布局(例如,在3 x 3网格中间的一个图块)。
挑战
仅使用可打印的ASCII编写两个矩形代码块,宽度均为M个字符,高度为N个字符(对于任何正整数M,N)。一个代码块将代表一个滑动拼图块,另一个代码块将代表一个空的网格空间。
将这两个代码块排列成W by H网格将创建一个代码表示的滑动拼图,该拼图可以保存为文本文件并作为常规程序运行。在运行时,此类程序应通过stdin提示用户输入1到4之间的数字;1表示向上,2表示向下,3表示左侧,4表示右侧。当用户键入他们的编号并按回车键时,程序将计算如何向该方向推其源代码图块,并将新的拼图布局保存到文件(新文件或同一文件)中,然后终止。
每次推后生成的新的滑动拼图代码文件都可以无限期地重复此过程。
例
假设我的图块代码块看起来像这样
// my
// tile
我的空网格空间代码块看起来像这样
//empty
//space
(M = 7,N = 2,这当然不是实际代码)
这两个模块的任何有效的滑动拼图布置都应该以我使用的语言创建一个程序,该程序可以运行以使用户朝某个方向推。
示例网格的代码表示为:
// my// my// my
// tile// tile// tile
// my//empty// my
// tile//space// tile
//empty//empty// my
//space//space// tile
因此,运行此命令并按2(向下),然后按Enter键会将其写入另一个文件(或相同文件):
//empty//empty// my
//space//space// tile
// my//empty// my
// tile//space// tile
// my// my// my
// tile// tile// tile
然后可以以完全相同的方式运行和推送该文件。
笔记
W by H滑动拼图的任何代码表示形式都应该可运行,并且能够正确推向自己。这包括从1乘1到某个合理的最大值(2 16乘2 16或更大)的所有网格大小。
程序可以读取自己的源代码。没有基于奎因的限制。任何形式的评论也可以。
即使没有要推动的瓷砖或不能推动的瓷砖,程序也必须提示要推入的方向。提示只是一个输入数字的地方,不需要任何消息。
您可以假设输入始终有效(1、2、3或4)。
用空格填充代码块就可以了。请记住,它们只能是可打印的ASCII,这意味着没有制表符,也没有换行符(除了有助于形成代码块的换行符)。
如果您的语言不支持stdin,请使用最接近的输入法。
您可以要求换行符位于代码难题文件的末尾。(或要求它不存在。)
您如何命名新文件并不重要。
f.txt
还是f
很好。这两个代码块可能不相同。
计分
目的是用最小的代码大小来做到这一点(这就是为什么将其标记为代码高尔夫)。最小代码块面积(M × N)的提交者为获胜者。决胜局获得了最高的票数。
f.txt
吗?是。