Yarr! Gizli hazineye bir harita!


49

Giriş

“Yarr !! Kendimizi“ programcı ”olarak adlandıran bir hanımefendi vardı, bir haritayı 'gizli hazinemiz haline getirdi!” Ancak' tuhaf sayılar 'harfleri ile yazılmış! ”E5, N2, E3” Çılgınlık! Uygun bir hazine haritası bile yazamıyorum, 'işe yaramaz sürün. Bizi düzeltin! Size hazineden payını hediye edeceğiz!'

Zorluk Açıklaması

Bir korsan grubu hazine haritasını okumakta zorlanıyor. Daha piratey bir forma dönüştürmek için bir program yazabilir misiniz?

Giriş olarak, orijinal hazine haritasını alacaksınız. Virgülle ayrılmış dizelerin bir listesi, her biri bir harf bölümünden (korsanlara hangi yöne girmeleri gerektiğini söyler) ve bir sayı bölümünden (bu korsanlara bu yönde kaç adım atmaları gerektiğini söyleyen ) oluşan bir liste . Örneğin, aşağıdaki hazine haritası:

E2,N4,E5,S2,W1,S3

"Doğuya iki adım yürüyün, kuzeye dört adım yürüyün, doğuya beş adım yürüyün, güneyden iki adım yürüyün, batıya bir adım yürüyün, sonra güneyden üç adım yürüyün" anlamına gelir.

Çıktısı olarak bir grafik şeklinde çıkış haritası, karakterleri kullanarak olacak sen >, ^, v, ve <işaretçiler olarak. Yukarıdaki girişin çıktısı:

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

XBunun yerine güneydeki son adımı değiştirdiğimize dikkat edin . Bunun nedeni, son adımın hazinenin olduğu ve hepimizin bildiği gibi, korsanların hazine haritalarında X'e sahip olmaları gerektiği, aksi takdirde nasıl okuyacaklarını bilemeyecek olmalarıdır.

Bu arada, harita kendisini asla geçmeyecek, bu yüzden çakışmalarla uğraşmak konusunda endişelenmenize gerek yok. Ayrıca, çıktının sonunda izleyen yeni bir satırın olmasına izin verilir.

Örnek Girişler ve Çıkışlar

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
Her satırda sonda boşluklar var mı? Sayı her zaman ondan az mı olacak?
Downgoat

9
Son hamleden sonrakiX adımı işaretlemesi gerektiğini düşünüyorum, diğer tüm hamleler de sayıldığı gibi. Son adımın N3 olduğunu hayal edin: kuzeye üç adım yürüyüp kazıyorsunuz, ancak burada hiçbir şey yok, bunun yerine 2 adım yürümek zorunda kaldınız. Mevcut kuralı saklamanızın sakıncası yok, çünkü ele alınması gereken küçük bir köşe davası ekliyor. Ama o laddie'ye ne olduğunu unutma.
Ağustos'ta

6
@coredump Veya belki de korsanları yanlış yönlendirmek istiyoruz, böylece hazineyi kendimiz için alabilelim;) Hayır, haklısın, korsanlar çok yakında bir adım kazıyorlar. Halihazırda üç cevap verildiğinde, mevcut çözümleri geçersiz kılmaktan kaçınmak için kuralı koruyacağım.
apsent

4
@ jpmc26 Peki, bu korsanlar alfabenin çok şey bilmiyorum ... onlar :) C'de son birkaç yıl geçirdi
apsent

4
Dördüncü örnek sadece korsanları
avlıyor

Yanıtlar:


8

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

Stdin ile girişi girin.

Bu kullanır y -> x -> charhem harita, inşa etmek sözlüğü xve ynegatif olabilir. Girdi ayrıştırıldıktan sonra, x koordinatının global minimum değeri çıkarılır. Her satır için, geçerli satır için global minimumdan maksimum dizine geçen bir aralıkta yinelenir ve bu dizin için doğru karakteri yazdırır.

Teması ile kalmak için, ifadeleri açmak için NESWutanmadan gelen korsan edildi uygun endeksleri içine SP3000 'ın cevabı .

[x,y] -> charSözlük kullanılan orijinal sürüm :

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 bayt

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

Gibi giriş "E2,N4,E5,S2,W1,S3".

NSEW[1, 3, 2, 0]tarafından eşleştirildi d=ord(c)%10%7. Değiştirilip değiştirilmeyeceğine yveya xsonra karar d%2verilip verilmeyeceğine ve artırılmaya veya azaltılmaya karar verilir d-2|1. Birinci ve üçüncü ifadeler kaba kuvvet tarafından bulundu.

Bunun dışında, formun iç içe geçmiş sözlüğünün basit bir kullanımıdır {y: {x: char}}.

