Yarr! Un mapa del tesoro escondido!

49

Introducción

"¡Yarr! ¡Tuvimos un muchacho que se hacía llamar" programador "para hacer un mapa de nuestro tesoro escondido! ¡Pero está escrito con números y letras extraños!" E5, N2, E3 "... ¿qué hace? "¡Locura! ¡Ni siquiera puedo escribir un mapa del tesoro apropiado, cretino inútil. ¡Arreglalo para nosotros! ¡Te regalaremos una parte del tesoro!"

Descripción del desafío

Un grupo de piratas tiene problemas para leer un mapa del tesoro. ¿Puedes escribir un programa para convertirlo en una forma más ... de piratería?

Como entrada, recibirá el mapa del tesoro original. Es una lista de cadenas separadas por comas, cada cadena que consiste en una porción de letra (que le dice a los piratas en qué dirección deben caminar), y una porción de número (que les dice a los piratas cuántos pasos deben tomar en esa dirección). Por ejemplo, el siguiente mapa del tesoro:

E2,N4,E5,S2,W1,S3

significaría: "camina dos pasos hacia el este, camina cuatro pasos hacia el norte, camina cinco pasos hacia el este, camina dos pasos hacia el sur, camina un paso hacia el oeste, luego camina tres pasos hacia el sur".

Como salida, tendrá salida el mapa en una forma gráfica, el uso de los caracteres >, ^, v, y <como punteros. Aquí está la salida para la entrada anterior:

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

Tenga en cuenta que hemos reemplazado el último paso hacia el sur con un Xlugar. Esto se debe a que el último paso es donde está el tesoro, y como todos sabemos, los piratas deben tener una X en sus mapas del tesoro, de lo contrario no sabrán cómo leerlo.

Por cierto, el mapa nunca se cruzará, por lo que no debe preocuparse por las superposiciones. Además, puede tener una nueva línea final al final de la salida.

Entradas y salidas de muestra

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
^        ^<<
Ajenjo
fuente
1
¿Se nos permite tener espacios finales en cada línea? ¿El número siempre será menor que diez?
Downgoat
99
Realmente creo que Xdebería marcar el paso después del último movimiento, como todos los demás movimientos se cuentan. Imagina que el último paso es N3: caminas tres pasos hacia el norte y cavas, pero no hay nada aquí, tuviste que caminar 2 pasos en su lugar. No me importa si mantienes la regla existente, porque agrega un pequeño caso de esquina para manejar. Pero recuerda lo que le pasó a ese muchacho.
coredump
66
@coredump O tal vez queremos engañar a los piratas, para que podamos tomar el tesoro por nosotros mismos;) No, tienes razón, los piratas están cavando un paso demasiado pronto. Dado que ya hay tres respuestas, mantendré la regla tal como es para evitar invalidar las soluciones existentes.
Absenta
44
@ jpmc26 Bueno, estos piratas no saben mucho del alfabeto ... pasaron los últimos años en C :)
absenta
44
El cuarto ejemplo es solo trollear a los piratas ...
solo el

Respuestas:

8

Rubí, 213 209 198 186 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]}*""}

Pase la entrada a través de stdin.

Este utiliza un y -> x -> chardiccionario para construir el mapa, donde ambos xy ypuede ser negativo. Una vez que se ha analizado la entrada, se extrae el mínimo global de la coordenada x. Para cada fila, itera sobre un rango que va desde el índice mínimo global al índice máximo para la línea actual e imprime el carácter correcto para ese índice.

Para mantenerse con el tema, las expresiones que se convierten NESWen los índices apropiados fueron pirateados sin pudor de SP3000 's respuesta .

Versión original que usaba un [x,y] -> chardiccionario:

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
Ventero
fuente
20

Python 2, 249 248 244 239 237 bytes

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))

Entrada como "E2,N4,E5,S2,W1,S3".

NSEWestá mapeado [1, 3, 2, 0]por d=ord(c)%10%7. Si se cambia yo xluego se decide por d%2, y si se incrementa o disminuye d-2|1. La primera y tercera expresiones fueron encontradas por la fuerza bruta.

Aparte de eso, es un uso simple de un diccionario anidado de la forma {y: {x: char}}.

(Gracias a @joriki por la ayuda con el mapeo)

Sp3000
fuente
1
(d + 1 & 2) - 1
joriki
1
@joriki Ah, esa es una buena expresión, ¡gracias!
Sp3000
2
Aquí hay un código que escribí (en un contexto diferente) para encontrar expresiones simples para funciones enteras. No lo usé para esto, pero pensé que podría ser interesante para ti. (El código relevante comienza donde dice "Este es el código que utilicé para optimizar la codificación".)
joriki
3
@joriki Brute forcing es una gran idea: ¡acabo de aparecer 1|d%-3(que es la negación, pero me di cuenta de que también está bien)!
Sp3000
14

