Take the 2-minute tour ×
Programming Puzzles & Code Golf Stack Exchange is a question and answer site for programming puzzle enthusiasts and code golfers. It's 100% free, no registration required.

Finding a treasure hidden by pirates is really easy. Everything you need for this is a map. It is widely known that pirates draw maps by hand and describe the algorithm to find a place in the following way: "Stand near a lone palm tree, do 30 steps towards the forest, 15 towards the lake, ..."

A journey through such route is usually a great opportunity to see the scenery... However, nowadays nobody has time for that. That's why treasure seekers have asked you to write a program that would determine the exact location of a treasure using a given map.


Input

The input consists of multiple instructions <Direction> <Distance>, separated with commas (that are followed by one whitespace each).

Direction is one of the following:
N - North, S - South, E - East, W - West,
NE - Northeast, NW - Northwest, SE - Southeast, SW - Southwest.

Distance is an integer (1 to 1000).

Output

The result is the coordinates where you end up after finishing the instructions, with three decimal places, separated with a comma and a whitespace. Start location has zero coordinates (0, 0).

The first coordinate is X (East means coordinates larger than zero, West means less than zero).
The second coordinate is Y (North means more than zero, South means less than zero).


Examples

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 (in Ukrainian). Input format is different there.

share|improve this question
8  
Bonus points for doing it in Logo? ;) –  Peter Taylor May 3 '11 at 21:31
    
@Peter The output format is strict... But we will see whether people like the picture :D –  Oleh Prypin May 3 '11 at 21:38
1  
The first example output should be -3.000, 2.000. –  Lowjacker May 3 '11 at 21:59
    
with UCB Logo the output format can be obtained as (print (word (form xcor 4 3) ",) (form ycor 4 3)). But I'm not sure how easy parsing the input would be. –  Peter Taylor May 3 '11 at 22:16
    
@Lowjacker Yes, thanks. Actually, the input was wrong. –  Oleh Prypin May 4 '11 at 11:32
add comment

10 Answers

up vote 6 down vote accepted

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
share|improve this answer
add comment

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(/=',')
share|improve this answer
    
How about changing the defintion of f to use pattern guards? They have the nice property to not require a line break and should be more breve in this case. Also, use interact. –  FUZxxl May 6 '11 at 13:58
add comment

C99 (319 chars)

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

input in stdin, test run at ideone :)

share|improve this answer
add comment

Python, 158 154 150 chars

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)
share|improve this answer
    
You actually have 157 chars, not 158. –  Lowjacker May 3 '11 at 23:24
    
I guess I don't need to, but I usually count the trailing newline. –  Keith Randall May 4 '11 at 3:16
    
[157] Line 1: D=dict(N=1j,E=1,S=-1j,W=-1) [153] Line 2: is j really needed? [152] Lines 3-4: If you switch to Python 3, raw_inputinput, and even though you have to use parentheses after print, you save 2 characters [150] –  Oleh Prypin May 4 '11 at 12:19
1  
@BlaXpirit: Thanks for the dict optimization. The j is needed in line 2 in case all the directions are E and W. The resulting p needs to be complex for .real and .imag to work. –  Keith Randall May 4 '11 at 15:29
1  
int class has both imag and real attrs... –  JBernardo Jul 5 '11 at 22:08
show 4 more comments

JavaScript, 179 164 170 168 158 156 153 chars

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: fixed accuracy issue
  • 168: replaced (E|W) in regex with (.)
  • 158: replaced repetitive logic in function with variable d
  • 156: reused n instead of a new variable d
  • 153: Personally, I think this edit makes it ten times uglier, but it's three characters shorter. It's based on the non-standard behavior that you can call RegExp objects as functions: /./g('string') is the same as /./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))

share|improve this answer
1  
Unfortunately, q=.707 fails the "NW 10" input due to rounding errors; I think you need "q=Math.SQRT1_2" which adds 8 chars. On the other hand, you can replace "(E|W)?" with "(.)?" since you have already established north/south/neither and the input is well-formed, saving 2 chars. –  DocMax Jun 14 '11 at 6:45
    
Thanks for the regex bit. As for the accuracy issue, I used SQRT2 instead and switched the multiplication to division. –  Casey Chu Jun 14 '11 at 10:22
add comment

Haskell, 199 characters

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
share|improve this answer
add comment

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)
share|improve this answer
add comment

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 input

share|improve this answer
add comment

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

This can probably lose up to 10 characters by reducing the accuracy of √2/2.

share|improve this answer
add comment

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"

reads input as program arguments. Example:

groovy golf.groovy NW 10, SW 10, W 10
share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.