ヤル!隠された宝物への地図!


49

前書き

「ヤァ!!私たちは自分自身を「プログラマー」と呼んだラディに地図を作ってもらいました!しかし、「tis written wit」奇妙な数字「n文字!」「E5、N2、E3」...意味ですか?狂気!適切な宝の地図を書くことすらできません、無駄なクレチンです。それを修正してください!宝を分け前に贈ります! "

チャレンジの説明

海賊グループが宝の地図を読むのに苦労しています。もっと...海賊版に変換するプログラムを書くことができますか?

入力として、元の宝の地図を受け取ります。これはコンマ区切りの文字列のリストです。各文字列は、文字部分(海賊にどの方向に進む必要があるかを伝える)と数字部分(海賊にその方向に進むべき歩数を伝える)で構成されます。たとえば、次の宝の地図:

E2,N4,E5,S2,W1,S3

「東へ2歩、北へ4歩、東へ5歩、南へ2歩、西へ1歩、そして南へ3歩」という意味です。

出力として、あなたは文字を使用して、グラフ形式で出力マップをよ>^v、および<ポインタとして。上記の入力の出力は次のとおりです。

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

X代わりに南への最後のステップを置き換えたことに注意してください。これは、最後のステップが宝のある場所であり、誰もが知っているように、海賊は宝の地図にXがなければならないからです。

ちなみに、マップはそれ自体と交差することはないので、重複を処理することを心配する必要はありません。また、出力の最後に改行を追加することもできます。

サンプルの入力と出力

S5,W2

 v
 v
 v
 v
 v
X<

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

>v>v
^>^X

N1

X

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

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

E21,S2

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

N12,E11,S12,W2,N4

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

1
各行の末尾にスペースを入れることはできますか?数は常に10未満になりますか?
ダウンゴート

9
他のすべての動きがカウントされるように、最後の動きのXのステップをマークする必要があると本当に思います。最後のステップがN3であると想像してください。北に3歩歩いて掘りますが、ここには何もありません。代わりに2歩歩かなければなりません。既存のルールを保持するかどうかは気にしません。それは、処理するための小さなコーナーケースを追加するからです。しかし、その若者に何が起こったのか覚えておいてください。
コアダンプ

6
@coredumpまたは、海賊を誤解させて、宝物を自分のものにすることができるかもしれません。すでに3つの答えがあるので、既存のソリューションの無効化を避けるために、ルールをそのままにします。
アブサン

4
@ jpmc26まあ、これらの海賊はアルファベットの多くを知らない...彼らは最後の数年間をCで過ごした:)
アブサン

4
4番目の例は、ちょうど海賊トローリングされる...
justhalf

回答:


8

ルビー、 213209198186 178

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

stdinを介して入力を渡します。

これは、y -> x -> charディクショナリを使用してマップを構築します。両方xyが負の場合もあります。入力が解析されると、x座標のグローバルな最小値が抽出されます。次に、各行について、現在の行のグローバルミニマムインデックスから最大インデックスまでの範囲で反復処理を行い、そのインデックスの正しい文字を出力します。

テーマにとどまるためNESWに、適切なインデックスに変換する表現は、Sp3000回答から恥知らずに海賊版にされました

[x,y] -> char辞書を使用した元のバージョン:

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

20

Python 2、249 248 244 239 237バイト

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

のように入力し"E2,N4,E5,S2,W1,S3"ます。

NSEW[1, 3, 2, 0]によってマップされd=ord(c)%10%7ます。変更するかどうyかは、xそれまでに決定されd%2、かつ増減するかどうかによって決定されますd-2|1。最初と3番目の式は、総当たりで発見されました。

それ以外は、のネストされた辞書の単純な使用法です{y: {x: char}}

(マッピングの支援について@jorikiに感謝します)


1
(d + 1 & 2) - 1
ジョリキ

1
@joriki Ahそれはいい表現だ-ありがとう!
Sp3000

2
整数関数の簡単な式を見つけるために(異なるコンテキストで)書いたコードいくつか示します。私はこれを使用しませんでしたが、あなたにとって面白いかもしれないと思っただけです。(関連するコードは、「これはエンコードを最適化するために使用したコードです」という箇所から始まります。)
joriki

3
@joriki Brute forcingは素晴らしいアイデアです-ちょうど現れました1|d%-3(これは否定ですが、私はそれも大丈夫だと気づきました)!
Sp3000

