耶!藏宝图!


49

介绍

“是的!我们有个小伙子自称是“程序员”,在地图上隐藏了我们的藏宝!但是“写得很机智”这个奇怪的数字“ n个字母!”“ E5,N2,E3”……甚至还能做什么? “疯狂!!甚至没能画出合适的藏宝图,没用的克汀丁。给我们修理吧!我们会赠予您一部分宝藏!”

挑战说明

一群海盗在阅读藏宝图时遇到了麻烦。您可以编写一个程序将其转换为更多盗版形式吗?

作为输入,您将收到原始的藏宝图。这是一个用逗号分隔的字符串的列表,每个字符串包括一个字母部分(告诉海盗他们需要走的方向)和一个数字部分(告诉海盗在这个方向上要走多少步)。例如,以下藏宝图:

E2,N4,E5,S2,W1,S3

意思是“向东走两步,向北走四步,向东走五步,向南走两步,向西走一步,然后向南走三步。”

作为输出,就会输出地图图形形式,用文字>^v,和<为指针。这是上述输入的输出:

  >>>>>v
  ^    v
  ^   v<
  ^   v
>>^   X

请注意,我们已将南面的最后一步替换为X。这是因为最后一步是宝藏在哪里,众所周知,海盗的宝藏地图上必须有一个X,否则他们将不知道如何阅读。

顺便说一下,地图永远不会交叉,因此您不必担心重叠问题。另外,允许在输出末尾添加尾随新行。

样本输入和输出

S5,W2

 v
 v
 v
 v
 v
X<

N1,E1,S1,E1,N1,E1,S2

>v>v
^>^X

N1

X

N6,E6,S6,W5,N5,E4,S4,W3,N3,E2,S2,W1,N2

>>>>>>v
^>>>>vv
^^>>vvv
^^^Xvvv
^^^^<vv
^^^<<<v
^^<<<<<

E21,S2

>>>>>>>>>>>>>>>>>>>>>v
                     X

N12,E11,S12,W2,N4

>>>>>>>>>>>v
^          v
^          v
^          v
^          v
^          v
^          v
^          v
^          v
^        X v
^        ^ v
^        ^ v
^        ^<<

1
允许在每行上保留尾随空格吗?这个数字是否总是少于10?
2015年

9
我真的认为X应该标记最后一步之后的步骤,就像其他所有步骤一样。想象最后一步是N3:您向北走了三步并进行挖掘,但是这里什么也没有,您不得不走了两步。我不介意您是否保留现有规则,因为它增加了一些处理不便的情况。但是请记住那个小伙子发生了什么。
coredump

6
@coredump或也许我们想误导海盗,以便我们可以为自己夺走宝藏;)不,您是正确的,海盗们的挖掘步伐为时过早。鉴于已经有三个答案,我将保留规则,以免使现有解决方案无效。
2015年

4
@ jpmc26好吧,这些海盗不太了解字母...他们在C度过了最近几年:)
苦艾酒

4
第四个例子只是拖钓海盗……
justhalf 2015年

Answers:


8

红宝石, 213209198186 178

M={};x=0,m=q=0
gets.scan(/.(\d+)/){?1.upto($1){m,y=x
x[d=$&.ord%10%7-2]+=1|($u=M[y]||={})[m]=d
m<q&&q=m}}
$u[m]=2
puts M.sort.map{|_,b|(q..b.max[0]).map{|k|">vX <^"[b[k]||3]}*""}

通过stdin传递输入。

这使用y -> x -> char字典来构建地图,其中xy都可以为负。解析输入后,将提取x坐标的全局最小值。然后,对于每一行,它会在从全局最小值到当前行的最大索引的范围内进行迭代,并为该索引打印正确的字符。

为了与主题保持一致,NESWSp3000答案中毫不客气地盗版了将变成适当索引的表达式。

使用[x,y] -> char字典的原始版本:

