Yarr! แผนที่สู่ขุมทรัพย์ที่ซ่อนอยู่!


49

บทนำ

"Yarr !! เรามีแลดดี้ที่เรียกตัวเองว่า" โปรแกรมเมอร์ "ทำแผนที่ t 'สมบัติที่ซ่อนเร้นของเรา! แต่' tis เขียนด้วยตัวอักษร n 'ตัวเลขแปลก'!" E5, N2, E3 "... มันคืออะไร หมายความว่าอะไร Madness! ไม่สามารถเขียนแผนที่ขุมทรัพย์ที่เหมาะสมได้ด้วย 'cretin ที่ไร้ประโยชน์จงแก้ไขมันเถิดพวกเรา! เราจะมอบสมบัติส่วนแบ่งให้คุณ!

คำอธิบายการท้าทาย

กลุ่มโจรสลัดกำลังประสบปัญหาในการอ่านแผนที่ขุมทรัพย์ คุณสามารถเขียนโปรแกรมเพื่อแปลงเป็นรูปแบบโจรสลัด ...

ในฐานะที่เป็นอินพุทคุณจะได้รับแผนที่ขุมทรัพย์ดั้งเดิม มันคือรายการของสตริงที่คั่นด้วยเครื่องหมายจุลภาคแต่ละสตริงซึ่งประกอบด้วยส่วนของตัวอักษร (ซึ่งบอกโจรสลัดว่าต้องใช้ทิศทางใดในการเดิน) และส่วนของตัวเลข (ซึ่งบอกให้พวกโจรสลัดรู้ว่ามีกี่ก้าวในทิศทางนั้น) ตัวอย่างเช่นแผนที่ขุมทรัพย์ต่อไปนี้:

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
เราได้รับอนุญาตให้มีช่องว่างต่อท้ายในแต่ละบรรทัดหรือไม่ จำนวนจะน้อยกว่าสิบเสมอหรือไม่
Downgoat

9
ฉันคิดว่าXควรทำเครื่องหมายขั้นตอนหลังจากการย้ายครั้งสุดท้ายเช่นการเคลื่อนไหวอื่น ๆ จะถูกนับ ลองนึกภาพขั้นตอนสุดท้ายคือ N3: คุณเดินสามก้าวไปทางทิศเหนือและขุด แต่ไม่มีอะไรที่นี่คุณต้องเดิน 2 ก้าวแทน ฉันไม่คิดว่าคุณจะรักษากฎที่มีอยู่เพราะมันเพิ่มกรณีมุมเล็ก ๆ ที่จะจัดการ แต่จำสิ่งที่เกิดขึ้นกับหนุ่มที่
coredump

6
@coredump หรือบางทีเราต้องการทำให้โจรสลัดเข้าใจผิดเพื่อที่เราจะได้เอาสมบัติไปใช้กับตัวเราเอง) ไม่หรอกคุณกำลังถูกโจรสลัดกำลังขุดหนึ่งก้าวเร็วเกินไป เนื่องจากมีสามคำตอบฉันจะรักษากฎไว้เพื่อหลีกเลี่ยงการทำให้โซลูชันที่มีอยู่ใช้ไม่ได้
absinthe

4
@ jpmc26 ดีโจรสลัดเหล่านี้ไม่ทราบว่ามากของตัวอักษร ... พวกเขาใช้เวลาไม่กี่ปีที่ผ่านมาที่ C :)
Absinthe

4
ตัวอย่างที่สี่เป็นเพียงการ
หลอกล่อ

คำตอบ:


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 's คำตอบ

รุ่นดั้งเดิมที่ใช้[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 บังคับให้เป็นความคิดที่ดี - เพิ่งเปิด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
นั่นเป็นวิธีที่ดีในการแยกแถลงการณ์! แน่นอนว่าสามารถอ่านได้มากกว่าการวางทุกอย่างในบรรทัดเดียวและคั่นด้วยเครื่องหมายอัฒภาค หากฉันอาจเสนอคำแนะนำของฉัน: คุณสามารถบันทึก byte โดยการย้าย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
@Undefined ฟังก์ชั่นที่คุณอาจต้องการที่จะใช้ชวเลขสำหรับ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); ด้วยการแทนที่ a whileด้วยการforวนซ้ำและบีบการกำหนดลงไป (ไม่สามารถใช้การwhileวนซ้ำได้) ฉันบันทึกไบต์อื่น


ฉันชอบที่จะเห็นรูปแบบที่ไม่ดี
Lars Ebert

1
@ LarsEbert ฉันอัปเดตคำตอบพร้อมลิงก์ไปยังโค้ดที่ไม่ได้รับการแก้ไข ฉันตรวจสอบวิธีการแก้ปัญหาของคุณทันที (ไม่ได้ทำมาก่อน); เราได้ใช้อัลกอริทึมเดียวกันโดยทั่วไปแล้ว คุณจัดการกับขั้นตอนสุดท้ายได้ดีกว่าของฉัน ฉันสามารถดึง 25 $count --;ไบต์มากขึ้นถ้าผมใช้
axiac

$argnบันทึก 3 ไบต์chopบันทึก 1 ไบต์"X"-> Xใช้ค่าคงที่บันทึกไบต์เพิ่มเติม
JörgHülsermann

