Trésor de pirate

18

Trouver un trésor caché par des pirates est vraiment facile. Tout ce dont vous avez besoin est une carte. Il est bien connu que les pirates dessinent des cartes à la main et décrivent l'algorithme pour trouver un endroit de la manière suivante: "Tenez-vous près d'un palmier solitaire, faites 30 pas vers la forêt, 15 vers le lac, ..."

Un voyage à travers un tel itinéraire est généralement une excellente occasion de voir le paysage ... Cependant, de nos jours, personne n'a le temps pour cela. C'est pourquoi les chercheurs de trésors vous ont demandé d'écrire un programme qui déterminerait l'emplacement exact d'un trésor en utilisant une carte donnée.


Contribution

L'entrée se compose de plusieurs instructions <Direction> <Distance>, séparées par des virgules (qui sont suivies d'un espace chacun).

La direction est l'une des suivantes:
N- Nord, S- Sud, E- Est, W- Ouest,
NE- Nord-est, NW- Nord-ouest, SE- Sud-est, SW- Sud-ouest.

La distance est un entier (1 à 1000).

Production

Le résultat est les coordonnées où vous vous retrouvez après avoir terminé les instructions, avec trois décimales, séparées par une virgule et un espace. L'emplacement de départ a zéro coordonnées (0, 0).

La première coordonnée est X (Est signifie des coordonnées supérieures à zéro, Ouest signifie moins de zéro).
La deuxième coordonnée est Y (Nord signifie plus de zéro, Sud signifie moins de zéro).


Exemples

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


Source (en ukrainien). Le format d'entrée y est différent.

Oleh Prypin
la source
8
Des points bonus pour le faire dans Logo? ;)
Peter Taylor
@Peter Le format de sortie est strict ... Mais nous verrons si les gens aiment la photo: D
Oleh Prypin
1
Le premier exemple de sortie devrait être -3.000, 2.000.
Lowjacker
avec le logo UCB le format de sortie peut être obtenu comme (print (word (form xcor 4 3) ",) (form ycor 4 3)). Mais je ne suis pas sûr de la facilité d'analyse de l'entrée.
Peter Taylor
@Lowjacker Oui, merci. En fait, l'entrée était incorrecte.
Oleh Prypin

Réponses:

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
la source
?i.to_cpeut être raccourci à 1.i-4 octets.
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
la source
Que diriez-vous de changer la définition de f pour utiliser des protections de motif? Ils ont la belle propriété de ne pas nécessiter de saut de ligne et devraient être plus brefs dans ce cas. Utilisez également interact.
FUZxxl
3

C99 (319 caractères)

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

entrée stdin, test exécuté sur ideone :)

pmg
la source
3

Python, 158 154 150 150 caractères

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
la source
Vous avez en fait 157 caractères, pas 158.
Lowjacker
Je suppose que je n'ai pas besoin de le faire, mais je compte généralement la nouvelle ligne de fin.
Keith Randall
[157] Ligne 1: D=dict(N=1j,E=1,S=-1j,W=-1)[153] Ligne 2: est-elle jvraiment nécessaire? [152] Lignes 3-4: Si vous passez à Python 3, raw_inputinput, et même si vous devez utiliser des parenthèses après print, vous enregistrez 2 caractères [150]
Oleh Prypin
1
@BlaXpirit: Merci pour l'optimisation du dict. Le j est nécessaire dans la ligne 2 dans le cas où toutes les directions sont E et W. Le p résultant doit être complexe pour .realet .imagpour fonctionner.
Keith Randall
1
int class has both imagand realattrs ...
JBernardo
3

JavaScript, 179 164 170 168 158 156 153 caractères

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: problème de précision fixe
  • 168: remplacé (E|W)en regex par(.)
  • 158: remplacement de la logique répétitive en fonction par une variable d
  • 156: réutilisé nau lieu d'une nouvelle variabled
  • 153: Personnellement, je pense que cette édition le rend dix fois plus laid, mais c'est trois caractères plus court. Il est basé sur le comportement non standard que vous pouvez appeler des objets RegExp en tant que fonctions: /./g('string')est le même 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
la source
1
Malheureusement, q = .707 échoue à l'entrée "NW 10" en raison d'erreurs d'arrondi; Je pense que vous avez besoin de "q = Math.SQRT1_2" qui ajoute 8 caractères. En revanche, vous pouvez remplacer "(E | W)?" avec "(.)?" car vous avez déjà établi nord / sud / ni et l'entrée est bien formée, économisant 2 caractères.
DocMax
Merci pour le bit regex. En ce qui concerne le problème de précision, j'ai plutôt utilisé SQRT2 et basculé la multiplication en division.
Casey Chu
2

Haskell, 199 caractères

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
la source
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
la source
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);}}

entrée stdin

vérité
la source
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

Cela peut probablement perdre jusqu'à 10 caractères en réduisant la précision de √2 / 2.

Joey
la source
1

C (gcc) , 155 152 octets

-3 octets grâce au plafond

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

Essayez-le en ligne!

gastropner
la source
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"

lit l'entrée comme arguments de programme. Exemple:

groovy golf.groovy NW 10, SW 10, W 10
TheBigS
la source
0

Perl 5 -n , 122 octets

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

Essayez-le en ligne!

Xcali
la source