Javascript (ES6), 260

Esta fue una interesante ...

¡Gracias @ETHproductions, @ edc65 y @vihan por la ayuda!

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}

Esto define una función anónima, por lo que para llamarla agregue f=al principio para darle un nombre.

Probar: console.log(f("E2,N4,E5,S2,W1,S3"))

Explicación:

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
jrich
fuente
3
¡Esa es una buena manera de separar las declaraciones! Sin duda, es mucho más legible que poner todo en una línea y separarlos con punto y coma. Si puedo ofrecer mi sugerencia: puede guardar un byte moviendo su i++del forbucle al último lugar donde se usa, en este caso c=i++>r-2?"X":c.
ETHproductions
1
Además, dado que está utilizando ES6, sugeriría usar v[0].repeat(+v.slice(1))en lugar de Array(v.slice(1)- -1).join(v[0]), y " ".repeat(j-p-1)en lugar de Array(j-p).join(" "), guardar 11 bytes en general. Creo que también podría colocar F='forEach'al comienzo de la función, luego cambiar cada uno .forEachde allí en adelante [F], guardando otros 4.
ETHproductions
1
Intente usar .map en lugar de .forEach. Es tan corto que ni siquiera debería acortarlo a F
edc65
1
@UndefinedFunction es posible que desee usar shorthands para la ifs, podría ayudar si disminuye las variables al mismo tiempo también
Downgoat
1
Si mi comprensión es correcta, ¿ q=x=y=2e3significa que la salida sería incorrecta si lo hiciera, por ejemplo W9999?
Sp3000
7

PHP, 431 417 bytes

$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";}

Póngalo en un archivo ( treasure.php), elimine la sangría, una las líneas (está envuelto aquí para facilitar la lectura), coloque el <?phpmarcador al comienzo del archivo (no se muestra aquí, ya que técnicamente no forma parte del programa).

Ejemplo de ejecución:

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

La opción -d error_reporting=0es necesaria para suprimir avisos sobre valores no encontrados en índices especificados en $z.

Actualizar:

Mientras preparaba la versión no codificada del código para publicar, descubrí que contenía dos asignaciones innecesarias (12 bytes) y un espacio en blanco que se puede eliminar ( as$i); Además, al reemplazar a whilecon un forbucle y apretar una asignación en él (no es posible usar el whilebucle) guardé otro byte.

axiac
fuente
Me encantaría ver una versión sin golf.
Lars Ebert
1
@LarsEbert Actualicé la respuesta con un enlace al código no protegido. Verifiqué tu solución ahora (no lo hice antes); Básicamente hemos utilizado el mismo algoritmo. El tuyo maneja el último paso mejor que el mío. Puedo eliminar 25 bytes más si lo implemento $count --;.
axiac
$argnguardar 3 bytes chopguardar 1 byte "X"-> Xusar constantes guardar más bytes
Jörg Hülsermann
@ JörgHülsermann No entiendo la $argnpista. Soy consciente del "X"->Xtruco, pero probablemente lo olvidé cuando escribí esta solución. Escribo código PHP desde 2002 pero hasta hoy no noté que PHP proporciona la chop()función. Gracias por esta pista.
axiac
7

Perl, 702 613 546 474 439 338 260 bytes

Gracias a Dom Hastings por su ayuda y su versión supergolf.
El código usa una matriz 2D.

Versión de 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$/}

Mi versión de golf menor de 338 bytes (para referencia):

@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$/}

Prueba

$ 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< ^<<
 >>>>>^
