代码高尔夫:河内塔
规则
河内塔是一个谜题,如果您不太熟悉它,它的工作原理如下:
游戏场地由 3 个杆和 x 个圆盘组成,每个圆盘都更大比上一个。圆盘可以放在杆上,遵循以下规则:
- 一次只能移动一个圆盘,并且必须将其移动到另一根杆的顶部,
- 该圆盘必须从一根杆的顶部取出
- 一个圆盘可以移动到某处,仅如果目标杆上最上面的圆盘大于要移动的圆盘
最后- 游戏场地开始如下:
- 一根杆,带有x个圆盘,排序后最大的位于底部,最小的位于底部顶
- 一根空杆
- 一个空杆
游戏的目标是将原来的“一堆”圆盘移到另一根杆上,即将所有圆盘放在另一根杆上杆,所以(再次)最大的在底部,最小的在顶部
实现
您的目标将是用您选择的编程语言编写一个程序,该程序接受输入(如下所述)并输出解决问题所需的步骤的位置。
与往常一样,尽量使其尽可能短。
输入
输入示例:
4-3,7-6-5,2-1
输入是一个字符串,由 3 部分组成,以逗号分隔。这些零件是 3 个杆上每一个上的圆盘列表。它们也被分开,这次用连字符(-),每个子部分都是一个数字,数字越大,磁盘越大。
因此 - 对于上面的输入,这将是一个视觉表示:
. . .
| =====|===== |
===|=== ======|====== =|=
====|==== =======|======= ==|==
ROD 1 ROD 2 ROD 3
输出
正如您在上面的表示中看到的 - 输入的最左边部分是杆号 1,中间是杆号两个,最后一个是棒号 3。
程序的输出应如下所示:
12,23,31,12,23,13
一个数字列表,以逗号分隔,定义应取出磁盘的棒,以及应放置磁盘的棒在。只有 3 根杆,因此只有 6 种可能的组合(因为磁盘必须移动到另一根杆,而不是同一杆):
12
13
21
23
31
32
注意
输入不必描述处于“原始”状态的字段 - 它可以是中解决了。
您的程序不能产生空输出。如果输入处于原始状态,只需将磁盘放在不同的杆上即可。
输入可以有一个空杆,如下所示:
2-1,3,
,,1
4-3,,2-1
如果输入不是这样的格式,您的程序可能会产生未定义的行为。如果输入无效(例如较大的磁盘放在较小的磁盘上、丢失磁盘、无法解决),则可能会出现这种情况。 输入将始终有效。
确保解决方案尽可能快(尽可能少的转弯) - 也就是说,不要浪费“12,21”的转弯,12"...
测试
所以,我为你准备了这个小闪存,你可以用它来测试你的程序是否产生了一个好的解决方案,而无需写下来或任何东西。
这是: Hanoi AlgoTest (等待它加载然后刷新 -- 死链接 :|)
要使用它,请将程序的输入粘贴到 INPUT 字段,并将程序生成的输出粘贴到 PROCESS 字段。它将以您也可以更改的速度运行模拟,并以视觉表示形式打印出底部的任何错误。
希望有帮助。
Rules
The Towers of Hanoi is a puzzle, and if you are not very familiar with it, here is how it works:
The play field consists of 3 rods, and x number of disks, each next one bigger than the previous one. The disks can be put on the rod, with these RULES:
- only one disk can be moved at once, and it must be moved on the top of another rod
- the disk must be taken from the top of a rod
- a disk can be moved somewhere, ONLY if the top-most disk at the target rod is bigger than the one to be moved
And finally - the play field STARTS like this:
- a rod, with x disks, sorted so the largest is on the bottom, and the smallest on the top
- an empty rod
- an empty rod
The GOAL of the game is to move the original "stack" of disks on another rod, that is - put all of the disks on another rod, so (again) the largest is on the bottom, and the smallest on the top
Implementation
YOUR goal will be to make a program in programming language of your choice, that takes an input (described below) and outputs the steps necessary to solve the position.
As always, try to make it as short as possible.
Input
An example input:
4-3,7-6-5,2-1
Input is a string, consisting of 3 parts, separated by commas. The parts are a list of disks on each of the 3 rods. They are separated too, this time with hyphens ( - ), and each subpart is a number, the larger the number is, the larger the disk is.
So - for the above input, this would be a visual representation:
. . .
| =====|===== |
===|=== ======|====== =|=
====|==== =======|======= ==|==
ROD 1 ROD 2 ROD 3
Output
As you can see in the above representation - the the left-most part of the input is rod number one, the middle is rod number two, and the last one is rod number 3.
The output of your program should look like this:
12,23,31,12,23,13
A list of numbers, separated by commas that defines the rod that a disk should be taken of, and the rod that the disk should be put on. There are only 3 rods, so there is just 6 possible combinations (because a disk has to be moved to another rod, not the same one):
12
13
21
23
31
32
Notes
The input does not have to describe a field in "original" state - it can be mid-solved.
Your program can NOT produce null output. If the input IS in the original state, just put the disks to a DIFFERENT rod.
The input can have an empty rod(s), like these:
2-1,3,
,,1
4-3,,2-1
If the input is not in this formatted like that, your program can produce undefined behavior. So it can if the input is not valid (like bigger disk on a smaller one, missing disk, unsolvable). Input will always be valid.
Make sure the solution is as fast as possible (as little turns as possible) - that is, don't waste turns by "12,21,12"...
Testing
So, I prepared this small flash for you, with which you can test if your program produced a good solution without writing it down or anything.
Here it is: Hanoi AlgoTest (wait for it to load then refresh -- Dead link :|)
To use it, paste the input to the program to the INPUT field, and the output produced by your program to the PROCESS field. It will run a simulation, at speed which you can also change, with a visual representation, printing out any errors in the bottom part.
Hope it helps.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
Perl, 209 (203) char
重写以跟踪每个磁盘的位置,而不是每个杆上包含的磁盘列表。
<罢工>306 <罢工>291 <罢工>263 <罢工>244
236213删除不必要的空格后的 209 个字符。$R[j]
:磁盘 j 的位置$n
:磁盘 #1 的位置$m
:要移动的磁盘数量$p
:将磁盘移动到的位置&M(r,s)
:将$m-1
磁盘从 r 移动到 s 。附加到$_
并设置@R
sub M
内的替换可优化输出,删除无关步骤。它可以被删除(12 个字符)并且输出仍然有效。如果使用命令行开关
-apF,
调用 perl 解释器,则可以删除另外 12 个字符。加上命令行开关的额外 6 个字符,这使我们的净字符数减少到 203 个:Perl, 209 (203) char
Rewritten to keep track of the location of each disk as opposed to the list of disks that are contained on each rod.
306291263244236213209 chars after removing unnecessary whitespace.$R[j]
: the location of disk j$n
: the location of disk #1$m
: the number of disks to move$p
: the location to move the disks to&M(r,s)
: move$m-1
disks from r to s. Appends to$_
and sets@R
The substitution inside
sub M
optimizes the output, removing extraneous steps. It could be removed (12 characters) and the output would still be valid.Another 12 characters can be removed if the perl interpreter is invoked with the command-line switch
-apF,
. With the extra 6 chars for the command-line switch, this gets us down to net 203 characters:这是 10 的入门,用 Scala 编写,修改了几次。我不知道有什么问题,也没有其他想法来进一步减少
作为 Scala 脚本运行的动作。
其中的一些部分非常优雅(IMO),但其他部分是一个丑陋的黑客
最短的代码(但不是最佳的移动),跟踪磁盘的位置而不是杆上的磁盘列表(从 Perl 解决方案中无耻地窃取的想法)
谜题取自命令行。
338 字节。不算太破烂,因为这是一种静态类型语言,并且仍然相对可读(如果将 ; 替换为换行符)
可读版本如下(具有更优化的移动)
Here's a starter for 10, in Scala, revised a few times. I don't know of any issues, and I have no other ideas for further reducing the moves
Runs as a Scala script.
Bits of this are quite elegant (IMO) but other bits are an ugly hack
Shortest code (but non-optimal moves), tracking position of disks rather than list of disks on rods (idea shamelessly stolen from the Perl solution)
Puzzle is taken from the command line.
338 bytes. Not too shabby since this is a statically typed language, and still relatively readable (if you replace ; with newlines)
Readable version follows (with more optimal moves)
Perl 241 char
当然不是最有效的方法,但它确实有效。
更新以抑制最后一个逗号。
与空格相同:
用法:
输出:
21,23,12,23,12,32,21,23,12,23,12,32,21,32,12,23,21,32,21,32,12, 23,12,32,21,23,12,23,21,32,21,32,12,23,21,32,21,32,12,23,12,32,21,23,12,23, 12,32,21,32,12,23,21,32,21,23,12,23,12,32,21,23,12,23,21,32,21,32,12,23,21, 32,21,32,12,23,12,32,21,23,12,23,21,32,21,32,12,23,21,32,21,23,12,23,12,32, 21,23,12,23,12,32,21,32,12,23,21,32,21,23,12,23,12,32,21,23,12,23,12,32,21, 32,12,23,21,32,21,32,12,23,12,32,21,23,12,23,21,32,21,32,12,23,21,32,21,23, 12,23,12,32,21,23,12,23,12,32,21,32,12,23,21,32,21,23,12,23,12,32,21,23,12, 23
Perl 241 char
Certainly not the most efficient way, but it works.
Updated to suppress last comma.
Same with whitespaces:
Usage:
Output:
21,23,12,23,12,32,21,23,12,23,12,32,21,32,12,23,21,32,21,32,12,23,12,32,21,23,12,23,21,32,21,32,12,23,21,32,21,32,12,23,12,32,21,23,12,23,12,32,21,32,12,23,21,32,21,23,12,23,12,32,21,23,12,23,21,32,21,32,12,23,21,32,21,32,12,23,12,32,21,23,12,23,21,32,21,32,12,23,21,32,21,23,12,23,12,32,21,23,12,23,12,32,21,32,12,23,21,32,21,23,12,23,12,32,21,23,12,23,12,32,21,32,12,23,21,32,21,32,12,23,12,32,21,23,12,23,21,32,21,32,12,23,21,32,21,23,12,23,12,32,21,23,12,23,12,32,21,32,12,23,21,32,21,23,12,23,12,32,21,23,12,23
尝试Lua
我尝试实现 wikipedia 的迭代解决方案,但它并没有真正起作用,但是我花在它上面的时间已经结束了,所以我希望这能激励人们去适应它。
它确实很好地解析了所有内容,包括空列。
额外的好处:它可以很好地打印堆栈,就像问题中的视觉表示一样。
Attempt at Lua
I've tried to implement the iterative solution from wikipedia, but it doesn't really work, but the time i'm spending on it is up, so I hope this inspires someone to adapt it.
It does parse everything well, including empty columns.
Extra goodie: it does pretty printing of the stacks as in the visual representation in the question.