M={};x=0,0
gets.scan(/.(\d+)/){(?1..$1).map{x[d=$&.ord%10%7-2]+=1|M[$y=x+[]]=d}}
M[$y]=2
a,*q=M.minmax.flatten
M.map{|(x,y),v|($*[y-M.map{|a,|a[1]}.min]||=?\s.*q[2]-a)[x-a]=">vX<^"[v]}
puts$*.map &:rstrip

20

Python 2中,249个 248 244 239 237字节

D={}
m=X=Y=0
for s in input().split(","):d=ord(s[0])%10%7;exec"a,b=X,Y;E=D[Y]=D.get(Y,{});E[X]='<^>v'[d];m=min(m,X);%c+=d-2|1;"%(88+d%2)*int(s[1:])
D[b][a]="X"
for Y in sorted(D):print"".join(D[Y].get(n," ")for n in range(m,max(D[Y])+1))

输入类似"E2,N4,E5,S2,W1,S3"

NSEW被映射到[1, 3, 2, 0]通过d=ord(c)%10%7。是要更改y还是x由决定d%2,是增加还是减少由决定d-2|1。第一和第三种表达是通过蛮力发现的。

除此之外,它是形式的嵌套字典的简单用法{y: {x: char}}

(感谢@joriki提供映射帮助)


1
(d + 1 & 2) - 1
joriki

1
@joriki啊,这是一个很好的表达-谢谢!
Sp3000

2
这是我(在不同上下文中)编写的一些代码,用于查找整数函数的简单表达式。我没有为此使用它,而是以为它可能对您很有趣。(相关代码从“它是我用来优化编码的代码”的开头开始。)
joriki 2015年

3
@joriki Brute强迫是一个好主意-出现了1|d%-3(这是一个否定,但我只是意识到也可以)!
Sp3000

14

Javascript(ES6),260

这是一个有趣的...

感谢@ ETHproductions,@ edc65和@vihan的帮助!

s=>{z=o=""
m=[]
q=x=y=2e3
s.split`,`.map(v=>z+=v[0].repeat(+v.slice(1)))
for(i=0;d=z[i];q=x<q?x:q)(m[y]=m[y]||[])[x]=z[++i]?d=="N"&&--y?"^":d=="S"&&++y?"v":d=="W"&&--x?"<":++x?">":o:"X"
m.map(a=>a.map((b,j)=>o+=" ".repeat(-p-1+(p=j))+b,p=q-1,o+=`
`))
return o}

它定义了一个匿名函数,因此可以将其添加f=到开头以为其命名。

去测试: console.log(f("E2,N4,E5,S2,W1,S3"))

说明:

s=>{ //define function w/ parameter s
z=o=""      //z=modified input, o=final output
m=[]        //map of characters
q=x=y=2e3   //q=minimum value of x; x+y=coordinates. These start high to leave room to go backwards
s.split`,`.map(v=>z+=v[0].repeat(+v.slice(1)))    //change "N3,E4" -> "NNNEEEE", and put in z
for(i=0;d=z[i];q=x<q?x:q)   //for each direction d in z, while updating q:
    (m[y]=m[y]||[])[x]=     //in the right place on the map, put:
        z[++i]?                 //if last character of z, "X"
            d=="N"&&--y?"^":    
            d=="S"&&++y?"v":    //otherwise get the right character and change x+y accordingly
            d=="W"&&--x?"<":
            ++x?">":o
        :"X"
m.map(a=>a.map((b,j)=>o+=" ".repeat(-p-1+(p=j))+b,p=q-1,o+=`
`)) //dump map to o, with correct padding
return o}   //return

3
这是分隔语句的好方法!当然,与将所有内容放在一行并用分号隔开相比,它更具可读性。如果我可以提供我的建议:在这种情况下,您可以通过将循环i++for循环移动到使用的最后一个位置来节省一个字节c=i++>r-2?"X":c
ETHproductions'Aug

1
此外,由于你使用ES6,我会建议使用v[0].repeat(+v.slice(1))到位的Array(v.slice(1)- -1).join(v[0]),并" ".repeat(j-p-1)代替Array(j-p).join(" "),节省11个字节的整体。我想你也可以放置F='forEach'在函数的开始,那么每个改变.forEach从那里来[F],节省了另一个4
ETHproductions

