Yarr! Một bản đồ đến kho báu ẩn!


49

Giới thiệu

"Yarr !! Chúng tôi đã có một chàng trai tự gọi mình là" lập trình viên "tạo ra một bản đồ 'kho báu được giấu kín của chúng tôi! Nhưng' chúng tôi đã viết những chữ số lạ 'n chữ cái!" E5, N2, E3 "... có nghĩa là gì? Sự điên rồ! Thậm chí không thể ghi chép một bản đồ kho báu thích hợp, đó là 'cretin vô dụng. Hãy sửa nó cho chúng tôi! Chúng tôi sẽ tặng cho bạn một phần của kho báu! "

Mô tả thử thách

Một nhóm cướp biển đang gặp khó khăn khi đọc bản đồ kho báu. Bạn có thể viết một chương trình để chuyển đổi nó thành một hình thức ... cướp biển hơn không?

Là đầu vào, bạn sẽ nhận được bản đồ kho báu ban đầu. Đó là danh sách các chuỗi được phân tách bằng dấu phẩy, mỗi chuỗi bao gồm một phần chữ cái (cho biết những tên cướp biển cần đi theo hướng nào) và một phần số (cho biết cướp biển có bao nhiêu bước để đi theo hướng đó). Ví dụ, bản đồ kho báu sau đây:

E2,N4,E5,S2,W1,S3

có nghĩa là, "đi hai bước về phía đông, đi bốn bước về phía bắc, đi năm bước về phía đông, đi hai bước về phía nam, đi một bước về phía tây, sau đó đi ba bước về phía nam."

Khi sản lượng, bạn sẽ ra bản đồ dưới dạng đồ họa, sử dụng các nhân vật >, ^, v, và <là con trỏ. Đây là đầu ra cho đầu vào trên:

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

Lưu ý rằng chúng tôi đã thay thế bước cuối cùng ở phía nam bằng một Xthay thế. Điều này là do bước cuối cùng là nơi chứa kho báu, và như chúng ta đều biết, cướp biển phải có dấu X trên bản đồ kho báu của họ, nếu không họ sẽ không biết cách đọc nó.

Nhân tiện, bản đồ sẽ không bao giờ tự đi qua, vì vậy bạn không cần phải lo lắng về việc xử lý các lớp phủ. Ngoài ra, bạn được phép có một dòng mới ở cuối đầu ra.

Đầu vào và đầu ra mẫu

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
Chúng ta có được phép có dấu cách trên mỗi dòng không? Là số luôn luôn sẽ ít hơn mười?
Hạ cấp

9
Tôi thực sự nghĩ rằng Xnên đánh dấu bước sau bước cuối cùng, giống như tất cả các động thái khác được tính. Hãy tưởng tượng bước cuối cùng là N3: bạn đi bộ ba bước về phía bắc và đào, nhưng không có gì ở đây, bạn phải đi bộ 2 bước thay thế. Tôi không phiền nếu bạn giữ quy tắc hiện tại, bởi vì nó thêm một trường hợp góc nhỏ để xử lý. Nhưng hãy nhớ những gì đã xảy ra với laddie đó.
coredump

6
@coredump Hoặc có thể chúng ta muốn đánh lừa những tên cướp biển, để chúng ta có thể lấy kho báu cho chính mình;) Không, bạn đã đúng, những tên cướp biển đang đào một bước quá sớm. Vì đã có ba câu trả lời, tôi sẽ giữ nguyên quy tắc để tránh làm mất hiệu lực các giải pháp hiện có.
absinthe

4
@ jpmc26 Chà, những tên cướp biển này không biết nhiều về bảng chữ cái ... họ đã dành vài năm qua tại C :)
absinthe

4
Ví dụ thứ tư chỉ là
troll

Câu trả lời:


8

Hồng ngọc 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]}*""}

Truyền đầu vào qua stdin.

Điều này sử dụng một y -> x -> chartừ điển để xây dựng bản đồ, trong đó cả hai xycó thể âm. Khi đầu vào đã được phân tích cú pháp, mức tối thiểu toàn cầu của tọa độ x được trích xuất. Đối với mỗi hàng, sau đó nó lặp lại trong một phạm vi đi từ mức tối thiểu toàn cầu đến chỉ mục tối đa cho dòng hiện tại và in ký tự chính xác cho chỉ mục đó.

