Tesoro pirata

18

Encontrar un tesoro escondido por piratas es realmente fácil. Todo lo que necesitas para esto es un mapa. Es ampliamente conocido que los piratas dibujan mapas a mano y describen el algoritmo para encontrar un lugar de la siguiente manera: "Párate cerca de una palmera solitaria, haz 30 pasos hacia el bosque, 15 hacia el lago, ..."

Un viaje a través de esa ruta suele ser una gran oportunidad para ver el paisaje ... Sin embargo, hoy en día nadie tiene tiempo para eso. Es por eso que los buscadores de tesoros te han pedido que escribas un programa que determine la ubicación exacta de un tesoro usando un mapa dado.


Entrada

La entrada consta de varias instrucciones <Direction> <Distance>, separadas por comas (seguidas de un espacio en blanco cada una).

La dirección es una de las siguientes:
N- Norte, S- Sur, E- Este, W- Oeste,
NE- Noreste, NW- Noroeste, SE- Sureste, SW- Suroeste.

La distancia es un número entero (1 a 1000).

Salida

El resultado son las coordenadas donde terminas después de terminar las instrucciones, con tres decimales, separadas por una coma y un espacio en blanco. La ubicación de inicio tiene coordenadas cero (0, 0).

La primera coordenada es X (Este significa coordenadas mayores que cero, Oeste significa menos que cero).
La segunda coordenada es Y (Norte significa más que cero, Sur significa menos que cero).


Ejemplos

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


Fuente (en ucraniano). El formato de entrada es diferente allí.

Oleh Prypin
fuente
8
¿Puntos de bonificación por hacerlo en Logo? ;)
Peter Taylor
@ Peter El formato de salida es estricto ... Pero veremos si a la gente le gusta la imagen: D
Oleh Prypin
1
El primer ejemplo de salida debería ser -3.000, 2.000.
Lowjacker
con el logotipo de UCB, el formato de salida se puede obtener como (print (word (form xcor 4 3) ",) (form ycor 4 3)). Pero no estoy seguro de lo fácil que sería analizar la entrada.
Peter Taylor
@Lowjacker Sí, gracias. En realidad, la entrada fue incorrecta.
Oleh Prypin

Respuestas:

7

Ruby 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
Lowjacker
fuente
?i.to_cse puede acortar a 1.i-4 bytes.
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(/=',')
marinus
fuente
¿Qué tal cambiar la definición de f para usar guardias de patrones? Tienen la buena propiedad de no requerir un salto de línea y deberían ser más breves en este caso. Además, use interactuar.
FUZxxl
3

C99 (319 caracteres)

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

entrada stdin, prueba ejecutada en ideone :)

pmg
fuente
3

Python, 158 154 150 caracteres

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)
Keith Randall
fuente
En realidad tienes 157 caracteres, no 158.
Lowjacker
Supongo que no necesito hacerlo, pero generalmente cuento la nueva línea final.
Keith Randall
[157] Línea 1: D=dict(N=1j,E=1,S=-1j,W=-1)[153] Línea 2: ¿es jrealmente necesaria? [152] Líneas 3-4: si cambias a Python 3, raw_inputinput, y aunque tienes que usar paréntesis después print, guardas 2 caracteres [150]
Oleh Prypin
1
@BlaXpirit: Gracias por la optimización dict. La j es necesaria en la línea 2 en caso de que todas las direcciones sean E y W. La p resultante debe ser compleja para .realy .imagpara funcionar.
Keith Randall
1
int class tiene ambos imagy realatributos ...
JBernardo 05 de
3

JavaScript 179 164 170 168 158 156 153 caracteres

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: problema de precisión fijo
  • 168: reemplazado (E|W)en regex con(.)
  • 158: lógica repetitiva reemplazada en función con variable d
  • 156: reutilizado en nlugar de una nueva variabled
  • 153: Personalmente, creo que esta edición lo hace diez veces más feo, pero es tres caracteres más corto. Se basa en el comportamiento no estándar al que puede llamar objetos RegExp como funciones: /./g('string')es lo mismo que /./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))

Casey Chu
fuente
1
Desafortunadamente, q = .707 falla la entrada "NW 10" debido a errores de redondeo; Creo que necesita "q = Math.SQRT1_2" que agrega 8 caracteres. Por otro lado, puede reemplazar "(E | W)?" con "(.)?" dado que ya ha establecido norte / sur / ninguno y la entrada está bien formada, ahorrando 2 caracteres.
DocMax
Gracias por la expresión regular. En cuanto al problema de precisión, usé SQRT2 en su lugar y cambié la multiplicación a división.
Casey Chu
2

Haskell, 199 caracteres

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
hammar
fuente
1

Scala ( 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)
Lalith
fuente
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);}}

entrada estándar

la verdad
fuente
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

Esto probablemente puede perder hasta 10 caracteres al reducir la precisión de √2 / 2.

Joey
fuente
1

C (gcc) , 155 152 bytes

-3 bytes gracias a ceilingcat

float x,y,l;D;main(d){for(;scanf("%s%f,",&d,&l)>0;y+=d^78?d^83?0:-l:l)D=d,l/=D>99?D/=256,d&=255,sqrt(2):1,x+=D^87?D^69?0:l:-l;printf("%.3f, %.3f",x,y);}

Pruébalo en línea!

gastropner
fuente
0

Maravilloso (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"

lee la entrada como argumentos del programa. Ejemplo:

groovy golf.groovy NW 10, SW 10, W 10
TheBigS
fuente
0

Perl 5 -n , 122 bytes

s,(N|S)?(E|W)? (\d+),$d=$3/($1&$2?2**.5:1);$x+=$2&&$d*(-1)**($2gt F);$y+=$1&&$d*(-1)**($1gt O),ge;printf"%.3f, %.3f",$x,$y

Pruébalo en línea!

Xcali
fuente
0

J , 93 bytes

[:0j3&":@+.@(1#.".@>@{:*(0j1^2%~i.8){~<;._1@' E NE N NW W SW S SE'i.{.)@|:[:(<;._1);._1', ',]

Pruébalo en línea!

Jonás
fuente