ขุมทรัพย์โจรสลัด


18

การค้นหาขุมทรัพย์ที่ซ่อนโดยโจรสลัดนั้นง่ายมาก ทุกสิ่งที่คุณต้องการสำหรับแผนที่นี้คือ เป็นที่ทราบกันอย่างกว้างขวางว่าโจรสลัดวาดแผนที่ด้วยมือและอธิบายอัลกอริทึมเพื่อหาสถานที่ด้วยวิธีต่อไปนี้: "ยืนใกล้ต้นปาล์มโดดเดี่ยวทำ 30 ก้าวสู่ป่า 15 ก้าวสู่ทะเลสาบ ... "

การเดินทางผ่านเส้นทางดังกล่าวมักจะเป็นโอกาสที่ดีที่จะได้เห็นทิวทัศน์ ... อย่างไรก็ตามในปัจจุบันไม่มีใครมีเวลา นั่นเป็นสาเหตุที่ผู้แสวงหาสมบัติขอให้คุณเขียนโปรแกรมที่จะระบุตำแหน่งที่แน่นอนของขุมทรัพย์โดยใช้แผนที่ที่กำหนด


อินพุต

อินพุตประกอบด้วยคำสั่งหลายคำสั่ง<Direction> <Distance>คั่นด้วยเครื่องหมายจุลภาค (ซึ่งตามด้วยหนึ่งช่องว่างแต่ละคำสั่ง)

เส้นทางเป็นหนึ่งในสิ่งต่อไปนี้:
N- เหนือ, S- ใต้, E- ตะวันออก, W- ตะวันตก,
NE- ตะวันออกเฉียงเหนือ, NW- ตะวันตกเฉียงเหนือ, SE- ตะวันออกเฉียงใต้, SW- ตะวันตกเฉียงใต้

ระยะทางเป็นจำนวนเต็ม (1 ถึง 1,000)

เอาท์พุต

ผลลัพธ์คือพิกัดที่คุณสิ้นสุดหลังจากทำตามคำแนะนำด้วยทศนิยมสามตำแหน่งคั่นด้วยเครื่องหมายจุลภาคและช่องว่าง ตำแหน่งเริ่มต้นมีพิกัดเป็นศูนย์ (0, 0)

พิกัดแรกคือX (ทิศตะวันออกหมายถึงพิกัดที่มีขนาดใหญ่กว่าศูนย์ส่วนตะวันตกหมายถึงน้อยกว่าศูนย์)
ที่สองพิกัดY (นอร์ทหมายมากขึ้นกว่าศูนย์ภาคใต้หมายถึงน้อยกว่าศูนย์)


ตัวอย่าง

1 N 3, E 1, N 1, E 3, S 2, W 1

    3.000, 2.000

2 NW 10

    -7.071, 7.071

3 NE 42, NW 42, SE 42, SW 42

    0.000, 0.000


แหล่งที่มา (เป็นภาษายูเครน) รูปแบบอินพุตแตกต่างกัน


8
คะแนนโบนัสสำหรับการทำมันในโลโก้? ;)
Peter Taylor

@Peter รูปแบบผลลัพธ์มีความเข้มงวด ... แต่เราจะเห็นว่าคนชอบภาพ: D
Oleh Prypin

1
-3.000, 2.000เอาท์พุทตัวอย่างแรกที่ควรจะเป็น
Lowjacker

