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.


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

?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(/=',')

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 :)


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)

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


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

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)

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


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.



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


En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.