14

Javascript(ES6)、260

これは興味深いものでした...

@ ETHproductions、@ edc65、および@vihanに感謝します!

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

これは匿名関数を定義するので、それを呼び出すにはf=、名前を付けるために先頭に追加します。

テストする: console.log(f("E2,N4,E5,S2,W1,S3"))

説明:

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

3
これはステートメントを分離するのに良い方法です!確かにすべてを1行に入れてセミコロンで区切るよりもはるかに読みやすいです。私は私の提案を提供することがあります場合:あなたを動かすことでバイトを救うことができるi++から、forこの場合には、それが使われている最後の場所にループc=i++>r-2?"X":c
ETHproductions

1
あなたはES6を使用しているので、また、私が使用してことをお勧めv[0].repeat(+v.slice(1))の代わりにArray(v.slice(1)- -1).join(v[0])、と" ".repeat(j-p-1)の代わりに、Array(j-p).join(" ")全体の11バイトを保存し、。またF='forEach'、関数の先頭に配置し、.forEachそこからそれぞれを変更して[F]、さらに4を保存することもできると思います。
ETHproductions

1
.forEachの代わりに.mapを使用してみてください。非常に短いので、Fに短縮することすらすべきではありません
-edc65

1
@UndefinedFunctionの短縮形を使用するif場合がありますが、同時に変数をデクリメントすると役立つ場合があります
-Downgoat

1
私の理解が正しい場合、q=x=y=2e3私が言った場合、出力が間違っているということW9999ですか?
Sp3000

7

PHP、431 417バイト

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

ファイルに挿入(treasure.php)、インデントを削除、行を結合(読みやすくするためにここで折り返します)、<?phpファイルの先頭にマーカーを配置します(技術的にはプログラムの一部ではないため、ここには表示されません)。

実行例:

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

このオプション-d error_reporting=0は、の指定されたインデックスで見つからない値に関する通知を抑制するために必要です$z

更新:

投稿用にコードのないバージョンを準備しているときに、 2つの不要な割り当て(12バイト)と削除可能な空白が含まれていることを発見しました(as$i)。また、whileaをforループに置き換え、その中に割り当てを絞ることで(whileループを使用することはできません)、別のバイトを保存しました。


私は無料版を見てみたいです。
ラースエバート

1
@LarsEbert回答を更新して、未登録コードへのリンクを追加しました。私は今あなたの解決策をチェックしました(以前はしませんでした)。基本的に同じアルゴリズムを使用しました。あなたのものは私のものよりも最後のステップをうまく処理します。を実装すると、さらに25バイトを削除できます$count --;
axiac

$argn3保存バイトchop1バイトの保存"X"- > X使用定数は、より多くのバイトを保存する
イェルクHülsermann

@JörgHülsermann $argnヒントがわかりません。私は"X"->Xトリックを知っていますが、このソリューションを書いたときにおそらく忘れていました。2002年以来PHPコードを書いていますが、今日までPHPがchop()機能を提供していることに気付きませんでした。このヒントをありがとう。
アクシアック

7

Perlの、702の 613 546 474 439 338 260バイト

Dom Hastingsの助けと彼のスーパーゴルフバージョンに感謝します。
コードは2D配列を使用します。

Dom Hastingsによるバージョン:

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

338バイトの私のより低いゴルフバージョン(参照用):

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

テスト

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

3
を使用use strict;していない場合は、すべてのを必要としないmyため、少なくとも数バイトは節約されます。また、後者はスペースを必要とするため、==よりも短くなりeqます。
アレックスA.

1
私は間違っていない場合は、あなただけ呼んでいる$m一度、そうではなく変数として、コマンドライン引数を格納し、あなたはでそれを直接呼び出すことができsplit、すなわち@m=split(',',$ARGV[0])
アレックスA.