(Haritalama için @joriki'ye teşekkürler)


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

1
@ joriki Ah bu güzel bir ifade - teşekkürler!
Sp3000

2
İşte tamsayılı işlevler için basit ifadeler bulmak için yazdığım bazı kodlar (farklı bağlamda). Bunun için kullanmadım, ama sadece senin için ilginç olabileceğini düşündüm. (İlgili kod, "Bu, kodlamayı optimize etmek için kullandığım koddur" yazdığı yerden başlar.)
joriki

3
@ joriki Brute zorlama harika bir fikir - sadece ortaya çıktı 1|d%-3(bu olumsuzluk, ama ben de bunun tamam olduğunu anladım)!
Sp3000

14

Javascript (ES6), 260

Bu ilginç bir şeydi ...

Teşekkürler @ETHproductions, @ edc65 ve yardım için @ 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}

Bu adsız bir işlevi tanımlar; böylece f=ad vermek için başlangıcına eklemek üzere adlandırın.

Test etmek için: console.log(f("E2,N4,E5,S2,W1,S3"))

Açıklama:

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
İfadeleri ayırmanın güzel bir yolu! Her şeyi tek bir satıra koymak ve bunları noktalı virgülle ayırmaktan kesinlikle çok daha okunaklı. Benim önerim de önerebilir: Eğer hareket ettirerek bir byte kurtarabilecek i++gelen forbu durumda, kullanılan son sıraya döngü c=i++>r-2?"X":c.
ETHproductions

1
Ayrıca, ES6 kullandığınız v[0].repeat(+v.slice(1))için Array(v.slice(1)- -1).join(v[0]), genel olarak 11 byte tasarruf " ".repeat(j-p-1)yerine ve yerine kullanmanızı öneririm Array(j-p).join(" "). Sanırım F='forEach', fonksiyonun başına da yerleştirebilir , daha sonra her .forEachbirini oradan değiştirebilir, 4 tane daha [F]
kaydedebilirsiniz

1
.ForEach yerine .map kullanmayı deneyin. O kadar kısa ki
kısalmamalısınız

1
@UndefinedFunction ifs için shorthands kullanmak isteyebilirsiniz, aynı zamanda değişkenleri de
azaltırsanız

1
Anlayışım doğruysa, q=x=y=2e3yaparsam çıktının yanlış olacağı anlamına W9999mı geliyor?
Sp3000

7

PHP, 431 417 bayt

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

Bir dosyaya ( treasure.php) koyun , girintiyi kaldırın, satırları birleştirin (okunabilirlik için buraya sarılır), <?phpişaretçiyi dosyanın başlangıcına yerleştirin (teknik olarak programın bir parçası olmadığı için burada gösterilmez).

Yürütme örneği:

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

-d error_reporting=0Belirtilen endekslerde bulunmayan değerler hakkındaki uyarıları bastırmak için bu seçeneğe ihtiyaç vardır $z.

Güncelleme:

Yayınlama için kodun kodlanmamış versiyonunu hazırlarken, iki gereksiz atama (12 bayt) ve kaldırılabilecek bir boşluk içerdiğini keşfettim ( as$i); Ayrıca, whilebir fordöngü ile değiştirerek ve içine bir atama sıkarak ( whiledöngü kullanarak mümkün değildir ) başka bir bayt kurtardı.


Ungolded bir versiyonunu görmek isterim.
Lars Ebert

1
@LarsEbert Cevabı ungolfed koduna bir link ile güncelledim. Çözümünüzü şimdi kontrol ettim (daha önce yapmadım); temelde aynı algoritmayı kullandık. Seninki son adımı benimkinden daha iyi idare eder. Eğer uygularsam 25 bayt daha soyabilirim $count --;.
axiac

$argntasarruf 3 Bayt choptasarruf 1 Bayt "X"-> Xsabitleri kullan daha fazla bayt
kazan

@ JörgHülsermann Ben $argnipucunu alamadım . "X"->XPüf noktasının farkındayım ama muhtemelen bu çözümü yazdığımda unutmuşumdur. 2002'den beri PHP kodu yazıyorum ama bugüne kadar PHP'nin bu chop()işlevi sağladığını fark etmedim . Bu ipucu için teşekkür ederim.
axiac

7

Perl, 702 613 546 474 439 338 260 bayt

Dom Hastings'e yardımları ve sahip olduğu versiyon için teşekkür ederiz.
Kod 2B dizi kullanır.

Dom Hastings'in sürümü:

$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 baytlık golf versiyonum (referans için):

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

Ölçek

$ 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
Eğer kullanmıyorsanız use strict;, tüm gerekmez mysize en az birkaç bayt kurtaracak s. Ayrıca ikincisi boşluk gerektirdiğinden ==daha kısadır eq.
Alex A.

1
Yanılmıyorsam, sadece bir $mkez ararsınız, bu nedenle komut satırı argümanını bir değişken olarak saklamak yerine, onu doğrudan arayabilirsiniz split, yani @m=split(',',$ARGV[0]).
Alex A.

