Yarr! Peta ke harta karun!

49

pengantar

"Yarr !! Kami punya seorang laddie yang menyebut dirinya seorang" programmer "membuat peta untuk 'harta karun kami! Tapi' ini ditulis dengan 'angka-angka aneh' n huruf!" E5, N2, E3 "... apa bahkan maksudnya? Kegilaan! Bahkan tidak bisa menulis peta harta karun yang tepat, tidak berguna, perbaiki itu untuk kita! Kami akan menghadiahkan bagimu bagian dari harta karun! "

Deskripsi Tantangan

Sekelompok perompak mengalami kesulitan membaca peta harta karun. Bisakah Anda menulis program untuk mengubahnya menjadi lebih ... bentuk bajak laut?

Sebagai masukan, Anda akan menerima peta harta karun asli. Ini adalah daftar string yang dipisahkan koma, setiap string yang terdiri dari bagian huruf (yang memberi tahu bajak laut ke arah mana mereka harus berjalan), dan sebagian nomor (yang memberi tahu bajak laut berapa banyak langkah yang harus diambil ke arah itu). Misalnya, peta harta karun berikut:

E2,N4,E5,S2,W1,S3

berarti, "berjalan dua langkah ke timur, berjalan empat langkah ke utara, berjalan lima langkah ke timur, berjalan dua langkah ke selatan, berjalan satu langkah ke barat, lalu berjalan tiga langkah ke selatan."

Sebagai output, Anda akan keluaran peta dalam bentuk grafik, menggunakan karakter >, ^, v, dan <sebagai pointer. Inilah output untuk input di atas:

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

Perhatikan bahwa kami telah mengganti langkah terakhir ke selatan sebagai Xgantinya. Ini karena langkah terakhir adalah di mana harta karun itu, dan seperti yang kita semua tahu, bajak laut harus memiliki tanda X di peta harta karun mereka, kalau tidak mereka tidak akan tahu cara membacanya.

Ngomong-ngomong, peta tidak akan pernah menyeberang sendiri, jadi Anda tidak perlu khawatir berurusan dengan tumpang tindih. Juga, Anda diizinkan untuk memiliki garis baru di akhir output.

Input dan Output Sampel

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
^        ^<<
Absinth
sumber
1
Apakah kami diizinkan memiliki spasi tambahan di setiap baris? Apakah angkanya selalu kurang dari sepuluh?
Downgoat
9
Saya benar-benar berpikir Xharus menandai langkah setelah langkah terakhir, seperti semua gerakan lainnya dihitung. Bayangkan langkah terakhir adalah N3: Anda berjalan tiga langkah ke utara dan menggali, tetapi tidak ada di sini, Anda harus berjalan 2 langkah sebagai gantinya. Saya tidak keberatan jika Anda mematuhi aturan yang ada, karena menambahkan sedikit kasus sudut untuk menangani. Tapi ingat apa yang terjadi pada anak itu.
coredump
6
@coredump Atau mungkin kita ingin menyesatkan para perompak, sehingga kita dapat mengambil harta untuk diri kita sendiri;) Tidak, Anda benar, para perompak menggali satu langkah terlalu cepat. Mengingat sudah ada tiga jawaban, saya akan menaati aturan itu untuk menghindari membatalkan solusi yang ada.
absinthe
4
@ jpmc26 Nah, bajak laut ini tidak tahu banyak tentang alfabet ... mereka menghabiskan beberapa tahun terakhir di C :)
absinthe
4
Contoh keempat hanya mengendalikan para perompak ...
justhalf

Jawaban:

8

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

Masukan input melalui stdin.

Ini menggunakan y -> x -> charkamus untuk membuat peta, di mana keduanya xdan ybisa negatif. Setelah input diuraikan, minimum global koordinat x diekstraksi. Untuk setiap baris, itu kemudian beralih pada rentang dari global minimum ke indeks maksimum untuk baris saat ini, dan mencetak karakter yang benar untuk indeks itu.