1
@LukStormsさん、Perlのゴルファーをもっと見ることができてうれしいです!いくつかのバイトを節約するためのいくつかのこと!あなた$d$s変数はあなたにいくつかのバイトを保存するために正規表現を使用して手にすることができ($d,$s)=/^(.)(.+)$/、すべてのforeachsができfor、彼らが同じだとして(。あなたがまたしてこれらのいくつかを交換するいくつかの文字を救うことができるかもしれないmap{... }@xあなたは括弧を無視することができますので、周りの反復項目(あなたが他のループを含むようにしている場合、これはうまく動作します)あなたが使用している場合。$ARGV[0]ポップでいますが、スクリプトを使用する場合のようにすることを置き換えることができますがperl script.pl <<< "text"、あなたが使用することができます<>代わりに!
ドムヘイスティングス

1
argsを使用してスクリプトを保持したい場合はpop、いくつかを保存するために使用できます。/ ステートメントの代わりにuse Swtich、バイトを節約できる個別のチェックを行うことができます。のようなものも同様に機能します(true とfalseはであるため)。多くの場合、単語をむき出しの単語にすることができるので、うまくいきます!バイト、is 、is を保存するために使用できる魔法の変数がいくつかありますが、リテラルの改行がcharの保存にも役立つ場合があります。もう1つの(汚い!)トリックは、複数の割り当てで、さらにいくつかを保存することです。switchcase$y-="N"eq$d1''$y-=N eq$d$/'\n'$"' '$a=0;$b=0;$a=$b=0
ドムヘイスティングス

1
もう少しだけ、約束します。これがあなたが求めているちょっとした情報になることを願っています!関数呼び出しに括弧をオフに欠落していることはかなり標準の変更なので、substr($_,0,1)可能substr$_,0,1。Postfix forループとfor(@c){...}vsのようにチェックも便利な...for@c場合があります;が、コードで使用できない場合は、代わりにコンマで区切る必要があります(関数を呼び出すときに常に機能するとは限りません)。codegolf.stackexchange.com/questions/5105/…にも非常に多くの素晴らしいヒントがあります。幸運を!
ドムヘイスティングス

5

Python 2、394バイト

プログラムを実行してから、たとえば次のように標準入力に貼り付けます "E2,N4,E5,S2,W1,S3"

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

これはあまり最適化されていません。最初に、入力を実行してパスを記録します。次に、いくつかの数学を実行して、の正しい開始位置とサイズを決定しoます。次に、再度実行され、の適切なエントリをのo1つとして設定します>v<^X。主な賢さは、これらの両方のトラバーサルで同じ機能を再利用することです。


4

XQuery 3.0、498

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

XQueryの競争力はそれほど高くないことが多いため、これは楽しかったです。

非ゴルフ

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

4

PHP、496 514 528

幸運をPHPで試しましたが、結果はかなり長くなりますが、楽しみのために投稿したいと思っています。

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

非ゴルフ

<?php

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

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

    $map = [];

    $position = [0, 0];

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

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

?>

1
大幅に削減できます。たとえば、あなただけの書き込みができfor(;$i++<$f;)、(未定義の定数を使用し、不要な括弧を削除しようとするN(文字列の代わりに)'N'、...)
ブラックホール

1
ifsの代わりに、三項演算子または論理ANDを使用してみてください。また、PHP4.1を使用し、ポイントでGET配列を使用する場合にも役立ちます。
イスマエルミゲル

3

JavaScript(ES6)、244 249 274

わかりやすくするために追加された先頭のスペースと改行はカウントされません。ただし、結合呼び出しの終わり近くの改行は重要でカウントされます。

スニペットの実行テスト(ECMAScript 6、Firefox、およびSafari 9のみ)

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

// TEST

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

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


2

C、557

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

ゴルフされていないバージョン:

#include <stdio.h>

#define MAX_WIDTH 998
#define MAX_HEIGHT 998

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

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

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

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

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

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

    return 0;
}

動的なメモリ割り当てはそれほど難しくありませんが、mallocはコードゴルフで使用するには識別子が長すぎます。いくつかの識別子を短縮するために、cでのゴルフに合法的に自動で含まれる何らかの種類のPCG.hヘッダーがあるべきだと思います。


1

グルービー、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

Common Lisp-603

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

配列のない実装:上から下、左から右へ印刷します。

  • 方向を解析して(x y char)要素のトレースに展開します。

    単純な「N3」入力は以下を生成します ((0 0 #\^) (0 -1 #\^) (0 -2 #\X))

  • また、最小値xy
  • 結果のトレースをy最初にソートし、次にソートしますx
  • カーソルを移動しながら、ソートされたリストを反復処理します

    1. 改行とスペースを追加して、現在のカーソルを正しい位置に移動します
    2. 位置x - minxy - minyで、目的の文字を印刷します

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

結果:

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

>v>v
^>^X

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

1

CoffeeScript、303   285バイト

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

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.