Để phù hợp với chủ đề, các biểu thức để biến NESWthành các chỉ số thích hợp đã bị đánh cắp một cách đáng xấu hổ từ câu trả lời của Sp3000 .

Phiên bản gốc đã sử dụng [x,y] -> chartừ điển:

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

Đầu vào như thế nào "E2,N4,E5,S2,W1,S3".

NSEWđược ánh xạ tới [1, 3, 2, 0]bởi d=ord(c)%10%7. Việc thay đổi yhay xsau đó được quyết định bởi d%2, và việc tăng hay giảm được quyết định bởi d-2|1. Các biểu thức đầu tiên và thứ ba được tìm thấy bởi lực lượng vũ phu.

Ngoài ra, đó là cách sử dụng đơn giản của một từ điển lồng nhau của biểu mẫu {y: {x: char}}.

(Cảm ơn @joriki đã giúp đỡ về bản đồ)


1
(d + 1 & 2) - 1
joriki

1
@joriki Ah đó là một biểu hiện tốt đẹp - cảm ơn!
Sp3000

2
Đây là một số mã tôi đã viết (trong một ngữ cảnh khác) để tìm các biểu thức đơn giản cho các hàm số nguyên. Tôi đã không sử dụng nó cho việc này, nhưng chỉ nghĩ rằng nó có thể thú vị với bạn. (Mã liên quan bắt đầu khi có thông báo "Đây là mã mà tôi đã sử dụng để tối ưu hóa mã hóa".)
joriki

3
@joriki Brute buộc là một ý tưởng tuyệt vời - chỉ cần bật lên 1|d%-3(đó là sự phủ định, nhưng tôi chỉ nhận ra rằng điều đó cũng ổn)!
Sp3000

14

Javascript (ES6), 260

Đây là một điều thú vị ...

Cảm ơn @ETHproductions, @ edc65 và @vihan vì sự giúp đỡ!

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}

Điều này xác định một hàm ẩn danh, vì vậy để gọi nó thêm f=vào đầu để đặt tên cho nó.

Để kiểm tra: console.log(f("E2,N4,E5,S2,W1,S3"))

Giải trình:

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
Đó là một cách hay để phân tách các tuyên bố! Nó chắc chắn dễ đọc hơn nhiều so với việc đặt mọi thứ trên một dòng và phân tách chúng bằng dấu chấm phẩy. Nếu tôi có thể đưa ra đề nghị của mình: bạn có thể lưu một byte bằng cách di chuyển i++từ forvòng lặp đến vị trí cuối cùng được sử dụng, trong trường hợp này c=i++>r-2?"X":c.
Sản xuất ETH

1
Ngoài ra, vì bạn đang sử dụng ES6, tôi sẽ đề nghị sử dụng v[0].repeat(+v.slice(1))thay thế Array(v.slice(1)- -1).join(v[0])" ".repeat(j-p-1)thay thế Array(j-p).join(" "), tiết kiệm tổng cộng 11 byte. Tôi nghĩ rằng bạn cũng có thể đặt F='forEach'ở đầu chức năng, sau đó thay đổi từng chức năng .forEachtừ đó sang [F], tiết kiệm thêm 4.
Sản phẩm ETH

1
Hãy thử sử dụng .map thay vì .forEach. Nó quá ngắn, bạn thậm chí không nên rút ngắn nó xuống F
edc65

1
@Und xác định chức năng bạn có thể muốn sử dụng tốc ký cho ifs, nó có thể hữu ích nếu bạn giảm các biến cùng một lúc
Downgoat

1
Nếu sự hiểu biết của tôi là chính xác, có q=x=y=2e3nghĩa là đầu ra sẽ không chính xác nếu tôi đã làm, nói , 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";}

Đặt nó vào một tệp ( treasure.php), loại bỏ vết lõm, nối các dòng (nó được gói ở đây để dễ đọc), đặt <?phpđiểm đánh dấu ở đầu tệp (không hiển thị ở đây vì về mặt kỹ thuật không phải là một phần của chương trình).