LukStorms
fuente
3
Si no está utilizando use strict;, no necesita todos los mys, lo que le ahorrará al menos unos pocos bytes. También ==es más corto que eqya que este último requiere espacios.
Alex A.
1
Si no me equivoco, solo está llamando $muna vez, por lo que en lugar de almacenar el argumento de la línea de comando como una variable, puede llamarlo directamente split, es decir @m=split(',',$ARGV[0]).
Alex A.
1
¡Hola @LukStorms, me alegra ver más golfistas de Perl! ¡Algunas cosas para ayudar a ahorrar algunos bytes! Sus variables $dy $sse pueden capturar usando regex para ahorrarle algunos bytes ($d,$s)=/^(.)(.+)$/, y todas las foreachs pueden ser for(ya que son lo mismo. También podría guardar algunos caracteres reemplazando algunos de estos con map{... }@xya que puede ignorar los parens alrededor del elemento iterado (esto funciona bien si tiene que contener otros bucles). Si lo está usando $ARGV[0], puede reemplazarlo con pop, ¡pero si usa el script como perl script.pl <<< "text"puede usarlo <>!
Dom Hastings
1
Si desea mantener el script usando args, puede usarlo poppara guardar un par. En lugar de use Swtichy las declaraciones switch/ case, podría hacer comprobaciones individuales que podrían ahorrarle bytes. Algo así $y-="N"eq$dfuncionará también (ya que verdadero 1y falso es ''). A menudo, puedes tener palabras como palabras simples, ¡así $y-=N eq$dque funcionará! Hay algunas variables mágicas que puede usar para guardar bytes, $/es '\n'y $"es ' ', pero a veces una nueva línea literal también puede ayudar a salvar un carácter. Otro truco (¡sucio!) Son las asignaciones múltiples para guardar algunas más, como $a=0;$b=0;puede ser $a=$b=0.
Dom Hastings
1
Solo unos pocos más, lo prometo. ¡Espero que esta sea la información que buscas! Perder a los padres en las llamadas a funciones es un cambio bastante estándar, por lo que substr($_,0,1)puede serlo substr$_,0,1. Postfix para bucles y si las comprobaciones pueden ser útiles también como en for(@c){...}vs. ...for@cpero no puede usar ;en el código, tendría que separar las comas en su lugar (que no siempre funciona cuando se llaman funciones). También hay muchos consejos excelentes en codegolf.stackexchange.com/questions/5105/… . ¡Buena suerte!
Dom Hastings
5

Python 2, 394 bytes

Ejecute el programa y luego péguelo en la entrada estándar como, por ejemplo, "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])

Esto no está muy optimizado. Primero se ejecuta a través de la entrada para registrar la ruta. Luego hace algunos cálculos para determinar la posición inicial correcta y el tamaño de o. Luego se ejecuta nuevamente y establece las entradas apropiadas de ocomo una de >v<^X. La inteligencia principal está en reutilizar la misma función para estos dos recorridos.

Alex L
fuente
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 a menudo no es ni siquiera un poco competitivo, por lo que fue divertido.

Sin golf

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 ' '
    ,'')
Kniffler
fuente
4

PHP, 496 514 528

Probé mi suerte en PHP, el resultado es bastante largo, todavía quiero publicarlo, solo por diversión.

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 "
";}

Sin golf

<?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";
    }

?>
Lars Ebert
fuente
1
Se puede reducir mucho. Por ejemplo, puede escribir for(;$i++<$f;), tratar de eliminar corchetes innecesarios, usar constantes indefinidas ( N) en lugar de cadenas ( 'N'), ...
Blackhole
1
En lugar de ifs, intente usar operadores trenarios o lógicos ands. Además, ayudará si usa PHP4.1 y usa una matriz GET con los puntos.
Ismael Miguel
3

JavaScript (ES6), 244249274

Los espacios iniciales y las nuevas líneas se agregaron para mayor claridad y no se contaron, excepto la nueva línea cerca del final en la llamada de unión, que es significativa y contada.

Pruebe a ejecutar el fragmento (solo ECMAScript 6, Firefox y 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>

edc65
fuente
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);}}

Versión sin golf:

#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;
}

La asignación de memoria dinámica no es mucho más difícil, pero malloc es un identificador demasiado largo para ser utilizado en el código de golf. Siento que debería haber algún tipo de encabezado PCG.h legalmente incluido automáticamente para jugar golf en c, solo para acortar algunos identificadores.

LambdaBeta
fuente
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()}
dbramwell
fuente
1

Lisp común - 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))))

Implementación sin matrices: imprime de arriba a abajo, de izquierda a derecha.

  • Analiza y expande direcciones en un rastro de (x y char)elementos:

    La simple entrada "N3" produce ((0 0 #\^) (0 -1 #\^) (0 -2 #\X))

  • Además, calcule el mínimo xyy
  • Ordene la traza resultante por yprimero y luego porx
  • Iterar sobre la lista ordenada mientras mueve el cursor

    1. Agregue nuevas líneas y espacios para mover el cursor actual a la posición correcta
    2. Cuando en la posición x - minx, y - miny, imprimir el carácter deseado

Ejemplos

(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))

Resultado:

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

>v>v
^>^X

>>>>>>>>>>>v
^          v
^          v
^          v
^          v
^          v
^          v
^          v
^          v
^        X v
^        ^ v
^        ^ v
^        ^<<
volcado de memoria
fuente
1

CoffeeScript, 303   285 bytes

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'

metalim
fuente