Untuk tetap dengan tema, ekspresi untuk mengubah NESWke dalam indeks yang tepat yang tanpa malu-malu bajakan dari Sp3000 's jawaban .

Versi asli yang menggunakan [x,y] -> charkamus:

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

Masukan seperti "E2,N4,E5,S2,W1,S3".

NSEWdipetakan [1, 3, 2, 0]oleh d=ord(c)%10%7. Apakah akan berubah yatau xdiputuskan oleh d%2, dan apakah kenaikan atau penurunan diputuskan oleh d-2|1. Ekspresi pertama dan ketiga ditemukan oleh brute force.

Selain itu, ini adalah penggunaan sederhana kamus bersarang formulir {y: {x: char}}.

(Terima kasih kepada @joriki untuk bantuan pemetaan)

Sp3000
sumber
1
(d + 1 & 2) - 1
joriki
1
@joriki Ah itu ekspresi yang bagus - terima kasih!
Sp3000
2
Berikut adalah beberapa kode yang saya tulis (dalam konteks yang berbeda) untuk menemukan ekspresi sederhana untuk fungsi integer. Saya tidak menggunakannya untuk ini, tetapi hanya berpikir bahwa itu mungkin menarik untuk Anda. (Kode yang relevan dimulai di mana ia mengatakan "Ini adalah kode yang saya gunakan untuk mengoptimalkan pengkodean".)
joriki
3
@joriki Brute memaksakan ide bagus - baru saja muncul 1|d%-3(yang merupakan negasi, tapi saya baru sadar itu juga oke)!
Sp3000
14

Javascript (ES6), 260

Ini yang menarik ...

Terima kasih @ETHproductions, @ edc65, dan @vihan atas bantuannya!

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}

Ini mendefinisikan fungsi anonim, jadi menyebutnya menambahkan f=ke awal untuk memberinya nama.

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

Penjelasan:

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
sumber
3
Itu cara yang bagus untuk memisahkan pernyataan! Ini tentu jauh lebih mudah dibaca daripada meletakkan segala sesuatu pada satu baris dan memisahkannya dengan titik koma. Jika saya dapat menawarkan saran saya: Anda dapat menyimpan byte dengan memindahkan Anda i++dari forloop ke tempat terakhir yang digunakan, dalam hal ini c=i++>r-2?"X":c.
ETHproduk
1
Juga, karena Anda menggunakan ES6, saya sarankan menggunakan v[0].repeat(+v.slice(1))di tempat Array(v.slice(1)- -1).join(v[0]), dan " ".repeat(j-p-1)di tempat Array(j-p).join(" "), menghemat 11 byte secara keseluruhan. Saya pikir Anda juga bisa menempatkannya F='forEach'di awal fungsi, kemudian mengubah masing-masing .forEachdari sana ke [F], menyimpan 4. lainnya
ETHproduksi
1
Coba gunakan .map alih-alih .forEach. Ini sangat singkat sehingga Anda bahkan tidak boleh mempersingkatnya menjadi F
edc65
1
@UndefinedFungsi Anda mungkin ingin menggunakan singkatan untuk ifs, mungkin membantu jika Anda mengurangi variabel pada saat yang sama juga
Downgoat
1
Jika pemahaman saya benar, apakah ini q=x=y=2e3berarti output akan salah jika saya lakukan, katakanlah 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";}

Masukkan ke dalam file ( treasure.php), hapus lekukan, gabungkan baris (dibungkus di sini agar mudah dibaca), letakkan <?phppenanda di awal file (tidak ditampilkan di sini karena secara teknis bukan bagian dari program).

Contoh eksekusi:

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

Opsi -d error_reporting=0diperlukan untuk menekan pemberitahuan tentang nilai yang tidak ditemukan pada indeks yang ditentukan di $z.

Memperbarui:

