问题描述
按字符计数的最短代码,用于输入板的2D表示形式,并根据输入内容输出"true"或"false" .
The shortest code by character count to input a 2D representation of a board, and output 'true' or 'false' according to the input.
木板由4种类型的瓷砖制成:
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.
激光射线从其起点向其指向的方向射击.如果激光束撞击墙壁,它将停止.如果激光束击中镜子,它会向镜子指向的方向反弹90度.镜子是两面的,这意味着两面都是反射性的",并且可能以两种方式反射光线.如果激光束撞击激光束(^v><
)本身,则将其视为墙(激光束会破坏光束束,因此永远不会击中目标).
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).
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).
推荐答案
Perl, 160个字符
Perl, 166-> 160个字符.
Perl, 160 characters
Perl, 166 --> 160 chars.
当比赛结束时,解决方案的笔触为166,但是A. Rex找到了几种方法来减少另外6个字符:
Solution had 166 strokes when this contest ended, but A. Rex has found a couple ways to shave off 6 more characters:
s!.!$t{$s++}=$&!ge,$s=$r+=99for<>;%d='>.^1<2v3'=~/./g;($r)=grep$d|=$d{$t{$_}},%t;
{$_=$t{$r+=(1,-99,-1,99)[$d^=3*/\\/+m</>]};/[\/\\ ]/&&redo}die/x/?true:false,$/
第一行将输入加载到板子表%t
中,其中$t{99*i+j}
将字符保存在行 i ,列 j 处.然后,
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,
%d=split//,'>.^1<2v3' ; ($r)=grep{$d|=$d{$t{$_}}}%t
它在%t
的元素中搜索与> ^ <
或v
相匹配的字符,并同时将$d
设置为介于0和3之间的值,该值指示激光束的初始方向.
it searches the elements of %t
for a character that matches > ^ <
or v
, and simultaneously sets $d
to a value between 0 and 3 that indicates the initial direction of the laser beam.
在主循环中每次迭代的开始,如果光束当前在镜子上,我们将更新$d
.对3进行XOR运算可以得到\
镜像的正确行为,对3进行XOR运算可以得到/
镜像的正确行为.
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.
$d^=3*/\\/+m</>
接下来,根据当前方向更新当前位置$r
.
Next, the current position $r
is updated accoring to the current direction.
$r+=(1,-99,-1,99)[$d] ; $_ = $t{$r}
我们将当前位置的字符分配给$_
,以方便使用匹配运算符.
We assign the character at the current position to $_
to make convenient use of the match operators.
/[\/\\ ]/ && redo
如果我们在空格或镜像字符上,请继续.否则,如果我们位于目标($_ =~ /x/
)上,则终止true
,否则终止false
.
Continue if we are on a blank space or a mirror character. Otherwise we terminate true
if we are on the target ($_ =~ /x/
) and false
otherwise.
限制:可能无法解决超过99列的问题.可以删除此限制,但要多花3个字符,
Limitation: may not work on problems with more than 99 columns. This limitation could be removed at the expense of 3 more characters,
这篇关于高尔夫代码:激光的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!