Piratenschatz

18

Es ist wirklich einfach, einen Schatz zu finden, der von Piraten versteckt wird. Alles was Sie dafür brauchen, ist eine Karte. Es ist allgemein bekannt, dass Piraten Karten von Hand zeichnen und den Algorithmus beschreiben, um einen Ort auf folgende Weise zu finden: "Stelle dich neben eine einsame Palme, mache 30 Schritte in Richtung Wald, 15 in Richtung See, ..."

Eine Reise über eine solche Route ist in der Regel eine großartige Gelegenheit, die Landschaft zu sehen ... Heutzutage hat jedoch niemand Zeit dafür. Aus diesem Grund haben Schatzsucher Sie gebeten, ein Programm zu schreiben, mit dem Sie anhand einer bestimmten Karte die genaue Position eines Schatzes bestimmen können.


Eingang

Die Eingabe besteht aus mehreren Anweisungen <Direction> <Distance>, die durch Kommas getrennt sind (gefolgt von jeweils einem Leerzeichen).

Die Richtung ist eine der folgenden:
N- Norden, S- Süden, E- Osten, W- Westen,
NE- Nordosten, NW- Nordwesten, SE- Südosten, SW- Südwesten.

Die Entfernung ist eine ganze Zahl (1 bis 1000).

Ausgabe

Das Ergebnis sind die Koordinaten, bei denen Sie nach Beendigung der Anweisungen mit drei Dezimalstellen, getrennt durch ein Komma und ein Leerzeichen, landen. Die Startposition hat Nullkoordinaten (0, 0).

Die erste Koordinate ist X (Ost bedeutet Koordinaten größer als Null, West bedeutet weniger als Null).
Die zweite Koordinate ist Y (Nord bedeutet mehr als Null, Süd bedeutet weniger als Null).


Beispiele

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


Quelle (auf Ukrainisch). Das Eingabeformat ist dort anders.

Oleh Prypin
quelle
8
Bonuspunkte für das Logo? ;)
Peter Taylor
@ Peter Das Ausgabeformat ist streng ... Aber wir werden sehen, ob die Leute das Bild mögen: D
Oleh Prypin
1
Die erste Beispielausgabe sollte sein -3.000, 2.000.
Lowjacker
mit UCB Logo kann das Ausgabeformat erhalten werden als (print (word (form xcor 4 3) ",) (form ycor 4 3)). Ich bin mir jedoch nicht sicher, wie einfach das Parsen der Eingabe sein würde.
Peter Taylor
@ Lowjacker Ja, danke. Eigentlich war die Eingabe falsch.
Oleh Prypin

Antworten:

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
quelle
?i.to_ckann auf 1.i-4 Bytes gekürzt werden .
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
quelle
Wie wäre es, wenn Sie die Definition von f ändern, um Pattern Guards zu verwenden? Sie haben die nette Eigenschaft, keinen Zeilenumbruch zu erfordern und sollten in diesem Fall kürzer sein. Verwenden Sie auch interact.
FUZxxl
3

C99 (319 Zeichen)

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

Eingabe in stdin, Testlauf bei ideone :)

pmg
quelle
3

Python, 158 154 150 Zeichen

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
quelle
Sie haben tatsächlich 157 Zeichen, nicht 158.
Lowjacker
Ich glaube, ich muss nicht, aber ich zähle normalerweise die nachgestellte Zeile.
Keith Randall
[157] Zeile 1: D=dict(N=1j,E=1,S=-1j,W=-1)[153] Zeile 2: wird jwirklich benötigt? [152] Zeilen 3-4: Wenn Sie zu Python 3 wechseln, raw_inputinputund obwohl Sie danach Klammern verwenden müssen print, speichern Sie 2 Zeichen. [150]
Oleh Prypin
1
@BlaXpirit: Danke für die Diktoptimierung. Das j wird in Zeile 2 benötigt, wenn alle Richtungen E und W sind. Das resultierende p muss komplex sein .realund .imagfunktionieren.
Keith Randall
1
int class has both imagand realattrs ...
JBernardo
3

JavaScript, 179 164 170 168 158 156 153 Zeichen

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: Genauigkeitsproblem behoben
  • 168: ersetzt (E|W)durch(.)
  • 158: Repetitive Logik in Funktion durch Variable ersetzt d
  • 156: wird nanstelle einer neuen Variablen wiederverwendetd
  • 153: Ich persönlich denke, diese Bearbeitung macht es zehnmal hässlicher, aber es sind drei Zeichen kürzer. Es basiert auf dem nicht standardmäßigen Verhalten, dass Sie RegExp-Objekte als Funktionen aufrufen können: /./g('string')ist dasselbe wie /./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
quelle
1
Leider schlägt q = .707 die Eingabe "NW 10" aufgrund von Rundungsfehlern fehl; Ich denke, Sie brauchen "q = Math.SQRT1_2", was 8 Zeichen hinzufügt. Auf der anderen Seite können Sie "(E | W)?" mit "(.)?" Da Sie Nord / Süd / Keins bereits eingerichtet haben und die Eingabe wohlgeformt ist, sparen Sie 2 Zeichen.
DocMax
Danke für das Regex-Bit. Was die Genauigkeit betrifft, habe ich stattdessen SQRT2 verwendet und die Multiplikation auf Division umgestellt.
Casey Chu
2

Haskell, 199 Zeichen

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
quelle
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
quelle
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 eingang

Wahrhaftigkeit
quelle
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

Hierdurch können möglicherweise bis zu 10 Zeichen verloren gehen, wenn die Genauigkeit auf √2 / 2 verringert wird.

Joey
quelle
1

C (GCC) , 155 152 Bytes

-3 Bytes dank 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);}

Probieren Sie es online!

Gastropner
quelle
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"

Liest Eingaben als Programmargumente. Beispiel:

groovy golf.groovy NW 10, SW 10, W 10
TheBigS
quelle
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

Probieren Sie es online!

Xcali
quelle