Yarr! Una mappa per il tesoro nascosto!


49

introduzione

"Yarr !! Avevamo un ragazzo che si definiva un" programmatore "per creare una mappa del nostro tesoro nascosto! Ma è scritto con strani numeri e lettere!" E5, N2, E3 "... che cosa fa anche Voglio dire? Follia! Non riesco nemmeno a scrivere una vera e propria mappa del tesoro, il cretino inutile. Risolvilo per noi! Ti regaleremo una parte del tesoro! "

Descrizione della sfida

Un gruppo di pirati ha difficoltà a leggere una mappa del tesoro. Puoi scrivere un programma per convertirlo in una forma più ... pirata?

Come input, riceverai la mappa del tesoro originale. È un elenco di stringhe separate da virgola, ciascuna stringa che consiste in una porzione di lettere (che indica ai pirati in quale direzione devono camminare) e una porzione numerica (che indica ai pirati quanti passi intraprendere in quella direzione). Ad esempio, la seguente mappa del tesoro:

E2,N4,E5,S2,W1,S3

significherebbe: "cammina due passi verso est, cammina quattro passi verso nord, cammina cinque passi verso est, cammina due passi verso sud, cammina un passo verso ovest, quindi cammina tre passi verso sud".

Come uscita, ti uscita la mappa in una forma grafica, utilizzando i caratteri >, ^, v, e <come puntatori. Ecco l'output per l'input sopra:

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

Si noti che abbiamo sostituito l'ultimo passaggio a sud con un Xinvece. Questo perché l'ultimo passaggio è dove si trova il tesoro, e come tutti sappiamo, i pirati devono avere una X sulle loro mappe del tesoro, altrimenti non sapranno come leggerlo.

A proposito, la mappa non si attraverserà mai, quindi non devi preoccuparti di affrontare le sovrapposizioni. Inoltre, è consentito avere una nuova riga finale alla fine dell'output.

Ingressi e uscite di esempio

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
Ci è permesso avere spazi finali su ogni riga? Il numero sarà sempre inferiore a dieci?
Downgoat,

9
Penso davvero che Xdovrebbe segnare il passo dopo l'ultima mossa, come tutte le altre mosse sono conteggiate. Immagina che l'ultimo passo sia N3: cammini tre passi verso nord e scavi, ma qui non c'è nulla, invece devi camminare 2 passi. Non mi importa se mantieni la regola esistente, perché aggiunge un piccolo caso angolare da gestire. Ma ricorda cosa è successo a quel ragazzo.
coredump,

6
@coredump O forse vogliamo fuorviare i pirati, in modo che possiamo prendere il tesoro per noi stessi;) No, hai ragione, i pirati stanno scavando un passo troppo presto. Dato che ci sono già tre risposte, manterrò la regola per evitare di invalidare le soluzioni esistenti.
assenzio il

4
@ jpmc26 Beh, questi pirati non conoscono molto l'alfabeto ... hanno trascorso gli ultimi anni a C :)
assenzio

4
Il quarto esempio è solo la pesca a traina dei pirati ...
solo l'

Risposte:


8

Rubino, 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]}*""}

Passa input tramite stdin.

Questo utilizza un y -> x -> chardizionario per costruire la mappa, dove entrambi xe ypossono essere negativi. Una volta analizzato l'input, viene estratto il minimo globale della coordinata x. Per ogni riga, quindi scorre su un intervallo che va dal minimo globale al massimo indice per la riga corrente e stampa il carattere corretto per tale indice.

Per rimanere con il tema, le espressioni di trasformare NESWin indici corretti sono stati spudoratamente usurpative SP3000 's risposta .

Versione originale che utilizzava un [x,y] -> chardizionario:

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 byte

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

Inserisci come "E2,N4,E5,S2,W1,S3".

NSEWè mappato [1, 3, 2, 0]da d=ord(c)%10%7. Se si decide di cambiare yo xviene deciso da d%2e se si decide di aumentare o diminuire d-2|1. La prima e la terza espressione sono state trovate con la forza bruta.

Oltre a ciò, è un semplice utilizzo di un dizionario nidificato del modulo {y: {x: char}}.