1
Hey @LukStorms, Perl golfçülerinin daha fazlasını görmekten memnun! Bazı baytları kurtarmanıza yardımcı olacak birkaç şey Kişisel $dve $sdeğişkenler bazı bayt kaydetmek için regex kullanarak yakaladı edilebilir ($d,$s)=/^(.)(.+)$/ve tüm foreachs olabilir for, ikisi de bir şekilde (. Ayrıca bazı karakter ile bunlardan bazıları yerine kaydetmek mümkün olabilir map{... }@xEğer parens görmezden beri - yinelenen öğenin etrafında (başka döngüler içermeniz gerekirse işe yarar). Kullanıyorsanız, bunu $ARGV[0]pop ile değiştirebilirsiniz, ancak betiği olduğu gibi perl script.pl <<< "text"kullanırsanız kullanabilirsiniz <>!
Dom Hastings

1
Senaryoyu args kullanarak tutmak istiyorsan, popbir çifti kurtarmak için kullanabilirsin . Yerine use Swtichve switch/ casetablolar, size bayt kurtarabilir bireysel kontrolleri yapabilir. Gibi bir şey $y-="N"eq$dde işe yarayacak (doğru 1ve yanlış olduğundan ''). Sık sık, korkak gibi sözleriniz olabilir $y-=N eq$d, işe yarayacak! Eğer bayt kaydetmek için kullanabileceğiniz bazı sihirli değişken vardır, $/olan '\n've $"olduğunu ' ', ama bazen bir hazır satır da bir char tasarruf yardımcı olabilir. Başka (kirli!) Hüner olduğu gibi birden atar, birkaç kurtarmaktır $a=0;$b=0;olabilir $a=$b=0.
Dom Hastings,

1
Sadece birkaç tane daha, söz veriyorum. Umarım peşinde olduğun tür bilgi budur! İşlev çağrıları üzerindeki parenlerin kaçırılması oldukça standart bir değişikliktir, öyle substr($_,0,1)olabilir substr$_,0,1. Döngüler için Postfix ve kontroller de olduğu gibi yararlı olabilir eğer for(@c){...}vs. ...for@cama kullanamıyorum ;kodunda yaptığında (işlevlerini çağıran yaparken hangi zaman çalışmaz) virgül yerine ayırmak gerekir. Codegolf.stackexchange.com/questions/5105/… adresinde de birçok harika ipucu var . İyi şanslar!
Dom Hastings,

5

Python 2,394 bayt

Programı çalıştırın, ardından standart girişe yapıştırın. "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])

Bu çok optimize edilmemiş. İlk önce yolu kaydetmek için girdi boyunca ilerler. Sonra doğru başlangıç ​​pozisyonu ve boyutunu belirlemek için bazı matematik yapar o. Daha sonra tekrar çalışır ve uygun girişlerden obirini ayarlar >v<^X. Ana zekâ, her iki geçiş için de aynı işlevi yeniden kullanmaktır.


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 çoğu zaman biraz da rekabetçi değil, bu yüzden eğlenceliydi.

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

PHP'de şansımı denedim, sonuç oldukça uzun, yine de sadece eğlence için göndermek istiyorum.

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
Çok azaltılabilir. Örneğin, sadece yazabilir for(;$i++<$f;), gereksiz parantezleri kaldırmayı deneyebilir N, dizeleri ( 'N') yerine tanımsız sabitleri ( ) kullanabilirsiniz …
Blackhole

1
S yerine, iftrenaryer operatörleri veya mantıksal ve-ler kullanmayı deneyin. Ayrıca, PHP4.1 kullanıyorsanız ve noktalarla birlikte bir GET dizisi kullanıyorsanız, yardımcı olacaktır.
Ismael Miguel,

3

JavaScript (ES6), 244 249 274

Öncü boşluklar ve yeni satırlar netlik için eklendi ve birleştirme çağrısında sona eren yeni satır dışında sayılmıyor, bu önemli ve sayılıyor.

Snippet'i çalıştırma testi (yalnızca ECMAScript 6, Firefox ve 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);}}

Ungolfed versiyonu:

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

Dinamik bellek ayırma zor değil, ancak malloc kod golfünde kullanılacak bir tanımlayıcı çok uzun. Bazı tanımlayıcıları kısaltmak için yasal olarak otomatik olarak c ile golf oynamaya dahil olan bir tür PCG.h başlığı olması gerektiğini düşünüyorum.


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

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

Dizi içermeyen uygulama: yukarıdan aşağıya, soldan sağa doğru yazdırır.

  • Yönleri ayrıştırıp (x y char)öğelerin izine genişletir :

    Basit "N3" girişi üretir ((0 0 #\^) (0 -1 #\^) (0 -2 #\X))

  • Ayrıca, minimal xve hesaplamaky
  • Sonuçta elde edilen izi yönce ve sonrax
  • İmleci hareket ettirirken sıralanan listeyi yineleyin

    1. Geçerli imleci doğru konuma taşımak için yeni satırlar ve boşluklar ekleyin
    2. Pozisyonunda olduğunda x - minx, y - minyistenen karakteri yazdırmak

Örnekler

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

Sonuç:

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

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'

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.