กับ UCB (print (word (form xcor 4 3) ",) (form ycor 4 3))โลโก้รูปแบบออกสามารถได้รับเป็น แต่ฉันไม่แน่ใจว่าการแยกวิเคราะห์อินพุตง่ายเพียงใด
Peter Taylor

@ Lowjacker ใช่ขอบคุณ ที่จริงแล้วอินพุตนั้นผิด
Oleh Prypin

คำตอบ:


7

ทับทิม 1.9, 175 171 162 153 130 120 117

l=0
gets.scan(/(\w+) (\d+)/){|d,n|l+=n.to_i*?i.to_c**%w[E NE N NW W SW S SE].index(d).quo(2)}
puts'%.3f, %.3f'%l.rect

?i.to_cสามารถย่อให้เหลือ1.i-4 ไบต์
MegaTom

3

Haskell (291)

import Text.Printf
d=sqrt(0.5)
f"N"n(x,y)=(x,y+n)
f"S"n(x,y)=(x,y-n)
f"E"n(x,y)=(x+n,y)
f"W"n(x,y)=(x-n,y)
f[a,b]n(x,y)=(s,t)where(s,_)=f[b](d*n)(x,y);(_,t)=f[a](d*n)(x,y)
p[]=(0,0)
p(a:b:c)=f a(read b::Float)$p c
s(a,b)=printf"%.3f, %.3f"a b
main=getLine>>=putStrLn.s.p.words.filter(/=',')

วิธีการเกี่ยวกับการเปลี่ยน defintion ของ f เพื่อใช้ยามแบบ? พวกเขามีคุณสมบัติที่ดีที่ไม่จำเป็นต้องมีตัวแบ่งบรรทัดและควรจะเน้นมากขึ้นในกรณีนี้ นอกจากนี้ยังใช้การโต้ตอบ
FUZxxl

3

C99 (319 ตัวอักษร)

#define B ;break;
#include<math.h>
#include<stdio.h>
float x,y,w,z,j;int
main(void){int
k;char
c[3];while(scanf("%s%d,",c,&k)==2){j=k;w=1;switch(c[1]){case'E':w=3;default:w-=2;j=sqrt(k*k/2)B
case
0:w=z=0;}switch(*c){case'N':z=1
B
case'S':z=-1
B
case'E':w=1
B
default:w=-1;}x+=w*j;y+=z*j;}printf("%5.3f, %5.3f\n",x,y);}

การป้อนข้อมูลในstdin, การทดสอบการทำงานที่ ideone :)


3

Python, 158 154 150 ตัวอักษร

p=0j
for s in raw_input().split(','):c,d=s.split();v=sum(dict(N=1j,E=1,S=-1j,W=-1)[x]for x in c);p+=v*int(d)/abs(v)
print'%.3f, %.3f'%(p.real,p.imag)

คุณมี 157 ตัวอักษรไม่ใช่ 158.
Lowjacker

ฉันเดาว่าฉันไม่ต้องการ แต่ปกติฉันจะนับจำนวนขึ้นบรรทัดใหม่
Keith Randall

[157] บรรทัดที่ 1: D=dict(N=1j,E=1,S=-1j,W=-1)[153] บรรทัดที่ 2: jจำเป็นจริงๆหรือ [152] บรรทัดที่ 3-4: หากคุณเปลี่ยนไปใช้ Python 3, raw_inputinputและถึงแม้ว่าคุณจะต้องใช้วงเล็บหลังprintคุณก็ประหยัด 2 ตัวอักษร [150]
Oleh Prypin

1
@BlaXpirit: ขอบคุณสำหรับการเพิ่มประสิทธิภาพ dict เจที่จำเป็นในสาย 2 ในกรณีที่ทุกทิศทางที่มีอีและดับบลิวพีที่เกิดความต้องการที่จะเป็นที่ซับซ้อนสำหรับการ.realและ.imagการทำงาน
Keith Randall

1
ชั้นเรียนที่มีทั้งแบบimagและrealattrs ...
JBernardo

3

JavaScript, 179 164 170 168 158 156 153 ตัวอักษร

prompt(X=Y=0).replace(/(N|S)?(.)? (\d+)/g,
        function(m,y,x,n){
            n/=x&&y?Math.SQRT2:1
            Y+=y?y<'S'?n:-n:0
            X+=x?x<'W'?n:-n:0
        })
alert(X.toFixed(3)+', '+Y.toFixed(3))
  • 170: ปัญหาความแม่นยำคงที่
  • 168: แทนที่ด้วย(E|W)regex ด้วย(.)
  • 158: แทนที่ตรรกะซ้ำในฟังก์ชันด้วยตัวแปร d
  • 156: นำมาใช้ใหม่nแทนที่จะเป็นตัวแปรใหม่d
  • 153: โดยส่วนตัวแล้วฉันคิดว่าการแก้ไขนี้ทำให้น่าเกลียดกว่าสิบเท่า แต่สั้นกว่าสามตัวอักษร มันขึ้นอยู่กับพฤติกรรมที่ไม่ได้มาตรฐานที่คุณสามารถเรียกวัตถุ RegExp เป็นฟังก์ชั่น: /./g('string')เป็นเช่นเดียวกับ/./g.exec('string'):

    for(p=prompt(X=Y=0),R=/(N|S)?(.)? (\d+)/g;[,y,x,n]=R(p)||0;X+=x?x<'W'?n:-n:0)n/=x&&y?Math.SQRT2:1,Y+=y?y<'S'?n:-n:0;alert(X.toFixed(3)+', '+Y.toFixed(3))


1
น่าเสียดายที่ q = .707 ล้มเหลวอินพุต "NW 10" เนื่องจากข้อผิดพลาดในการปัดเศษ ฉันคิดว่าคุณต้องการ "q = Math.SQRT1_2" ซึ่งเพิ่ม 8 ตัวอักษร คุณสามารถแทนที่ "(E | W) ได้ไหม" ด้วย "(.)?" เนื่องจากคุณได้กำหนดทิศเหนือ / ทิศใต้ / ทั้งสองและอินพุตนั้นมีรูปแบบที่ดีประหยัด 2 ตัวอักษร
DocMax

ขอบคุณสำหรับ bit regex สำหรับปัญหาเรื่องความแม่นยำฉันใช้ SQRT2 แทนและเปลี่ยนการคูณเป็นการหาร
Casey Chu

2

Haskell, 199 ตัวอักษร

import Text.Printf
import Complex
i=0:+(1::Float)
e 'S'= -i
e d=i^mod(fromEnum d-1)4
g p(d:s:t)=g(p+(signum.sum.map e)d*(fst(reads s!!0):+0))t
g(x:+y)[]=printf"%.3f, %.3f"x y
main=interact$g 0.words

1

สกาล่า ( 367 , 332)

var (x,y,s)=(.0,.0,.7071);args.mkString(" ").split(",").foreach{m=>val a=m.trim.split(" ");var (n,u,v)=(a(1).toInt,.0,.0);a(0) match{case "N"=>v=1;case "S"=>v= -1;case "E"=>u=1;case "W"=>u= -1;case "NW"=>{u= -s;v=s};case "NE"=>{u=s;v=s};case "SW"=>{u= -s;v= -s};case "SE"=>{u=s;v= -s}};x += n*u;y += n*v};printf("%1.3f %1.3f\n",x,y)

1

Java (459) (445) (402) (382) (363) (352)

import java.util.*;class
M{public
static void main(String[]a){double
x=0,y=0;Scanner
s=new
Scanner(System.in);s.useDelimiter("\\W+");while(s.hasNext()){String
d=s.next();double
z=Math.sqrt(d.length());int
w=s.nextInt();y+=(d.contains("N")?w:d.contains("S")?-w:0)/z;x+=(d.contains("E")?w:d.contains("W")?-w:0)/z;}System.out.format("%1.3f %1.3f",x,y);}}

อินพุต stdin


1

PowerShell, 178

$input-split','|%{,@{N=0,1
NE=($s=.707106781186548),$s
E=1,0
SE=$s,-$s
S=0,-1
SW=-$s,-$s
W=-1,0
NW=-$s,$s}[($a=-split$_)[0]]*$a[1]}|%{$x+=$_[0]
$y+=$_[1]}
'{0:N3}, {1:N3}'-f$x,$y

อาจทำให้เสียได้สูงสุด 10 ตัวอักษรโดยลดความแม่นยำของ√2 / 2



0

Groovy (215)

x=0.0;y=0.0;args.join(' ').split(', ').each{d=it.split(' ');c=d[0]==~/../?Math.sqrt(2):1;s=d[1] as int;a=['N':1,'S':-1,'E':1,'W':-1];m=d[0]=~/N|S/;y+=m?a[m[0]]*(s/c):0;m=d[0]=~/E|W/;x+=m?s/c*a[m[0]]:0};print "$x,$y"

อ่านอินพุตเป็นอาร์กิวเมนต์ของโปรแกรม ตัวอย่าง:

groovy golf.groovy NW 10, SW 10, W 10


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