Ví dụ về thực hiện:

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

Tùy chọn -d error_reporting=0là cần thiết để loại bỏ các thông báo về các giá trị không được tìm thấy tại các chỉ số được chỉ định trong $z.

Cập nhật:

Trong khi tôi đang chuẩn bị phiên bản mã không được mã hóa để đăng, tôi phát hiện ra nó chứa hai phép gán không cần thiết (12 byte) và khoảng trắng có thể được loại bỏ ( as$i); cũng có thể, bằng cách thay thế một whilevới một forvòng lặp và ép chuyển nhượng vào nó (không thể sử dụng whilevòng lặp) Tôi lưu byte khác.


Tôi rất thích nhìn thấy một phiên bản không có ý thức.
Lars Ebert

1
@LarsEbert Tôi đã cập nhật câu trả lời với một liên kết đến mã không được mã hóa. Tôi đã kiểm tra giải pháp của bạn bây giờ (không làm điều đó trước đây); về cơ bản chúng tôi đã sử dụng cùng một thuật toán. Bạn xử lý bước cuối cùng tốt hơn của tôi. Tôi có thể tước thêm 25 byte nếu tôi thực hiện $count --;.
axiac

$argntiết kiệm 3 byte choplưu 1 byte "X"-> Xsử dụng hằng số tiết kiệm nhiều byte hơn
Jörg Hülsermann

@ JörgHülsermann Tôi không nhận được $argngợi ý. Tôi nhận thức được "X"->Xmánh khóe nhưng có lẽ tôi đã quên nó khi tôi viết giải pháp này. Tôi viết mã PHP từ năm 2002 nhưng cho đến hôm nay tôi không nhận thấy rằng PHP cung cấp chop()hàm. Cảm ơn bạn cho gợi ý này.
axiac

7

Perl, 702 613 546 474 439 338 260 byte

Cảm ơn Dom Hastings vì sự giúp đỡ và phiên bản siêu nhân của anh ấy.
Mã sử ​​dụng một mảng 2D.

Phiên bản của 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$/}

Phiên bản chơi gôn ít hơn của tôi là 339 byte (để tham khảo):

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

Kiểm tra

$ 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
Nếu bạn không sử dụng use strict;, bạn không cần tất cả các mys, điều này sẽ giúp bạn tiết kiệm ít nhất một vài byte. Cũng ==ngắn hơn eqkể từ sau đòi hỏi không gian.
Alex A.

1
Nếu tôi không nhầm, bạn chỉ gọi $mmột lần, vì vậy thay vì lưu trữ đối số dòng lệnh dưới dạng một biến, bạn có thể gọi trực tiếp vào split, tức là @m=split(',',$ARGV[0]).
Alex A.

