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.


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

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

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


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)

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


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

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

stdin eingang


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.



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


Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.