挑战
按字符数输入最短的代码来输入棋盘的 2D 表示,并根据输入输出“真”或“假”。
该棋盘由 4 种类型的方块组成:
# - A solid wall
x - The target the laser has to hit
/ or \ - Mirrors pointing to a direction (depends on laser direction)
v, ^, > or < - The laser pointing to a direction (down, up, right and left respectively)
只有一束激光和一个目标。墙壁必须形成任何尺寸的实心矩形,激光和目标放置在里面。 “房间”内的墙壁是可能的。
激光射线从其原点发射并传播到它所指向的方向。如果激光射线击中墙壁,它就会停止。如果激光射线击中镜子,它会以 90 度反射到镜子指向的方向。镜子是双面的,这意味着两侧都是“反射”的,并且可以以两种方式反射光线。如果激光射线击中激光器 (^v><
) 本身,它将被视为一堵墙(激光束会破坏光束器,因此它永远不会击中目标)。
测试用例
Input:
##########
# / \ #
# #
# \ x#
# > / #
##########
Output:
true
Input:
##########
# v x #
# / #
# /#
# \ #
##########
Output:
false
Input:
#############
# # #
# > # #
# # #
# # x #
# # #
#############
Output:
false
Input:
##########
#/\/\/\ #
#\\//\\\ #
#//\/\/\\#
#\/\/\/x^#
##########
Output:
true
代码计数包括输入/输出(即完整程序)。
The challenge
The shortest code by character count to input a 2D representation of a board, and output 'true' or 'false' according to the input.
The board is made out of 4 types of tiles:
# - A solid wall
x - The target the laser has to hit
/ or \ - Mirrors pointing to a direction (depends on laser direction)
v, ^, > or < - The laser pointing to a direction (down, up, right and left respectively)
There is only one laser and only one target. Walls must form a solid rectangle of any size, where the laser and target are placed inside. Walls inside the 'room' are possible.
Laser ray shots and travels from its origin to the direction it's pointing. If a laser ray hits the wall, it stops. If a laser ray hits a mirror, it bounces 90 degrees to the direction the mirror points to. Mirrors are two sided, meaning both sides are 'reflective' and may bounce a ray in two ways. If a laser ray hits the laser (^v><
) itself, it is treated as a wall (laser beam destroys the beamer and so it'll never hit the target).
Test cases
Input:
##########
# / \ #
# #
# \ x#
# > / #
##########
Output:
true
Input:
##########
# v x #
# / #
# /#
# \ #
##########
Output:
false
Input:
#############
# # #
# > # #
# # #
# # x #
# # #
#############
Output:
false
Input:
##########
#/\/\/\ #
#\\//\\\ #
#//\/\/\\#
#\/\/\/x^#
##########
Output:
true
Code count includes input/output (i.e full program).
发布评论
评论(28)
Perl,
166160 个字符Perl,
251248246222214 <罢工>208 <罢工>203 <罢工>201 <罢工>193 <罢工>190 <罢工>180罢工> <罢工> 176 < 罢工> 173 < 罢工> 170 166 --> 160 个字符。当比赛结束时,解决方案有 166 笔,但 A. Rex 找到了几种方法来减少 6 个字符:
第一行将输入加载到
%t
中,这是棋盘的一个表格,其中$t{99*i+j}
保存第 i 行、j 列的字符。然后,它在
%t
的元素中搜索与> 匹配的字符。 ^ <
或v
,同时将$d
设置为 0 到 3 之间的值,表示激光束的初始方向。在主循环每次迭代开始时,如果光束当前位于镜子上,我们就会更新
$d
。异或 3 给出\
镜像的正确行为,异或 1 给出/
镜像的正确行为。接下来,根据当前方向更新当前位置
$r
。我们将当前位置的字符赋给
$_
,以方便使用匹配运算符。如果我们处于空白区域或镜像角色,则继续。否则,如果我们位于目标 (
$_ =~ /x/
) 上,则终止true
,否则终止false
。限制:可能无法解决超过 99 列的问题。可以通过增加 3 个字符来消除此限制,
Perl,
166160 charactersPerl,
251248246222214208203201193190180176173170166 --> 160 chars.Solution had 166 strokes when this contest ended, but A. Rex has found a couple ways to shave off 6 more characters:
The first line loads the input into
%t
, a table of the board where$t{99*i+j}
holds the character at row i,column j. Then,it searches the elements of
%t
for a character that matches> ^ <
orv
, and simultaneously sets$d
to a value between 0 and 3 that indicates the initial direction of the laser beam.At the beginning of each iteration in the main loop, we update
$d
if the beam is currently on a mirror. XOR'ing by 3 gives the correct behavior for a\
mirror and XOR'ing by 1 gives the correct behavior for a/
mirror.Next, the current position
$r
is updated accoring to the current direction.We assign the character at the current position to
$_
to make convenient use of the match operators.Continue if we are on a blank space or a mirror character. Otherwise we terminate
true
if we are on the target ($_ =~ /x/
) andfalse
otherwise.Limitation: may not work on problems with more than 99 columns. This limitation could be removed at the expense of 3 more characters,
Perl,177 个字符
第一个换行符可以删除;其他两项是强制性的。
解释:
如果向右移动的光束遇到{空旷的空间,向上倾斜的镜子,向下倾斜的镜子},它就会变成{向右移动的光束,向上移动的光束,向下移动的光束}。一路初始化
$/
——幸运的是“6”不是有效的输入字符。将棋盘读入
$_
。$s
是梁现在位于其顶部的任何符号。由于激光发射器将被视为一堵墙,因此首先将其设置为一堵墙。如果激光束指向除右侧以外的任何方向,请旋转其符号,然后将整个板旋转到位(同时旋转镜子的符号)。这是一个 90 度的左旋转,通过在调换行和列的同时反转行来有效地完成,这是一个稍微有点残忍的 s///e ,但有副作用。在 Golfed 代码中,tr 以
y'''
的形式编写,这允许我跳过反斜杠一个反斜杠。如果我们击中目标或墙壁,则以正确的消息结束。
如果激光前方有空位,请向前移动。如果激光器前面有镜子,请向前移动并旋转光束。无论哪种情况,都将“保存的符号”放回到旧的光束位置,并将我们刚刚覆盖的内容放入保存的符号中。
重复直到终止。
{...;redo}
比for(;;){...}
少两个字符,比while(1){.. 少三个字符.}
。Perl, 177 Characters
The first linebreak can be removed; the other two are mandatory.
Explanation:
If a right-moving beam runs into an {empty space, up-angled mirror, down-angled mirror} it becomes a {right-moving beam, up-moving beam, down-moving beam}. Initialize
$/
along the way -- fortunately "6" is not a valid input char.Read the board into
$_
.$s
is the symbol of whatever the beam is sitting on top of now. Since the laser emitter is to be treated like a wall, set this to be a wall to begin with.If the laser beam is pointing any way except right, rotate its symbol, and then rotate the whole board in place (also rotating the symbols for the mirrors). It's a 90 degree left rotation, accomplished effectively by reversing the rows while transposing rows and columns, in a slightly fiendish
s///e
with side effects. In the golfed code, the tr is written in the formy'''
which allows me to skip backslashing one backslash.Terminate with the right message if we hit the target or a wall.
If there's an empty space in front of the laser, move forward. If there's a mirror in front of the laser, move forward and rotate the beam. In either case, put the "saved symbol" back into the old beam location, and put the thing we just overwrote into the saved symbol.
Repeat until termination.
{...;redo}
is two characters less thanfor(;;){...}
and three less thanwhile(1){...}
.C89 (209 个字符)
解释
如果你不懂 C,这个怪物可能很难理解。只是一个预警。
这个小宏检查当前字符 (
*p
) 是否等于字符形式的a
(*#a
)。如果相等,则将运动向量设置为b
(m=b
),将此角色标记为墙(*p=1
) ,并将起点设置为当前位置 (q=p
)。该宏包括“else”部分。声明一些变量。
*
q
是灯光的当前位置。*
G
是一维数组形式的游戏板。*
p
是填充G
时当前读取的位置。*
w
是板的宽度。明显的
main
。m
是存储运动矢量的变量。 (它是main
的一个参数,作为一种优化。)循环遍历所有字符,使用
p
填充G
。跳过G[0]
作为优化(无需在for
的第三部分浪费一个字符再次写入p
)。如果可能的话,使用上述宏来定义激光。
-1
和1
分别对应左和右,-w
和w
分别对应上下。如果当前字符是行尾标记 (ASCII 10),则设置宽度(如果尚未设置)。跳过的
G[0]
允许我们编写w=pG
而不是w=p-G+1
。此外,这还完成了来自M
的?:
链。通过移动矢量移动灯光。
反映运动矢量。
如果这是一堵墙或
x
,请使用适当的消息退出(m=0
终止循环)。否则,不执行任何操作 (noop;m=m
)C89 (209 characters)
Explanation
This monstrosity will probably be difficult to follow if you don't understand C. Just a forewarning.
This little macro checks if the current character (
*p
) is equal to whatevera
is in character form (*#a
). If they are equal, set the movement vector tob
(m=b
), mark this character as a wall (*p=1
), and set the starting point to the current location (q=p
). This macro includes the "else" portion.Declare some variables.
*
q
is the light's current location.*
G
is the game board as a 1D array.*
p
is the current read location when populatingG
.*
w
is the board's width.Obvious
main
.m
is a variable storing the movement vector. (It's a parameter tomain
as an optimization.)Loop through all characters, populating
G
usingp
. SkipG[0]
as an optimization (no need to waste a character writingp
again in the third part of thefor
).Use the aforementioned macro to define the lazer, if possible.
-1
and1
correspond to left and right, respectively, and-w
andw
up and down.If the current character is an end-of-line marker (ASCII 10), set the width if it hasn't already been set. The skipped
G[0]
allows us to writew=p-G
instead ofw=p-G+1
. Also, this finishes off the?:
chain from theM
's.Move the light by the movement vector.
Reflect the movement vector.
If this is a wall or
x
, quit with the appropriate message (m=0
terminates the loop). Otherwise, do nothing (noop;m=m
)我敢打赌人们已经等待这个了很长一段时间了。 (你的意思是,挑战结束了,没有人再关心了?)
中的解决方案
看哪......我在这里提出了Befunge-93
!它的重量高达 973 个字符(或者 688,如果您足够仁慈地忽略空白,空白仅用于格式化,在实际代码中不执行任何操作)。
警告:不久前我用 Perl 编写了自己的 Befunge-93 解释器,不幸的是,这就是我真正有时间测试它的全部内容。总的来说,我对它的正确性相当有信心,但它在 EOF 方面可能有一个奇怪的限制:由于 Perl 的
<>
运算符在文件末尾返回 undef,因此它被处理为0 在数字上下文中。对于基于 C 的实现,其中 EOF 具有不同的值(例如 -1),此代码可能不起作用。说明
如果您不熟悉 Befunge 语法和操作,请查看此处。
Befunge 是一种基于堆栈的语言,但有些命令允许将字符写入 Befunge 代码。我在两个地方利用了这一点。首先,我将整个输入复制到 Befunge 板上,但位于实际编写代码下方的几行。 (当然,当代码运行时,这实际上是不可见的。)
另一个地方靠近左上角:
在这种情况下,我上面突出显示的区域是我存储几个坐标的地方。中间行的第一列是我存储当前“光标位置”的 x 坐标的位置;第二列是我存储 y 坐标的位置;接下来的两列用于存储找到激光束源时的 x 和 y 坐标;最后一列(其中包含“a”字符)最终会被覆盖以包含当前的光束方向,该方向随着光束路径的追踪而明显变化。
程序首先将 (0,27) 作为初始光标位置。然后输入一次读取一个字符并放置到光标位置;换行符只会导致 y 坐标增加,x 坐标返回到 0,就像真正的回车一样。最终 undef 被解释器读取,并且 0 字符值用于表示输入结束并继续进行激光迭代步骤。当读取激光字符 [<>^v] 时,它也会被复制到内存存储库(在“a”字符上方),并且其坐标也会被复制到左侧的列。
所有这一切的最终结果是整个文件基本上被复制到 Befunge 代码中,比实际遍历的代码稍低一些。
然后,光束位置被复制回光标位置,并执行以下迭代:
如果有足够的需求,我将尝试指出代码中所有这些都是完成的确切位置。
I would bet people have been waiting for this one for a LOOOOONG time. (What do you mean, the challenge is over and nobody cares any more?)
Behold... I here present a solution in
Befunge-93!
It weighs in at a whopping 973 charaters (or 688 if you are charitable enough to ignore whitespace, which is only used for formatting and does nothing in actual code).
Caveat: I wrote my own Befunge-93 interpreter in Perl a short while ago, and unfortunately this is all I've really had time with which to test it. I'm reasonably confident in its correctness in general, but it might have an odd limitation with regard to EOF: Since Perl's
<>
operator returns undef at the end of file, this is processed as a 0 in the numeric context. For C-based implementations where EOF has a different value (-1 say), this code might not work.Explanation
If you're not familiar with the Befunge syntax and operation, check here.
Befunge is a stack-based language, but there are commands that allow one to write characters to the Befunge code. I take advantage of that in two places. First, I copy the entire input onto the Befunge board, but located a couple of lines below the actual written code. (Of course, this is never actually visible when the code runs.)
The other place is near the the upper-left:
In this case, the area I've highlighted above is where I store a couple of coordinates. The first column in the middle row there is where I store the x-coordinate for the current "cursor position"; the second column is where I store the y-coordinate; the next two columns are for storing the x- and y-coordinate of the laser beam source when that is found; and the final column (with the 'a' character in it) is eventually overwritten to contain the current beam direction, which obviously changes as the beam's path is traced.
The program starts by placing (0,27) as the initial cursor position. Then input is read one character at a time and placed in the cursor position; newlines merely cause the y-coordinate to increase and the x-coordinate to go back to 0, just like a real carriage return. Eventually undef is read by the interpreter and that 0 character value is used to signal the end of input and move on to the laser iteration steps. When the laser character [<>^v] is read, that is also copied to the memory repository (over the 'a' character) and its coordinates are copied to the columns just to the left.
The end result of all of this is that the entire file is basically copied into the Befunge code, a little ways below the actual code traversed.
Afterwards, the beam location is copied back into the cursor locations, and the following iteration is performed:
If there's enough demand for it, I'll try to point out exactly where in the code all this is accomplished.
F#,36 行,非常可读
好吧,只是为了得到答案:
示例:
F#, 36 lines, very readable
Ok, just to get an answer out there:
Samples:
Golfscript - 83 个字符(我和 strager 的混搭)
换行符只是用于包装
Golfscript - 107 个字符
换行符只是为了清晰
它是如何工作的。
第一行计算出初始位置和方向。
每当激光击中镜子时,第二行就会逐步进行转动。
Golfscript - 83 chars (mashup of mine and strager's)
The newline is just here for wrapping
Golfscript - 107 chars
The newline is just there for clarity
How it works.
First line works out the initial location and direction.
Second line steps through turning whenever the laser hits a mirror.
Ruby 中的 353 个字符:314现在 277 个字符!好的,Ruby 中的 256 个字符,现在我完成了。不错的整数。 :)247 个字符。我无法停止。223203Ruby 中的 201 个字符使用空格:
稍微重构:
353 chars in Ruby:314277 chars now!OK, 256 chars in Ruby and now I'm done. Nice round number to stop at. :)247 chars. I can't stop.223203201 chars in RubyWith whitespace:
Slightly refactored:
Python
294277253240232 个字符,包括换行符:(第 4 行和第 5 行中的第一个字符是制表符,而不是空格)
我忘记了 Python 甚至还有可选的分号。
工作原理
该代码背后的关键思想是使用复数来表示位置和方向。行是虚轴,向下增加。列是实轴,向右增加。
l='>v<^';
激光符号列表。选择顺序以使激光方向字符的索引对应于 sqrt(-1) 的幂x={'/':'^','\\':'v>^ <',' ':l};
一个变换表,用于确定当光束离开不同瓦片时方向如何变化。瓷砖是关键,新方向是价值。b=[1];
持有棋盘。第一个元素为 1(计算结果为 true),因此 while 循环将至少运行一次。r=p=0
r
是输入的当前行号,p
是激光束的当前位置。while b[-1]:
当 raw_input 返回空字符串时停止加载棋盘数据b+=[raw_input()];r+=1
将下一行输入追加到板并增加行计数器for g in l:
依次猜测每个激光方向c=b[r].find(g)
将列设置为如果激光不在直线上(或指向不同方向),则为 -1if-1 如果我们发现激光,则设置当前位置
p
和方向d
。d
是l
中的字符之一将板加载到
b
后,当前位置p
和方向 < code>d 已设置为激光源的代码。while' ' 空格的 ASCII 值比任何方向符号都低,因此我们将其用作停止标志。
z=l.find(d);
l
字符串中当前方向字符的索引。稍后使用z
来使用x
表确定新的波束方向,并增加位置。p+=1j**z;
使用 i 的幂递增位置。例如,l.find('<')==2
-> i^2 = -1,这将移至左侧一列。c=b[int(p.imag)][int(p.real)];
读取当前位置的字符d=x.get(c,' '*4) [z]
在变换表中查找光束的新方向。如果表中不存在当前字符,则将d
设置为空格。print'#' 如果我们停在目标以外的任何地方,则打印 false。
Python
294277253240232 characters including newlines:(the first character in lines 4 and 5 is a tab, not spaces)
I had forgotten Python even had optional semicolons.
How it works
The key idea behind this code is using complex numbers to represent positions and directions. The rows are the imaginary axis, increasing downward. The columns are the real axis, increasing to the right.
l='>v<^';
a list of the laser symbols. The order is chosen so that the index of a laser direction character corresponds with a power of sqrt(-1)x={'/':'^<v>','\\':'v>^<',' ':l};
a transformation table determining how the direction changes when the beam leaves different tiles. The tile is the key, and new directions are the values.b=[1];
holds the board. The first element is 1 (evaluates as true) so that the while loop will run at least once.r=p=0
r
is the current row number of the input,p
is the current position of the laser beam.while b[-1]:
stop loading board data when raw_input returns an empty stringb+=[raw_input()];r+=1
append the next line of input to the board and increment the row counterfor g in l:
guess each laser direction in turnc=b[r].find(g)
set the column to the location of the laser or -1 if it's not in the line (or is pointing in a different direction)if-1<c:p=c+1j*r;d=g
if we found a laser, then set the current positionp
and directiond
.d
is one of the chars inl
After loading the board into
b
, the current positionp
and directiond
have been set to those of the laser source.while' '<d:
space has a lower ASCII value than any of the direction symbols, so we use it as a stop flag.z=l.find(d);
index of the current direction char in thel
string.z
gets used later to both determine the new beam direction using thex
table, and to increment the position.p+=1j**z;
increment the position using a power of i. For example,l.find('<')==2
-> i^2 = -1, which would move to the left one column.c=b[int(p.imag)][int(p.real)];
read the char at the current positiond=x.get(c,' '*4)[z]
look up the new direction for the beam in the transformation table. If the current char doesn't exist in the table, then setd
to space.print'#'<c
print false if we stopped on anything other than the target.这
是是Brian 的解决方案到C#3 的直接移植,减去控制台交互。这不是挑战赛的一个条目,因为它不是一个完整的程序,我只是想知道他使用的一些 F# 结构如何在 C# 中表示。
编辑:经过一些实验,以下相当冗长的搜索代码:
已被替换为一些更紧凑的 LINQ to Objects 代码:
This
iswas a direct port of Brian's solution to C#3, minus the console interactions.This isn't an entry in the challenge since it isn't a complete program, I was just wondering how some of the F# constructs he used could be represented in C#.
Edit: After some experimentation, the following rather verbose search code:
has been replaced with some much more compact LINQ to Objects code:
F#,255 个字符(而且仍然相当可读!):
好的,经过一晚的休息,我改进了很多:
让我们逐行讨论它。
首先,将所有输入放入一个大的一维数组中(二维数组可能不利于代码高尔夫;只需使用一维数组并在索引中添加/减去一行的宽度即可向上/向下移动一行)。
接下来,我们通过索引数组来计算“w”(输入行的宽度)和“c”(起始位置)。
现在让我们定义“下一个”函数“n”,它采用当前位置“c”和方向“d”,即上、左、右、下的 0、1、2、3。
索引 epsilon 'e' 和 What-new-direction-if-we-hit-a-slash 's' 由表格计算。例如,如果当前方向“d”为 0(向上),则表的第一个元素为“-w,2”,这意味着我们将索引递减 w,如果我们击中斜杠,则新方向为 2 (正确的)。
现在我们递归到下一个函数“n”,其中(1)下一个索引(“c+e”-当前加上 epsilon),以及(2)新方向,我们通过向前查看数组中的内容来计算新方向下一个单元格。如果先行字符是斜杠,则新方向是“s”。如果它是反斜杠,则新方向是 3-s(我们选择编码 0123 使之有效)。如果它是一个空格,我们就继续朝同一个方向“d”前进。如果它是任何其他字符“c”,则游戏结束,如果该字符是“x”则打印“true”,否则打印“false”。
首先,我们使用初始位置“c”和起始方向(将方向初始编码为 0123)来调用递归函数“n”。
我想我可能还可以再删掉一些字符,但我对这样的结果非常满意(255 是一个不错的数字)。
F#, 255 chars (and still rather readable!):
Ok, after a night's rest, I improved this a lot:
Let's talk through it line by line.
First, slurp all the input into a big one-dimensional array (2D arrays can be bad for code golf; just use a 1D array and add/subtract the width of one line to the index to move up/down a line).
Next we compute 'w', the width of an input line, and 'c', the starting position, by indexing into our array.
Now let's define the 'next' function 'n', which takes a current position 'c' and a direction 'd' which is 0,1,2,3 for up,left,right,down.
The index-epsilon 'e' and the what-new-direction-if-we-hit-a-slash 's' are computed by a table. For example, if the current direction 'd' is 0 (up), then the first element of the table says "-w,2" which means we decrement the index by w, and if we hit a slash the new direction is 2 (right).
Now we recurse into the next function 'n' with (1) the next index ("c+e" - current plus epsilon), and (2) the new direction, which we compute by looking ahead to see what's in the array in that next cell. If the lookahead char is a slash, the new direction is 's'. If it's a backslash, the new direction is 3-s (our choice of encoding 0123 makes this work). If it's a space, we just keep going in the same direction 'd'. And if it's any other character 'c', then the game ends, printing 'true' if the char was 'x' and false otherwise.
To kick things off, we call the recursive function 'n' with the initial position 'c' and the starting direction (which does the initial encoding of direction into 0123).
I think I can probably still shave a few more characters off it, but I am pretty pleased with it like this (and 255 is a nice number).
权重为 18203 个字符的 Python 解决方案可以:
当没有“房间”时,“房间”
它仍然需要整理了一下,我不知道 2D 物理是否规定光束不能穿过自身...
一个 bash 脚本来展示颜色错误报告:
开发中使用的单元测试:
Weighing in at 18203 characters is a Python solution that can:
'room'
It still needs tidied up somewhat and I do not know if 2D physics dictate that the beam cannot cross itself...
A bash script to show off the colour error reporting:
The unittests used in development:
Ruby,176 个字符
我使用了一个简单的状态机(像大多数海报一样),没什么花哨的。我只是用我能想到的每一种技巧不断地削减它。用于改变方向的按位 XOR(作为整数存储在变量
c
中)比我在早期版本中使用的条件有很大改进。我怀疑递增
x
和y
的代码可以更短。这是执行增量的代码部分:编辑:我能够稍微缩短上面的内容:
激光
c
的当前方向存储如下:代码依靠这一事实将
x
和y
增加正确的数量(0、1 或 -1)。我尝试重新排列哪些数字映射到每个方向,寻找一种排列方式,可以让我进行一些按位操作来增加值,因为我有一种挥之不去的感觉,它会比算术版本短。Ruby, 176 characters
I used a simple state machine (like most posters), nothing fancy. I just kept whittling it down using every trick I could think of. The bitwise XOR used to change direction (stored as an integer in the variable
c
) was a big improvement over the conditionals I had in earlier versions.I have a suspicion that the code that increments
x
andy
could be made shorter. Here is the section of the code that does the incrementing:Edit: I was able to shorten the above slightly:
The current direction of the laser
c
is stored as follows:The code relies on this fact to increment
x
andy
by the correct amount (0, 1, or -1). I tried rearranging which numbers map to each direction, looking for an arrangement that would let me do some bitwise manipulation to increment the values, because I have a nagging feeling that it would be shorter than the arithmetic version.C# 3.0
259 个字符
可读性稍好一些:
字符的主要浪费似乎在于查找地图的宽度和激光源的位置。有什么想法如何缩短这个吗?
C# 3.0
259 chars
Slightly more readable:
The main waste of chars seems to be in finding the width of the map and the position of the laser source. Any ideas how to shorten this?
C + ASCII,197 个字符:
此 C 解决方案假定 ASCII 字符集,允许我们使用 XOR 镜像技巧。它也非常脆弱——例如,所有输入线的长度必须相同。
它突破了 200 个字符的大关 - 但天哪,仍然没有击败那些 Perl 解决方案!
C + ASCII, 197 characters:
This C solution assumes an ASCII character set, allowing us to use the XOR mirror trick. It's also incredibly fragile - all the input lines must be the same length, for example.
It breaks under the 200 character mark - but dang it, still haven't beaten those Perl solutions!
Golfscript (83 个字符)
你好,gnibbler!
Golfscript (83 characters)
Hello, gnibbler!
Python - 152
从名为“L”的文件读取输入
要从标准输入读取,请用此替换第一行
如果您需要小写 true/false,请将最后一行更改为
Python - 152
Reads input from a file called "L"
To read from stdin replace the first line with this
If you need lowercase true/false change the last line to
JavaScript - 265 个字符
更新 IV - 这很可能是最后一轮更新,通过切换到 do-while 循环并重写来设法节省更多字符运动方程。
更新 III - 感谢 strager 关于删除 Math.abs() 并将变量放入全局名称空间的建议,再加上对变量分配的一些重新排列,使代码减少到 282人物。
更新 II - 对代码进行了更多更新,以删除 != -1 的使用,以及更好地使用变量来进行较长的操作。
更新 - 通过创建对indexOf函数的引用(感谢LiraNuna!)并删除不需要的括号来进行一些更改。
这是我第一次进行代码高尔夫,所以我不确定这会好多少,任何反馈都会受到赞赏。
完全最小化版本:
带注释的原始版本:
用于测试的网页:
JavaScript - 265 Characters
Update IV - Odds are this will be the last round of updates, managed to save a couple more characters by switching to a do-while loop and rewriting the movement equation.
Update III - Thanks to the suggestion by strager in regards to removing Math.abs() and putting the variables in the global name space, that coupled with some rearranging of the variable assignments got the code down to 282 characters.
Update II - Some more updates to the code to remove the use of != -1 as well as some better use of variables for longer operations.
Update - When through and made some changes by creating a reference to the indexOf function (thanks LiraNuna!) and removing parenthesis that were not needed.
This is my first time doing a code golf so I'm not sure how much better this could be, any feed back is appreciated.
Fully minimized version:
Original version with comments:
Web page to test with:
镜之屋
不是真正的挑战,但我根据这个概念编写了一个游戏(不久前)。
它是用 Scala 编写的,是开源的,可以在此处获取:
它可以做更多的事情;处理颜色以及各种类型的镜子和设备,但版本 0.00001 完全满足了此挑战的要求。不过我已经丢失了那个版本,并且它从未针对字符数进行过优化。
House of Mirrors
Not an actual entry to the challenge, but I wrote a game based on this concept (not too long back).
It's written in Scala, open-source and available here:
It does a little bit more; deals with colors and various types of mirrors and devices, but version 0.00001 did exactly what this challenge asks. I have lost that version though and it was never optimised for character count anyway.
c (K&R) 根据 strager 的更多建议,需要 339 个字符。
我的物理学家指出,传播和反射操作是时间反转不变的,因此这个版本从目标发射光线,并检查光线是否到达激光发射器。
其余的实现非常简单,或多或少完全取自我之前的前瞻性工作。
压缩:
未压缩(ish):
没有输入验证,错误的输入可能会将其发送到无限循环。输入不大于 99 x 99 时可以正常工作。需要一个编译器来链接标准库而不包含任何标头。我想我已经完成了,strager 让我击败了相当大的距离,即使在他的帮助下。
我宁愿希望有人能展示一种更微妙的方法来完成任务。这并没有什么问题,但这并不是高深的魔法。
c (K&R) 339 necessary characters after more suggestions from strager.
The physicist in me noted that the propagation and reflection operations are time-reversal invariant, so this version, throws rays from the target and checks to see if the arrive at the laser emitter.
The rest of the implementation is very straight forward and is taken more or less exactly from my earlier, forward going effort.
Compressed:
Uncompressed(ish):
There is no input validation, and bad input can send it into an infinite loop. Works properly with input no larger than 99 by 99. Requires a compiler that will link the standard library without including any of the headers. And I think I'm done, strager has me beat by a considerable stretch, even with his help.
I'm rather hoping someone will demonstrate a more subtle way to accomplish the task. There s nothing wrong with this, but it is not deep magic.
红宝石 - 146 个字符
Ruby - 146 Chars
PostScript,359 字节
第一次尝试,还有很大的改进空间...
PostScript, 359 bytes
First attempt, lots of room for improvement...
Haskell,
395391383361339 个字符(优化)仍然使用通用状态机,而不是任何聪明的东西:
可读版本:
Haskell,
395391383361339 characters (optimized)Still uses a generic state machine, rather than anything clever:
A readable version:
我相信代码重用,我会使用您的代码之一作为 API :)。
32 个字符 \o/... wohoooo
I believe in Code Reuse, I'd use one of your code as an API :).
32 characters \o/... wohoooo
C++:388 个字符
(318 无标题)
工作原理:
首先读入所有行,然后找到激光。只要尚未找到激光箭头,以下代码就会计算为
0
,同时将水平位置分配给x
。然后我们查看找到的方向并将其存储在
i
中。i
的偶数值为上/左(“递减”),奇数值为下/右(“递增”)。根据该概念,设置d
(“方向”)和r
(“方向”)。我们用方向索引指针数组z
并将方向添加到我们得到的整数中。仅当我们击中斜杠时方向才会改变,而当我们击中反斜杠时方向保持不变。当然,当我们撞到镜子时,我们总是会改变方向(r = !r
)。C++: 388 characters
(318 without headers)
How it works:
First, all lines are read in, then, the laser is found. The following will evaluate to
0
as long as no laser arrow was found yet, and the same time assign tox
the horizontal position.Then we look what direction we found and store it in
i
. Even values ofi
are top/left ("decreasing") and odd values are bottom/right ("increasing"). According to that notion,d
("direction") andr
("orientation") are set. We index pointer arrayz
with orientation and add the direction to the integer we get. The direction changes only if we hit a slash, while it remains the same when we hit a back-slash. Of course, when we hit a mirror, then we always change orientation (r = !r
).Groovy @ 279 个字符
Groovy @ 279 characers
C#
1020 个字符。1088 个字符(从控制台添加的输入)。925 个字符(重构变量)。875 个字符(删除了多余的字典初始值设定项;更改为二进制和运算符)
在发布之前强调不要查看其他人的内容。我确信它可能会被 LINQ 提升一点。可读版本中的整个 FindLaser 方法对我来说似乎非常可疑。但是,它有效,但已经晚了:)
请注意,可读类包含一个附加方法,可以在激光移动时打印出当前的竞技场。
可读版本(不完全是最终的高尔夫版本,但前提相同):
C#
1020 characters.1088 characters (added input from console).925 characters (refactored variables).875 characters (removed redundant Dictionary initializer; changed to Binary & operators)
Made a Point not to look at anyone else's before posting. I'm sure it could be LINQ'd up a bit. And the whole FindLaser method in the readable version seems awfully fishy to me. But, it works and it's late :)
Note the readable class includes an additional method that prints out the current Arena as the laser moves around.
Readable Version (not quite the final golf version, but same premise):
Perl 219
我的 Perl 版本是
392342 个字符长(我必须处理光束击中激光的情况):更新,感谢 Hobbs 提醒我
tr//
,现在是 250 个字符:更新,删除
m//
中的m
,更改两个while
循环带来了一些节省;现在只需要一个空间。(
L:it;goto L
与do{it;redo}
的长度相同):我剃了一些,但它
几乎只是竞争其中一些,尽管已经晚了。它看起来好一点:
嗯...老实说,如果您了解
@b
是每行中的字符数组,并且可以读取简单的正则表达式和tr 语句。
Perl 219
My perl version is
392342 characters long (I had to handle the case of the beam hitting the laser):Update, thanks Hobbs for reminding me of
tr//
, it's now 250 characters:Update, removing the
m
inm//
, changing the twowhile
loops brought a few savings; there's now only one space required.(
L:it;goto L
is the same length asdo{it;redo}
):I shaved some, but it
barelyjust competes with some of these, albeit late.It looks a little better as:
Well... Honestly this should be self explanatory if you understand that the
@b
is an array arrays of characters in each line, and can read the simple regexp andtr
statements.F# - 454(或左右)
游戏有点晚了,但忍不住发布我的第二次尝试。
更新略有修改。如果发射器被击中,现在可以正确停止。扼杀了 Brian 对 IndexOfAny 的想法(遗憾的是该行是如此冗长)。我实际上还没有设法弄清楚如何让 ReadToEnd 从控制台返回,所以我相信这一点......
我对这个答案很满意,虽然它很短,但它仍然相当可读。
F# - 454 (or thereabouts)
Bit late to the game, but can't resist posting my 2d attempt.
Update modified slightly. Now stops correctly if transmitter is hit. Pinched Brian's idea for IndexOfAny (shame that line is so verbose). I haven't actually managed to work out how to get ReadToEnd to return from the Console, so I'm taking that bit on trust...
I'm pleased with this answer, as though it is quite short, it is still fairly readable.