(Grazie a @joriki per l'aiuto con la mappatura)


1
(d + 1 & 2) - 1
Joriki,

1
@joriki Ah, questa è una bella espressione - grazie!
Sp3000,

2
Ecco un po 'di codice che ho scritto (in un contesto diverso) per trovare espressioni semplici per funzioni intere. Non l'ho usato per questo, ma ho pensato che potesse essere interessante per te. (Il codice pertinente inizia dove dice "Questo è il codice che ho usato per ottimizzare la codifica".)
Joriki,

3
@joriki Il forzante del bruto è una grande idea - è appena arrivato 1|d%-3(che è la negazione, ma ho appena capito che va bene lo stesso)!
Sp3000,

14

Javascript (ES6), 260

Questo è stato interessante ...

Grazie @ETHproductions, @ edc65 e @vihan per l'aiuto!

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}

Questo definisce una funzione anonima, quindi per chiamarla aggiungere f=all'inizio per dargli un nome.

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

Spiegazione:

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
È un bel modo di separare le dichiarazioni! È certamente molto più leggibile che mettere tutto su una riga e separarli con punti e virgola. Se posso offrire il mio suggerimento: potresti salvare un byte spostando il tuo i++dal forciclo all'ultimo posto in cui è usato, in questo caso c=i++>r-2?"X":c.
ETHproductions

1
Inoltre, dal momento che stai usando ES6, ti suggerirei di utilizzare v[0].repeat(+v.slice(1))al posto di Array(v.slice(1)- -1).join(v[0]), e " ".repeat(j-p-1)al posto di Array(j-p).join(" "), risparmiando 11 byte complessivi. Penso che potresti anche posizionare F='forEach'all'inizio della funzione, quindi cambiare ciascuno .forEachda lì in poi [F], salvandone un altro 4.
ETHproductions

1
Prova a utilizzare .map anziché .forEach. È così corto che non dovresti nemmeno accorciarlo a F
edc65

1
@UndefinedFunction potresti voler usare shorthands per la ifs, potrebbe aiutare se decrementi anche le variabili allo stesso tempo
Downgoat

1
Se la mia comprensione è corretta, q=x=y=2e3significa che l'output sarebbe errato se lo facessi, diciamo W9999?
Sp3000,

7

PHP, 431 417 byte

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

Inseriscilo in un file ( treasure.php), rimuovi il rientro, unisci le linee (è racchiuso qui per leggibilità), metti il <?phpmarcatore all'inizio del file (non visualizzato qui perché tecnicamente non fa parte del programma).

Esempio di esecuzione:

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

L'opzione -d error_reporting=0è necessaria per sopprimere gli avvisi sui valori non trovati negli indici specificati in $z.

Aggiornare:

Mentre stavo preparando la versione non modificata del codice per la pubblicazione, ho scoperto che conteneva due assegnazioni non necessarie (12 byte) e uno spazio bianco che può essere rimosso ( as$i); inoltre, sostituendo a whilecon un forloop e comprimendo un compito in esso (non possibile utilizzando il whileloop) ho salvato un altro byte.


Mi piacerebbe vedere una versione non giocata.
Lars Ebert,

1
@LarsEbert Ho aggiornato la risposta con un link al codice non salvato. Ho verificato la tua soluzione ora (non l'ho mai fatto prima); abbiamo praticamente usato lo stesso algoritmo. Il tuo gestisce l'ultimo passo meglio del mio. Posso rimuovere altri 25 byte se implemento $count --;.
axiac,

$argnsalva 3 byte chopsalva 1 byte "X"-> Xusa costanti salva più byte
Jörg Hülsermann

@ JörgHülsermann Non capisco il $argnsuggerimento. Sono a conoscenza del "X"->Xtrucco, ma probabilmente me ne sono dimenticato quando ho scritto questa soluzione. Scrivo codice PHP dal 2002 ma fino ad oggi non ho notato che PHP fornisce la chop()funzione. Grazie per questo suggerimento.
axiac,

7

Perl, 702 613 546 474 439 338 260 byte

Grazie a Dom Hastings per il suo aiuto e la sua versione supergolfata.
Il codice utilizza un array 2D.

Versione di 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$/}

La mia versione da golf minore di 338 byte (per riferimento):

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

Test

$ 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
Se non stai usando use strict;, non hai bisogno di tutti i messaggi di posta myelettronica, che ti faranno risparmiare almeno qualche byte. Inoltre ==è più breve rispetto a eqquando quest'ultimo richiede spazi.
Alex A.

1
Se non sbaglio, stai chiamando solo $muna volta, quindi piuttosto che memorizzare l'argomento della riga di comando come variabile, puoi chiamarlo direttamente in split, cioè @m=split(',',$ARGV[0]).
Alex A.