1
尝试使用.map而不是.forEach。太短了,您甚至不应将其缩短为F
edc65

1
@UndefinedFunction您可能想使用ifs的简写形式,如果您同时减少变量,也可能会有所帮助
Downgoat 2015年

1
如果我的理解是正确的,是否q=x=y=2e3表示如果我这样做,输出将是不正确的W9999
Sp3000

7

PHP,431个 417字节

$g=explode(',',$argv[1]);$x=$y=$a=$b=$c=$d=$e=$f=0;
foreach($g as$i=>$h){list($k,$l,$m)=
    ['N'=>[-1,0,'^'],'E'=>[0,1,'>'],'S'=>[1,0,'v'],'W'=>[0,-1,'<']][$h[0]];
    for($s=substr($h,1);$s--;){$z[$f=$y][$e=$x]=$m;$y+=$k;$x+=$l;}
    if($i==count($g)-1){$x=$e;$y=$f;}
    $a=min($a,$x);$b=max($b,$x);$c=min($c,$y);$d=max($d,$y);
}$z[$y][$x]='X';for($y=$c;$y<=$d;$y++)
{$o='';for($x=$a;$x<=$b;$x++)$o.=$z[$y][$x]?:' ';echo rtrim($o)."\n";}

将其放入文件(treasure.php),删除缩进,连接各行(为便于阅读,将其包装在此处),将<?php标记置于文件的开头(由于技术上它不是程序的一部分,因此此处未显示)。

执行示例:

$ php -d error_reporting=0 treasure.php E2,N4,E5,S2,W1,S3
  >>>>>v
  ^    v
  ^   v<
  ^   v
>>^   X
$

-d error_reporting=0需要该选项来抑制有关在中的指定索引处找不到的值的通知$z

更新:

在准备发布的非代码版本时,我发现它包含两个不需要的分配(12个字节)和一个空白,可以将其删除(as$i)。此外,通过更换while具有for环和(使用不可能挤压分配到它while循环)我保存的下一个字节。


我希望看到一个非高尔夫版本。
拉尔斯·艾伯特

1
@LarsEbert我更新了答案,并带有指向未完成代码的链接。我现在检查了您的解决方案(以前没有做过);我们基本上使用了相同的算法。您的最后一步比我的要好。如果实现,我可以再剥离25个字节$count --;
axiac

$argn保存3个字节chop保存1个字节"X"- > X使用的常量节省更多的字节
约克Hülsermann

@JörgHülsermann我没有得到$argn提示。我知道这个"X"->X窍门,但是在编写此解决方案时我可能忘记了它。我从2002年开始编写PHP代码,但直到今天我才注意到PHP提供了该chop()功能。感谢您的提示。
axiac

7

Perl中,702 613 546 474 439 338 260个字节

感谢Dom Hastings的帮助和超级高尔夫版本。
该代码使用2D数组。

Dom Hastings版本:

