해적 보물


18

해적들이 숨겨둔 보물을 찾는 것은 정말 쉽습니다. 이것에 필요한 모든 것은지도입니다. 해적은 손으로지도를 그리고 다음과 같은 방식으로 장소를 찾기위한 알고리즘을 설명하는 것으로 널리 알려져 있습니다.

이러한 경로를 통한 여행은 일반적으로 경치를 볼 수있는 좋은 기회입니다 ... 그러나 오늘날 아무도 그럴 시간이 없습니다. 그렇기 때문에 보물 구직자들은 주어진지도를 사용하여 보물의 정확한 위치를 결정하는 프로그램을 작성하도록 요청했습니다.


입력

입력은 여러 개의 명령어로 구성되며 <Direction> <Distance>쉼표로 구분됩니다 (각 뒤에 공백이 하나씩).

방향 은 다음 중 하나입니다
N.-북쪽, S-남쪽, E-동쪽, W-서쪽,
NE-북동쪽, NW-북서쪽, SE-남동쪽, SW-남서쪽.

거리는 정수 (1 ~ 1000)입니다.

산출

결과는 지침을 완료 한 후 쉼표와 공백으로 구분 된 소수점 이하 세 자리로 끝나는 좌표입니다. 시작 위치는 0 좌표 (0, 0)를 갖습니다.

첫 번째 좌표는 X입니다 (East는 0보다 큰 좌표를 의미하고 West는 0보다 작음을 의미합니다).
두 번째 좌표는 Y입니다 (North는 0 보다 크며 South는 0보다 습니다).


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

    3.000, 2.000

2. NW 10

    -7.071, 7.071

삼. 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)). 그러나 입력을 구문 분석하는 것이 얼마나 쉬운 지 잘 모르겠습니다.
피터 테일러

@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_c1.i-4 바이트 로 단축 될 수 있습니다 .
MegaTom

3

하스켈 (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(/=',')

패턴 가드를 사용하도록 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

파이썬 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)

실제로 158
자가

필요하지는 않지만 일반적으로 후행 줄 바꿈을 계산합니다.
Keith Randall

[157] 1 행 : D=dict(N=1j,E=1,S=-1j,W=-1)[153] 2 행 : j정말로 필요합니까? [152] 3-4 행 : raw_input→ Python 3으로 전환하면 → input뒤에 괄호를 사용해야하더라도 print2자를 절약 할 수 있습니다 [150]
Oleh Prypin

1
@BlaXpirit : dict 최적화에 감사드립니다. 모든 방향이 E와 W 인 경우 j는 2 행에 필요합니다. 결과 p는 복잡 .real하고 .imag작동해야합니다.
Keith Randall

1
INT 클래스는 모두 가지고 imagreal... 바인드합니다을
JBernardo

3

자바 스크립트, 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)정규식으로 대체(.)
  • 158 : 함수의 반복 논리를 변수로 대체 d
  • 156 : n새로운 변수 대신 재사용d
  • 153 : 개인적으로,이 편집으로 인해 10 배 더 추한 것으로 생각되지만 3 자 더 짧습니다. 그것은 당신이 정규식 함수로 객체를 호출 할 수있는 표준이 아닌 행동을 기반으로 : /./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"입력에 실패합니다. 8자를 추가하는 "q = Math.SQRT1_2"가 필요하다고 생각합니다. 반면에 "(E | W)?"를 바꿀 수 있습니다. "(.)?" 이미 북쪽 / 남쪽 / 아무것도 설정하지 않았고 입력이 잘 구성되어 2 문자를 절약했기 때문입니다.
DocMax

정규식 비트 주셔서 감사합니다. 정확성 문제에 대해서는 대신 SQRT2를 사용하여 곱셈을 나누기로 전환했습니다.
Casey Chu

2

하스켈, 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

자바 (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);}}

표준 입력


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

√2 / 2의 정확도를 줄이면 최대 10자를 잃을 수 있습니다.



0

그루비 (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.