1
Ehi @LukStorms, felice di vedere più giocatori di golf Perl! Alcune cose per aiutare a salvare alcuni byte! Your $de $svariabili possono essere catturati usando regex per salvarti alcuni byte ($d,$s)=/^(.)(.+)$/, e tutti foreachpossono essere for(come sono gli stessi. Potresti anche essere in grado di salvare alcuni caratteri sostituendone alcuni con map{... }@xdato che puoi ignorare le parentesi intorno all'elemento iterato (funziona bene se devi contenere altri loop). Se stai usando $ARGV[0]puoi sostituirlo con pop, ma se usi lo script come in perl script.pl <<< "text"puoi <>invece usare !
Dom Hastings

1
Se vuoi mantenere lo script usando args, puoi usarlo popper salvarne un paio. Invece di use Swtiche le istruzioni switch/ case, è possibile eseguire controlli individuali che potrebbero farti risparmiare byte. Qualcosa del genere $y-="N"eq$dfunzionerà anche (dal momento che vero 1e falso è ''). Spesso, puoi avere parole come parole d'ordine, quindi $y-=N eq$dfunzionerà! Ci sono alcune variabili magiche che puoi usare per salvare byte, $/è '\n'ed $"è ' ', ma a volte una nuova riga letterale potrebbe aiutare a salvare anche un carattere. Un altro trucco (sporco!) È più assegnazioni per salvare un po 'di più, come in $a=0;$b=0;può essere $a=$b=0.
Dom Hastings,

1
Solo qualche altro, lo prometto. Spero che questa sia l'informazione che stai cercando! Perdere parentesi sulle chiamate di funzione è una modifica piuttosto standard, quindi substr($_,0,1)può esserlo substr$_,0,1. Postfix per i loop e se i controlli possono essere utili anche come in for(@c){...}vs. ...for@cma non è possibile utilizzare ;nel codice, dovresti invece separare le virgole (che non funziona sempre quando chiami funzioni). Ci sono così tanti ottimi consigli anche su codegolf.stackexchange.com/questions/5105/… . In bocca al lupo!
Dom Hastings,

5

Python 2, 394 byte

Esegui il programma quindi incollalo nello standard input come ad es "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])

Questo non è molto ottimizzato. Prima scorre attraverso l'input per registrare il percorso. Quindi fa un po 'di matematica per determinare la giusta posizione iniziale e la dimensione di o. Quindi scorre di nuovo e imposta le voci appropriate di ocome una delle >v<^X. La principale intelligenza sta nel riutilizzare la stessa funzione per entrambi questi attraversamenti.


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 non è spesso nemmeno leggermente competitivo, quindi è stato divertente.

Ungolfed

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

Ho tentato la fortuna in PHP, il risultato è piuttosto lungo, voglio ancora pubblicarlo, solo per divertimento.

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

Ungolfed

<?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
Può essere ridotto molto. Ad esempio, puoi semplicemente scrivere for(;$i++<$f;), provare a rimuovere parentesi non necessarie, utilizzare costanti indefinite ( N) invece di stringhe ( 'N'), ...
Blackhole

1
Invece di ifs, prova a usare operatori trenari o e logici. Inoltre, sarà d'aiuto se usi PHP4.1 e usi un array GET con i punti.
Ismael Miguel,

3

JavaScript (ES6), 244 249 274

Spazi iniziali e newline aggiunti per chiarezza e non conteggiati, tranne la newline vicino alla fine nella chiamata di join, che è significativo e conteggiato.

Test di esecuzione dello snippet (solo ECMAScript 6, Firefox e 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);}}

Versione non golfata:

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

L'allocazione dinamica della memoria non è molto più difficile, ma malloc è un identificatore troppo lungo per essere utilizzato nel code golf. Sento che dovrebbe esserci una specie di intestazione PCG.h legalmente inclusa automaticamente per giocare a golf in c, solo per mettere in cortocircuito alcuni identificatori.


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

Implementazione senza array: stampa dall'alto verso il basso, da sinistra a destra.

  • Analizza ed espande le direzioni in una traccia di (x y char)elementi:

    Il semplice input "N3" produce ((0 0 #\^) (0 -1 #\^) (0 -2 #\X))

  • Inoltre, calcola il minimo xey
  • Ordina la traccia risultante per yprima e poi perx
  • Scorrere l'elenco ordinato mentre si sposta il cursore

    1. Aggiungi nuove righe e spazi per spostare il cursore corrente nella posizione corretta
    2. Quando in posizione x - minx, y - miny, stampare il carattere desiderato

Esempi

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

Risultato:

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

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'

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.