1
Xin chào @LukStorms, rất vui khi thấy nhiều người chơi gôn Perl hơn! Một vài điều để giúp tiết kiệm một số byte! Các biến $d$sbiến của bạn có thể được lấy bằng regex để tiết kiệm cho bạn một số byte ($d,$s)=/^(.)(.+)$/và tất cả đều foreachcó thể for(vì chúng giống nhau. Bạn cũng có thể lưu một số ký tự thay thế một số ký tự này bằng map{... }@xvì bạn có thể bỏ qua parens xung quanh mục lặp (điều này hoạt động tốt nếu bạn phải chứa các vòng lặp khác). Nếu bạn đang sử dụng, $ARGV[0]bạn có thể thay thế mục đó bằng pop, nhưng nếu bạn sử dụng tập lệnh như trong thì perl script.pl <<< "text"bạn có thể sử dụng <>thay thế!
Dom Hastings

1
Nếu bạn muốn giữ tập lệnh bằng args, bạn có thể sử dụng popđể lưu một vài. Thay vì use Swtichswitch/ các casecâu lệnh, bạn có thể thực hiện các kiểm tra riêng lẻ có thể giúp bạn tiết kiệm byte. Một cái gì đó như $y-="N"eq$dsẽ làm việc là tốt (vì đúng 1và sai là ''). Thông thường, bạn có thể có các từ như barewords, vì vậy $y-=N eq$dsẽ làm việc! Có một số biến ma thuật bạn có thể sử dụng để tiết kiệm byte, $/'\n'$"' ', nhưng đôi khi một chữ giúp đỡ newline sức tiết kiệm một char quá. Một mẹo (bẩn!) Khác là nhiều nhiệm vụ để tiết kiệm thêm một vài thứ, như $a=0;$b=0;có thể $a=$b=0.
Dom Hastings

1
Chỉ một vài điều nữa, tôi hứa. Tôi hy vọng đây là thông tin tốt nhất mà bạn theo dõi! Thiếu parens trong các cuộc gọi chức năng là một thay đổi khá chuẩn, vì vậy substr($_,0,1)có thể substr$_,0,1. Postfix cho các vòng lặp và nếu kiểm tra cũng có thể hữu ích như trong for(@c){...}so với ...for@cnhưng bạn không thể sử dụng ;mã, thay vào đó bạn phải phân tách bằng dấu phẩy (không phải lúc nào cũng hoạt động khi bạn gọi hàm). Có rất nhiều lời khuyên tuyệt vời cũng có tại codegolf.stackexchange.com/questions/5105/ . Chúc may mắn!
Dom Hastings

5

Python 2, 394 byte

Chạy chương trình sau đó dán vào đầu vào tiêu chuẩn, vd "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])

Điều này không được tối ưu hóa cho lắm. Đầu tiên nó chạy qua đầu vào để ghi lại đường dẫn. Sau đó, nó thực hiện một số phép toán để xác định vị trí và kích thước bắt đầu đúng o. Sau đó, nó chạy qua một lần nữa và thiết lập các mục thích hợp olà một trong số đó >v<^X. Sự thông minh chính là trong việc sử dụng lại chức năng tương tự cho cả hai đường ngang này.


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 thường không cạnh tranh một chút, vì vậy điều này thật thú vị.

Ung dung

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

Tôi đã thử vận ​​may của mình trong PHP, kết quả khá dài, tôi vẫn muốn đăng nó, chỉ để cho vui.

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

Ung dung

<?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
Có thể giảm rất nhiều. Chẳng hạn, bạn chỉ có thể viết for(;$i++<$f;), cố gắng loại bỏ các dấu ngoặc không cần thiết, sử dụng các hằng số không xác định ( N) thay vì các chuỗi ( 'N'),
Vượt

1
Thay vì ifs, hãy thử sử dụng toán tử ba hoặc logic ands. Ngoài ra, nó sẽ hữu ích nếu bạn sử dụng PHP4.1 và sử dụng mảng GET với các điểm.
Ismael Miguel

3

JavaScript (ES6), 244 249 274

Không gian hàng đầu và dòng mới được thêm vào cho rõ ràng và không được tính, ngoại trừ dòng mới gần cuối trong cuộc gọi tham gia, đó là đáng kể và được tính.

Kiểm tra chạy đoạn mã (chỉ là ECMAScript 6, Firefox và 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);}}

Phiên bản bị đánh cắp:

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

Phân bổ bộ nhớ động không khó hơn nhiều, nhưng malloc quá dài để nhận dạng được sử dụng trong môn đánh gôn. Tôi cảm thấy nên có một số loại tiêu đề PCG.h tự động được bao gồm một cách hợp pháp để chơi gôn trong c, chỉ để rút ngắn một số định danh.


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 thường gặp - 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))))

Thực hiện không có mảng: in từ trên xuống dưới, từ trái sang phải.

  • Phân tích cú pháp và mở rộng hướng thành một dấu vết của (x y char)các yếu tố:

    Đầu vào "N3" đơn giản tạo ra ((0 0 #\^) (0 -1 #\^) (0 -2 #\X))

  • Ngoài ra, tính toán tối thiểu xy
  • Sắp xếp theo dõi kết quả theo ytrước và sau đó theox
  • Lặp lại danh sách đã sắp xếp trong khi di chuyển con trỏ

    1. Thêm dòng mới và dấu cách để di chuyển con trỏ hiện tại vào đúng vị trí
    2. Khi ở vị trí x - minx, y - miny, in ký tự bạn cần

Ví dụ

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

Kết quả:

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

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.