Ketika saya sedang mempersiapkan versi kode untuk posting yang tidak diklik, saya menemukan kode itu berisi dua tugas yang tidak dibutuhkan (12 byte) dan spasi putih yang dapat dihapus ( as$i); juga, dengan mengganti whiledengan forloop dan memeras tugas ke dalamnya (tidak mungkin menggunakan whileloop) saya menyimpan byte lain.

aksioma
sumber
Saya akan senang melihat versi tanpa ungolfed.
Lars Ebert
1
@ LarsEbert Saya memperbarui jawabannya dengan tautan ke kode ungolfed. Saya memeriksa solusi Anda sekarang (tidak melakukannya sebelumnya); pada dasarnya kami menggunakan algoritma yang sama. Anda menangani langkah terakhir lebih baik dari saya. Saya bisa menghapus 25 byte lebih banyak jika saya terapkan $count --;.
aksioma
$argnsave 3 Bytes chopsave 1 Byte "X"-> Xuse constants save more bytes
Jörg Hülsermann
@ JörgHülsermann Saya tidak mendapatkan $argnpetunjuk. Saya menyadari "X"->Xtriknya tetapi saya mungkin lupa tentangnya ketika saya menulis solusi ini. Saya menulis kode PHP sejak tahun 2002 tetapi sampai hari ini saya tidak melihat bahwa PHP menyediakan chop()fungsinya. Terima kasih atas petunjuk ini.
aksioma
7

Perl, 702 613 546 474 439 338 260 byte

Terima kasih kepada Dom Hastings atas bantuannya dan versi supernya.
Kode menggunakan array 2D.

Versi oleh 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$/}

Versi golf saya yang lebih kecil sebesar 338 byte (untuk referensi):

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

Uji