@ JörgHülsermannฉันไม่ได้$argnรับคำใบ้ ฉันรู้ถึง"X"->Xเคล็ดลับ แต่ฉันอาจลืมไปเมื่อฉันเขียนโซลูชันนี้ ฉันเขียนโค้ด PHP ตั้งแต่ปี 2002 แต่จนถึงวันนี้ฉันไม่ได้สังเกตว่า PHP มีchop()ฟังก์ชั่น ขอบคุณสำหรับคำแนะนำนี้
axiac

7

Perl, 702 613 546 474 439 338 260 ไบต์

ขอบคุณ Dom Hastings สำหรับความช่วยเหลือและรุ่นที่มีพลังสูงของเขา
รหัสใช้อาร์เรย์ 2 มิติ

รุ่นโดย 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$/}

รุ่น golfer น้อยกว่าของฉันที่ 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ตั้งแต่หลังต้องมีช่องว่าง
Alex A.

1
ถ้าฉันไม่ผิดคุณเพียงโทร$mครั้งเดียวดังนั้นแทนที่จะเก็บอาร์กิวเมนต์บรรทัดคำสั่งเป็นตัวแปรที่คุณสามารถเรียกมันโดยตรงในคือsplit @m=split(',',$ARGV[0])
Alex A.

1
สวัสดี @LukStorms ดีใจที่ได้เห็นนักกอล์ฟ Perl เพิ่มเติม! บางสิ่งที่จะช่วยประหยัดไบต์! ตัวแปร$dและของคุณ$sสามารถถูกจับได้โดยใช้ regex เพื่อช่วยคุณประหยัดไบ($d,$s)=/^(.)(.+)$/ท์ได้และทุกอย่างforeachเป็นไปได้for(เหมือนกันคุณสามารถบันทึกตัวอักษรบางตัวแทนบางตัวด้วยmap{... }@xเนื่องจากคุณไม่สนใจ parens รอบรายการที่มีการทำซ้ำ (สิ่งนี้ใช้ได้ดีถ้าคุณต้องมีลูปอื่น ๆ ) ถ้าคุณใช้$ARGV[0]คุณสามารถแทนที่มันด้วยป๊อป แต่ถ้าคุณใช้สคริปต์เหมือนที่perl script.pl <<< "text"คุณสามารถใช้<>แทน!
Dom Hastings

1
หากคุณต้องการเก็บสคริปต์โดยใช้ args คุณสามารถใช้popเพื่อบันทึกคู่ แทนที่จะใช้use Swtichและswitch/ casestatement คุณสามารถทำการตรวจสอบเดี่ยว ๆ ซึ่งอาจช่วยให้คุณประหยัดไบต์ สิ่งที่ชอบ$y-="N"eq$dจะทำงานได้ดี (เนื่องจากความจริง1และเท็จคือ'') บ่อยครั้งที่คุณสามารถมีคำว่า barewords ดังนั้น$y-=N eq$dจะได้ผล! มีบางตัวแปรมายากลที่คุณสามารถใช้เพื่อบันทึกไบต์$/เป็น'\n'และ$"เป็น' 'แต่บางครั้งขึ้นบรรทัดใหม่ที่แท้จริงอาจจะช่วยประหยัดถ่านเกินไป อื่น ๆ (สกปรก!) เคล็ดลับคือการกำหนดหลายที่จะบันทึกไม่กี่มากขึ้นในขณะที่สามารถ$a=0;$b=0; $a=$b=0
Dom Hastings

1
อีกไม่กี่ฉันสัญญา ฉันหวังว่านี่จะเป็นข้อมูลที่คุณหลังจาก! การพลาดฟัง parens ในการเรียกใช้ฟังก์ชันเป็นการเปลี่ยนแปลงมาตรฐานที่ค่อนข้างดีดังนั้นจึงsubstr($_,0,1)เป็นsubstr$_,0,1ไปได้ Postfix สำหรับลูปและหากการตรวจสอบมีประโยชน์เช่นเดียวfor(@c){...}กับใน...for@cแต่คุณไม่สามารถใช้;ในโค้ดได้คุณจะต้องคั่นด้วยเครื่องหมายจุลภาคแทน (ซึ่งจะไม่ทำงานเมื่อคุณเรียกใช้ฟังก์ชัน) มีเคล็ดลับที่ดีมากจึงยังอยู่ที่codegolf.stackexchange.com/questions/5105/... โชคดี!
Dom Hastings

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 ไม่ได้มีการแข่งขันเพียงเล็กน้อยดังนั้นมันสนุก

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 ผลลัพธ์ค่อนข้างยาวฉันยังต้องการโพสต์เพื่อความสนุก

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
สามารถลดลงได้มาก ตัวอย่างเช่นคุณสามารถเขียนfor(;$i++<$f;)ลองลบวงเล็บเหลี่ยมที่ไม่จำเป็นออกใช้ค่าคงที่ที่ไม่ได้กำหนด ( N) แทนสตริง ( 'N'), ...
Blackhole

1
แทนที่จะifลองใช้ตัวดำเนินการ trenary หรือตรรกะและ นอกจากนี้ยังจะช่วยถ้าคุณใช้ PHP4.1 และใช้อาร์เรย์ GET กับคะแนน
Ismael Miguel

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 นั้นยาวเกินกว่าที่จะใช้ในการเขียนโค้ดกอล์ฟได้ ฉันรู้สึกว่าควรมี PCG.h บางส่วนหัวที่ถูกต้องตามกฎหมายรวมอัตโนมัติสำหรับการเล่นกอล์ฟใน c เพียงเพื่อย่อบางตัวบ่งชี้


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

เสียงกระเพื่อมสามัญ - 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'

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.