$x=$y=$a=$b=99;map{/^./;$a=($c=$x)<$a?$x:$a,$A=$x>$A?$x:$A,$b=($C=$y)<$b?$y:$b,$B=$y>$B?$y:$B,$q[$c][$C]={split'','W<E>N^Sv'}->{$&},$x+={W,-1,E,1}->{$&},$y+={N,-1,S,1}->{$&}for 1..$'}split',',pop;$q[$c][$C]=X;for$y($b..$B){print$q[$_][$y]||$"for$a..$A;print$/}

我的次级高尔夫版本338字节(仅供参考):

@m=split(',',pop);$x=$y=$a=$b=99;map{($d,$s)=/^(.)(.+)$/;for(1..$s){$c=$x;$C=$y;if($x<$a){$a=$x}if($x>$A){$A=$x}if($y<$b){$b=$y}if($y>$B){$B=$y}if($d eq"W"){$r="<";$x--}if($d eq"E"){$r=">";$x++}if($d eq"N"){$r="^";$y--}if($d eq"S"){$r=v;$y++}$q[$c][$C]=$r}}@m;$q[$c][$C]=X;for$y($b..$B){for$x($a..$A){$t=$q[$x][$y];print$t?$t:$"}print$/}

测试

$ perl piratemap_golf.pl E4,N3,W6,S10,W1,S1,E5,N1,W2,N6,E6,N5,W10,S1,E2
v<<<<<<<<<<
>Xv<<<<<< ^
  v     ^ ^
  v     ^ ^
  v >>>>^ ^
  v >>>>>>^
  v ^
  v ^
  v ^
  v ^
  v ^
 v< ^<<
 >>>>>^

3
如果您不使用use strict;,则不需要所有my,这将节省至少几个字节。也==eq后者要短,因为后者需要空格。
Alex A.

1
如果我没有记错的话,你只叫$m一次,因此而不是存储命令行参数作为变量,你可以直接调用它split,即@m=split(',',$ARGV[0])
Alex A.

1
嘿@LukStorms,很高兴见到更多Perl高尔夫球手!一些有助于节省一些字节的事情!可以使用regex来抓取您的$d$s变量,以为您节省一些字节($d,$s)=/^(.)(.+)$/,而所有foreachs都可以for(因为它们相同。您还可以保存一些字符,用map{... 代替其中的某些字符,}@x因为您可以忽略括号-迭代项目周围(如果必须包含其他循环,则效果很好)。如果使用$ARGV[0],可以将其替换为pop,但是如果使用脚本,则perl script.pl <<< "text"可以<>改为使用它
Dom Hastings 2015年

1
如果要使用args保留脚本,则可以使用pop来保存一对。代替use Swtichswitch/ case语句,您可以进行单个检查,这可以节省字节。诸如此类的东西$y-="N"eq$d也会起作用(因为true 1和false是'')。通常,您可以将单词作为裸词,因此$y-=N eq$d可以使用!您可以使用一些不可思议的变量来保存字节,$/is '\n'$"is ' ',但是有时,文字换行符也可以帮助保存字符。另一个(脏!)诀窍是多受让人,以节省数越多,如$a=0;$b=0;$a=$b=0
唐·黑斯廷斯

1
我保证,再多几个。我希望这是您想要的信息!在函数调用中缺少有效的方法是相当标准的更改,因此substr($_,0,1)可以substr$_,0,1。Postfix for循环,如果检查也可以像for(@c){...}vs中一样有用,...for@c但是您不能;在代码中使用它,则必须用逗号隔开(这在调用函数时并不总是有效)。在codegolf.stackexchange.com/questions/5105/…上也有很多很棒的技巧。祝好运!
唐·黑斯廷斯

5

Python 2,394字节

运行程序,然后粘贴到标准输入中,例如 "E2,N4,E5,S2,W1,S3"

m=input().split(',')
def f(x,y,h,o,s=[]):
 for c in m:
  for _ in range(int(c[1:])):
   a,b,l={'E':(1,0,'>'),'W':(-1,0,'<'),'N':(0,1,'^'),'S':(0,-1,'v')}[c[0]]
   if o:o[h-y][x]=l
   s+=[(x,y)];x+=a;y+=b
 if o:o[h-y+b][x-a]='X'
 return s
p,q=zip(*f(*[0]*4))
w,h=max(p)-min(p),max(q)-min(q)
o=[[' ']*-~w for _ in range(h+1)]
f(-min(p),-min(q),h,o)
print'\n'.join(["".join(l).rstrip()for l in o])

这不是很优化。首先,它通过输入运行以记录路径。然后,它会做一些数学运算来确定的正确起始位置和大小o。然后,它将再次运行并将的相应条目设置o为之一>v<^X。主要的聪明之处在于为这两个遍历重用相同的功能。


4

XQuery 3.0、498

declare variable $v external;let $m:=<v>{tokenize($v,',')!(for $j in(1 to xs:int(substring(.,2)))return<c>{translate(substring(.,1,1),'NESW','^>v<')}</c>)}</v>/c!(let $p:=./preceding-sibling::c return<p x="{count($p[.='>'])-count($p[.='<'])}" y="{count($p[.='v'])-count($p[.='^'])}">{if(./following::*)then .else'X'}</p>)for $y in(min(xs:int($m/@y))to max(xs:int($m/@y)))return string-join(for $x in(min(xs:int($m/@x))to max(xs:int($m/@x)))let $d:=$m[@x=$x and @y=$y]return if($d)then$d else' ','')

XQuery甚至通常都没有什么竞争力,所以这很有趣。

不打高尔夫球

declare variable $v external;
let $map := <vector>{ tokenize($v,',') ! 
        (for $j in (1 to xs:int(substring(.,2)))
            return <step>{ translate(substring(.,1,1),'NESW','^>v<') }</step> ) 
         }</vector>/step !
            (let $path_so_far := ./preceding-sibling::step
            return <point 
                x="{ count($path_so_far[.='>']) - count($path_so_far[.='<']) }" 
                y="{ count($path_so_far[.='v']) - count($path_so_far[.='^']) }">
                {if(./following::*) then string(.) else 'X'}
            </point>)
for $y in (min(xs:int($map/@y)) to max(xs:int($map/@y)))
return string-join(
    for $x in (min(xs:int($map/@x)) to max(xs:int($map/@x)))
    let $d := $map[@x=$x and @y=$y]
    return if($d) then string($d) else ' '
    ,'')

4

PHP,496 514 528

我用PHP尝试了运气,结果相当长,我仍然想发布它,只是为了好玩。

function a($c){global$a,$b;$a[$b[1]][$b[0]]=$c;}$c=explode(',',$argv[1]);$a=[];$b=[0,0];foreach($c as$d=>$e){$f=substr($e,1);if($d==count($c)-1)$f--;for($i=0;$i++<$f;){if($e[0]==N){a('^');$b[1]--;}elseif($e[0]==E){a('>');$b[0]++;}elseif($e[0]==S){a(v);$b[1]++;}else{a('<');$b[0]--;}}}a(X);$d=$e=$f=$g=0;foreach($a as$y=>$h){$f=min($f,$y);$g=max($g,$y);foreach($h as$x=>$i){$d=min($d,$x);$e=max($e,$x);}}for($y=$f;$y<=$g;$y++){for($x=$d;$x<=$e;$x++)echo isset($a[$y][$x])?$a[$y][$x]:' ';echo "
";}

不打高尔夫球

<?php

    function setInMap($char) {
        global $map, $position;
        $map[$position[1]][$position[0]] = $char;
    }

    $instructions = explode(',', $argv[1]);

    $map = [];

    $position = [0, 0];

    foreach($instructions as $index => $instruction) {
        $count = substr($instruction, 1);
        if($index === count($instructions) - 1) {
            $count--;
        }
        for($i = 0; $i < $count; $i++) {
            if($instruction[0] === 'N') {
                setInMap('^');
                $position[1]--;
            } elseif($instruction[0] === 'E') {
                setInMap('>');
                $position[0]++;
            } elseif($instruction[0] === 'S') {
                setInMap('v');
                $position[1]++;
            } else($instruction[0] === 'W') {
                setInMap('<');
                $position[0]--;
            }
        }
    }
    setInMap('X');

    $minX = $maxX = $minY = $maxY = 0;
    foreach($map as $y => $row) {
        $minY = min($minY, $y);
        $maxY = max($maxY, $y);
        foreach($row as $x => $cell) {
            $minX = min($minX, $x);
            $maxX = max($maxX, $x);
        }
    }
    for($y = $minY; $y <= $maxY; $y++) {
        for($x = $minX; $x <= $maxX; $x++) {
            if(isset($map[$y][$x])) {
                echo $map[$y][$x];
            } else {
                echo ' ';
            }
        }
        echo "\n";
    }

?>

1
可以减少很多。例如,您可以编写for(;$i++<$f;),尝试删除不必要的括号,使用未定义的常量(N)而不是字符串('N'),…
Blackhole

1
if尝试使用三进制运算符或逻辑与来代替s。另外,如果您使用PHP4.1并使用带有这些点的GET数组,也将有所帮助。
伊斯梅尔·米格尔

3

的JavaScript(ES6),244 249 274

为了清楚起见,添加了前导空格和换行符,不计入此数目,除了联接调用末尾附近的换行符是有意义的且已计数。

测试运行代码段(仅适用于ECMAScript 6,Firefox和Safari 9)

F=m=>(
  x=y=0,p=[],
  m.replace(/\w(\d+)/g,(d,z)=>{
    for(d='NWSE'.search(d[0]);
        z--&&(p=~x?~y?p:[y=0,...p]:p.map(r=>' '+r,x=0));
        p[u=y]=(w=r.slice(0,x))+'^<v>'[d]+(v=r.slice(x+1)),
        d&1?x+=d-2:y+=d-1)
      for(r=p[y]||'';!r[x];)r+=' ';
  }),
  p[u]=w+'X'+v,
  p.join`
`
)

// TEST

out=x=>O.innerHTML+=x.replace(/</g,'&lt;')+'\n'

;['S5,W2','N1,E1,S1,E1,N1,E1,S2','N1','N6,E6,S6,W5,N5,E4,S4,W3,N3,E2,S2,W1,N2','E21,S2','N12,E11,S12,W2,N4']
.forEach(a=>out(a+'\n'+F(a)+'\n'))
<pre id=O></pre>


2

C,557

main(_,a,minX,maxX,minY,maxY,x,y,v,dir,dist)char**a;char*v;{char o[998][999];for(y=0;y-998;++y){for(x=0;x-998;++x)o[y][x]=32;o[y][998]=0;}y=x=minY=minX=maxY=maxX=499;v=a[1];while(*v){dir=*v++;dist=atoi(v);while(*v&&*v!=44)v++;v+=!!*v;if(dir==78){while(dist--)o[y--][x]=94;if(y<minY)minY=y;y+=!*v;}if(dir==69){while(dist--)o[y][x++]=62;if(x>maxX)maxX=x;x-=!*v;}if(dir==83){while(dist--)o[y++][x]=86;if(y>maxY)maxY=y;y-=!*v;}if(dir==87){while(dist--)o[y][x--]=60;if(x<minX)minX=x;x+=!*v;}}o[y][x]=88;for(y=minY;y<=maxY;++y){o[y][maxX+1]=0;puts(o[y]+minX);}}

非高尔夫版本:

#include <stdio.h>

#define MAX_WIDTH 998
#define MAX_HEIGHT 998

int main(int argc, char *argv[]) {
    int minX,maxX,minY,maxY;
    int x,y;
    char output[MAX_HEIGHT][MAX_WIDTH+1];
    char *v;

    for (y=0; y<MAX_HEIGHT; ++y) {
        for (x=0; x<MAX_WIDTH; ++x) 
            output[y][x] = ' ';
        output[y][MAX_WIDTH] = 0;
    }

    x = minX = maxX = MAX_WIDTH/2;
    y = minY = maxY = MAX_HEIGHT/2;

    v = argv[1];
    while (*v) {
        char dir; int dist;
        dir = *(v++);
        dist = atoi(v);
        while (*v && *v != ',') v++;
        if (*v) v++;

        switch (dir) {
            case 'N':case 'n':
                while (dist--) output[y--][x] = '^';
                if (y < minY) minY = y;
                if (!*v) y++;
                break;
            case 'E':case 'e':
                while (dist--) output[y][x++] = '>';
                if (x > maxX) maxX = x;
                if (!*v) x--;
                break;
            case 'S':case 's':
                while (dist--) output[y++][x] = 'v';
                if (y > maxY) maxY = y;
                if (!*v) y--;
                break;
            case 'W':case 'w':
                while (dist--) output[y][x--] = '<';
                if (x < minX) minX = x;
                if (!*v) x++;
                break;
        }
    }

    output[y][x] = 'x';
    for (y = minY; y <= maxY; ++y) {
        output[y][maxX+1] = 0;
        puts(output[y]+minX);
    }

    return 0;
}

动态内存分配并不困难,但是malloc太长了,无法在代码组合中使用的标识符。我觉得应该有某种PCG.h标头可以合法地自动包含在c中打高尔夫球,只是为了缩短一些标识符。


1

Groovy,359岁

c=args[0].split(',').collect{[it[0],it[1..-1]as int]}
m=[[]]
x=y=0
d=["N":["^",0,1],"S":["v",0,-1],"E":[">",1,0],"W":["<",-1,0]]
c.each{z->(1..z[1]).each{if(x<0){m*.add(0," ");x=0};if(y<0){m.add(0,[]);y=0};m[y]=m[y]?:[];m[y][x]=d[z[0]][0];if(c.last()==z&&it==z[1])m[y][x]='X';y+=d[z[0]][2];x+=d[z[0]][1]}}
m.reverse().each{println it.collect{it?:" "}.join()}

1

普通Lisp-603

(lambda(s)(do((x 0)i(y 0)j(p 0)r(q 0)(g(mapcar(lambda(x)`(,(aref x 0),(parse-integer x :start 1)))(split-sequence:split-sequence #\, s))(cdr g))c)((not g)(setf x 0 y 0)(dolist(e(stable-sort(sort r #'<= :key #'car)#'< :key #'cadr))(dotimes(_(-(cadr e)p y))(terpri)(incf y)(setf x 0))(dotimes(_(-(car e)q x))(princ" ")(incf x))(princ(caddr e))(incf x)))(case(caar g)(#\N(setf i 0 j -1 c #\^))(#\E(setf i 1 j 0 c #\>))(#\W(setf i -1 j 0 c #\<))(#\S(setf i 0 j 1 c #\v)))(dotimes(_(-(cadar g)(if(cdr g)0 1)))(push`(,x,y,c)r)(incf x i)(incf y j))(setf q(min q x)p(min p y))(unless(cdr g)(push`(,x,y #\X)r))))

无数组实现:从上到下,从左到右打印。

  • 解析方向并将其扩展为一系列(x y char)元素:

    简单的“ N3”输入产生 ((0 0 #\^) (0 -1 #\^) (0 -2 #\X))

  • 另外,计算最小xy
  • y首先对结果跟踪进行排序,然后按x
  • 移动光标时遍历排序列表

    1. 添加换行符和空格以将当前光标移动到正确的位置
    2. 在位置x - minxy - miny,打印所需的字符

例子

(loop for input in  '("N6,E6,S6,W5,N5,E4,S4,W3,N3,E2,S2,W1,N2" 
                      "N1,E1,S1,E1,N1,E1,S2" 
                      "N12,E11,S12,W2,N4")
      do (fresh-line)
         (terpri)
      (funcall *fun* input))

结果:

>>>>>>v
^>>>>vv
^^>>vvv
^^^Xvvv
^^^^<vv
^^^<<<v
^^<<<<<

>v>v
^>^X

>>>>>>>>>>>v
^          v
^          v
^          v
^          v
^          v
^          v
^          v
^          v
^        X v
^        ^ v
^        ^ v
^        ^<<

1

CoffeeScript,303   285字节

Y=(s)->o=[];t=l=x=y=0;q='';q+=s[0]for[1..s[1..]]for s in s.split ',';q=q[..-2];(i='NWSE'.search c;(o[y]?=[])[x]='^<v>'[i];j=(i&2)-1;x+=j*(i&1);y+=j*(!(i&1));y<t&&t=y;x<l&&l=x)for c in q;(o[y]?=[])[x]='X';((o[y][x]||' 'for x in[l...o[y].length]).join ''for y in[t...o.length]).join '\n'

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.