Ярр! Карта до прихованого скарбу!


49

Вступ

"Yarr !! У нас був хлопець, який назвав себе" програмістом ", скласти карту для нашого прихованого скарбу! Але" це написано дотепністю "дивні цифри" n літери! "E5, N2, E3" ... що це навіть робить мається на увазі? Божевілля! Навіть не можна виписати належну карту скарбів, непридатний кретин. Виправте це нам! Ми ​​подаруємо вам скарбницю! "

Опис виклику

У групи піратів виникають проблеми з читанням карти скарбів. Чи можете ви написати програму, щоб перетворити її у більш ... піратську форму?

Як вхід, ви отримаєте оригінальну карту скарбів. Це список рядків, розділених комами, кожний рядок складається з літери (яка вказує піратам, в якому напрямку вони повинні пройти), і частини числа (яка повідомляє піратам, скільки кроків зробити в цьому напрямку). Наприклад, наступна карта скарбів:

E2,N4,E5,S2,W1,S3

означало б «пройтися двома кроками на схід, пройти чотири кроки на північ, пройти п’ять кроків на схід, пройти два кроки на південь, пройти один крок на захід, потім пройти три кроки на південь».

Як вихід, ви будете виводити карту в графічному вигляді, використовуючи символи >, ^, 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
Чи дозволяється нам мати пробіли у кожному рядку? Чи число завжди буде менше десяти?
Пуховик

9
Я дійсно думаю, що Xслід позначити крок після останнього руху, як і всі інші рухи. Уявіть собі, що останній крок - це N3: ви ходите три кроки на північ і копаєте, але тут нічого немає, вам довелося замість цього пройти 2 кроки. Я не заперечую, якщо ви дотримуєтесь існуючого правила, оскільки це додає невеликий кутовий кейс для обробки. Але пригадайте, що сталося з тим хлопцем.
coredump

6
@coredump Або, можливо, ми хочемо ввести в оману піратів, щоб ми могли взяти скарб для себе;) Ні, ви праві, пірати копають один крок занадто рано. Враховуючи, що вже є три відповіді, я дотримуватимусь цього правила, як уникнути недійсності існуючих рішень.
абсент

4
@ jpmc26 Ну, ці пірати не знають багато алфавіту ... останні кілька років вони провели у С :)
абсент

4
Четвертий приклад - це просто тролінг піратів ...
justhalf

Відповіді:


8

Рубі, 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.

Для цього використовується y -> x -> charсловник для побудови карти, де і те, xі інше yможе бути негативним. Після того, як вхід розібраний, витягується глобальний мінімум координати 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. Перший і третій вирази були виявлені грубою силою.

Крім цього, це просте використання вкладеного словника форми {y: {x: char}}.

(Дякую @joriki за допомогу з картографуванням)


1
(d + 1 & 2) - 1
joriki

1
@joriki Ах, це приємний вираз - дякую!
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
Це приємний спосіб розділити заяви! Це, безумовно, набагато легше для читання, ніж розміщувати все на одному рядку та розділяти їх крапками з комою. Якщо я можу запропонувати свою пропозицію: ви можете зберегти байт, перемістивши його 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
Спробуйте використовувати .map замість .forEach. Це так коротко, що ви навіть не повинні скорочувати його до F
edc65

1
@UndefinedFunction ви можете використовувати скорочення для ifs, це може допомогти, якщо ви одночасно зменшуєте змінні
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.

Оновлення:

Під час підготовки готівкової версії коду для публікації я виявив, що він містить два непотрібні завдання (12 байт) та пробіл, який можна видалити ( as$i); Крім того , шляхом заміни whileз forпетлею і стискаючи призначення в нього (неможливо з допомогою whileпетлі) Я зберіг інші байти.


Мені б хотілося побачити версію, що не має волі.
Ларс Еберт