$ 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
sumber
3
Jika Anda tidak menggunakan use strict;, Anda tidak perlu semua my, yang akan menghemat setidaknya beberapa byte. Juga ==lebih pendek daripada eqkarena yang terakhir membutuhkan ruang.
Alex A.
1
Jika saya tidak salah, Anda hanya menelepon $msekali, jadi daripada menyimpan argumen baris perintah sebagai variabel, Anda dapat memanggilnya langsung split, yaitu @m=split(',',$ARGV[0]).
Alex A.
1
Hai @LukStorms, senang melihat lebih banyak pegolf Perl! Beberapa hal untuk membantu menghemat beberapa byte! Variabel Anda $ddan $sdapat diambil menggunakan regex untuk menyelamatkan Anda beberapa byte ($d,$s)=/^(.)(.+)$/, dan semua foreachbisa for(karena mereka sama. Anda mungkin juga dapat menyimpan beberapa karakter menggantikan beberapa ini dengan map{... }@xkarena Anda dapat mengabaikan parens sekitar item iterated (ini bekerja dengan baik jika Anda harus mengandung loop lain). Jika Anda menggunakan $ARGV[0]Anda dapat menggantinya dengan pop, tetapi jika Anda menggunakan skrip seperti yang perl script.pl <<< "text"Anda dapat gunakan <>sebagai gantinya!
Dom Hastings
1
Jika Anda ingin menyimpan skrip menggunakan args, Anda dapat menggunakan popuntuk menyimpan pasangan. Alih-alih use Swtichdan switch/ casepernyataan, Anda bisa melakukan pemeriksaan individual yang mungkin menghemat byte. Sesuatu seperti $y-="N"eq$dakan bekerja juga (karena benar 1dan salah ''). Seringkali, Anda dapat menggunakan kata-kata sebagai bareword, sehingga $y-=N eq$dakan berhasil! Ada beberapa variabel ajaib yang dapat digunakan untuk menyimpan byte, $/adalah '\n'dan $"adalah ' ', tapi kadang-kadang harfiah baris kekuatan membantu menyelamatkan char juga. Trik lain (kotor!) Adalah banyak tugas untuk menyimpan beberapa lagi, seperti yang $a=0;$b=0;bisa dilakukan $a=$b=0.
Dom Hastings
1
Hanya beberapa lagi, aku janji. Saya harap ini adalah info yang Anda cari! Kehilangan parens pada panggilan fungsi adalah perubahan standar yang cukup, begitu substr($_,0,1)juga halnya substr$_,0,1. Postfix untuk loop dan jika cek juga dapat berguna seperti pada for(@c){...}vs. ...for@ctetapi Anda tidak dapat menggunakan ;dalam kode, Anda harus koma terpisah (yang tidak selalu berfungsi ketika Anda memanggil fungsi). Ada begitu banyak tips hebat juga di codegolf.stackexchange.com/questions/5105/… . Semoga berhasil!
Dom Hastings
5

Python 2, 394 byte

Jalankan program lalu tempel ke input standar seperti misalnya "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])

Ini tidak terlalu optimal. Pertama itu berjalan melalui input untuk merekam path. Kemudian melakukan beberapa matematika untuk menentukan posisi awal yang tepat dan ukuran o. Kemudian ia menjalankan kembali dan menetapkan entri yang sesuai osebagai salah satu dari >v<^X. Kecerdasan utama dalam menggunakan kembali fungsi yang sama untuk kedua traversal ini.

Alex L
sumber
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 bahkan tidak sedikit kompetitif, jadi ini menyenangkan.

Tidak disatukan

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
sumber
4

PHP, 496 514 528

Saya mencoba peruntungan di PHP, hasilnya agak lama, saya masih ingin mempostingnya, hanya untuk bersenang-senang.

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

Tidak disatukan

<?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
sumber
1
Bisa dikurangi banyak. Misalnya, Anda bisa menulis for(;$i++<$f;), mencoba menghapus tanda kurung yang tidak perlu, menggunakan konstanta yang tidak terdefinisi ( N) alih-alih string ( 'N'), ...
Blackhole
1
Alih-alih ifs, coba gunakan operator trenary atau ands logis. Juga, ini akan membantu jika Anda menggunakan PHP4.1 dan menggunakan array GET dengan poin.
Ismael Miguel
3

JavaScript (ES6), 244 249 274

Spasi utama dan baris baru ditambahkan untuk kejelasan dan tidak dihitung, kecuali baris baru di dekat akhir panggilan gabungan, yang signifikan dan dihitung.

Tes menjalankan cuplikan (hanya ECMAScript 6, Firefox dan Safari 9 saja)

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
sumber
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 tidak disatukan:

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

Alokasi memori dinamis tidak jauh lebih sulit, tetapi malloc adalah pengidentifikasi yang terlalu panjang untuk digunakan dalam kode golf. Saya merasa seperti harus ada semacam header PCG.h yang secara otomatis disertakan untuk bermain golf di c, hanya untuk menyingkat beberapa pengidentifikasi.

LambdaBeta
sumber
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
sumber
1

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

Implementasi bebas array: mencetak dari atas ke bawah, dari kiri ke kanan.

  • Mengurai dan memperluas arah menjadi jejak (x y char)elemen:

    Input "N3" yang sederhana menghasilkan ((0 0 #\^) (0 -1 #\^) (0 -2 #\X))

  • Juga, hitung minimal xdany
  • Urutkan jejak yang dihasilkan oleh ypertama dan kemudian olehx
  • Iterasi daftar yang diurutkan saat memindahkan kursor

    1. Tambahkan baris baru dan spasi untuk memindahkan kursor saat ini di posisi yang tepat
    2. Ketika pada posisi x - minx, y - miny, mencetak karakter yang dikehendaki

Contohnya

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

Hasil:

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

>v>v
^>^X

>>>>>>>>>>>v
^          v
^          v
^          v
^          v
^          v
^          v
^          v
^          v
^        X v
^        ^ v
^        ^ v
^        ^<<
coredump
sumber
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'

metalim
sumber