1
@LarsEbert Я оновив відповідь за допомогою посилання на код, який не використовується. Я перевірив ваше рішення зараз (не робив цього раніше); ми в основному використовували той самий алгоритм. Твій останній крок справляється краще, ніж мій. Я можу зняти ще 25 байт, якщо реалізую $count --;.
аксіак

$argnзберегти 3 байти chopзберегти 1 байт "X"-> Xвикористовувати константи, заощадити більше байтів
Jörg Hülsermann

@ JörgHülsermann Я не розумію $argn. Мені відомо про "X"->Xтрюк, але я, мабуть, забув про нього, коли писав це рішення. Я пишу PHP-код з 2002 року, але до сьогоднішнього дня я не помітив, що PHP забезпечує цю chop()функцію. Дякую за цю підказку
аксіак

7

Perl, 702 613 546 474 439 338 260 байт

Дякуємо Дому Гастінгсу за допомогу та його супергольдовану версію.
У коді використовується 2D масив.

Версія Дома Гастінгса:

$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;, вам не потрібні всі mys, що заощадить принаймні кілька байт. Також ==коротше, eqоскільки для останнього потрібні пробіли.
Олексій А.

1
Якщо я не помиляюся, ви дзвоните лише $mодин раз, тому замість того, щоб зберігати аргумент командного рядка як змінну, ви можете викликати його безпосередньо в split, тобто @m=split(',',$ARGV[0]).
Олексій А.

1
Привіт @LukStorms, рада бачити більше гольфістів Perl! Кілька речей, які допоможуть зберегти кілька байт! Ваші $dта $sзмінні можуть бути схоплені за допомогою regex, щоб зберегти кілька байтів ($d,$s)=/^(.)(.+)$/, і всі foreachs можуть бути for(оскільки вони однакові. Ви також можете зберегти деякі символи, замінивши деякі з них map{... }@xоскільки ви можете ігнорувати парони навколо ітераційного елемента (це добре працює, якщо вам доведеться містити інші петлі). Якщо ви використовуєте, $ARGV[0]ви можете замінити це на поп, але якщо ви використовуєте сценарій, як у perl script.pl <<< "text"вас, можна використовувати <>замість цього
Dom Hastings,

1
Якщо ви хочете зберегти сценарій за допомогою аргументів, ви можете popзберегти пару. Замість use Swtichта switch/ caseоператорів ви можете робити окремі перевірки, які можуть економити ваші байти. Щось подібне також $y-="N"eq$dбуде працювати (оскільки це правда 1і помилка ''). Часто ви можете мати слова як голосні слова, так $y-=N eq$dбуде працювати! Є кілька магічних змінних, які можна використовувати для збереження байтів, $/є '\n'і $"є ' ', але іноді буквальний новий рядок також може допомогти зберегти знак. Ще один (брудний!) Трюк - це багаторазове призначення, щоб заощадити ще кілька, як $a=0;$b=0;це можливо $a=$b=0.
Дом Гастінгс

1
Ще кілька, обіцяю. Я сподіваюся, що це така собі інформація, яку ви хочете! Відсутність паролів на функціональних викликах є досить стандартною зміною, так substr($_,0,1)може бути substr$_,0,1. Postfix для циклів, і якщо перевірки можуть бути корисними, як і в for(@c){...}порівнянні, ...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. Потім він проходить через ще раз і встановлює відповідні записи oяк одного з >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'),…
Blackhole

1
Замість ifs спробуйте використовувати тренажерні оператори або логічні та. Крім того, це допоможе, якщо ви використовуєте 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

С, 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 є занадто довгим ідентифікатором, щоб використовуватись у коді гольфу. Я відчуваю, що для гольфу в С легально має бути якийсь заголовок 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

Лист звичайний - 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))

  • Також обчисліть мінімальний xіy
  • Сортуйте отриманий слід yспочатку, а потім заx
  • Ітерація над відсортованим списком під час переміщення курсору

    1. Додайте нові рядки та пробіли, щоб перемістити поточний курсор у потрібному положенні
    2. У положенні x - minx, y - 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'

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.