20
\$\begingroup\$

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.

\$\endgroup\$
5
  • 8
    \$\begingroup\$ Bonus points for doing it in Logo? ;) \$\endgroup\$ May 3, 2011 at 21:31
  • \$\begingroup\$ @Peter The output format is strict... But we will see whether people like the picture :D \$\endgroup\$ May 3, 2011 at 21:38
  • 1
    \$\begingroup\$ The first example output should be -3.000, 2.000. \$\endgroup\$
    – Lowjacker
    May 3, 2011 at 21:59
  • \$\begingroup\$ 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. \$\endgroup\$ May 3, 2011 at 22:16
  • \$\begingroup\$ @Lowjacker Yes, thanks. Actually, the input was wrong. \$\endgroup\$ May 4, 2011 at 11:32

13 Answers 13

8
\$\begingroup\$

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
\$\endgroup\$
1
  • \$\begingroup\$ ?i.to_c can be shortened to 1.i for -4 bytes. \$\endgroup\$
    – MegaTom
    Jun 9, 2019 at 2:37
4
\$\begingroup\$

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(/=',')
\$\endgroup\$
1
  • \$\begingroup\$ 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. \$\endgroup\$
    – FUZxxl
    May 6, 2011 at 13:58
4
\$\begingroup\$

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

\$\endgroup\$
4
\$\begingroup\$

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)
\$\endgroup\$
8
  • \$\begingroup\$ You actually have 157 chars, not 158. \$\endgroup\$
    – Lowjacker
    May 3, 2011 at 23:24
  • \$\begingroup\$ I guess I don't need to, but I usually count the trailing newline. \$\endgroup\$ May 4, 2011 at 3:16
  • \$\begingroup\$ [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] \$\endgroup\$ May 4, 2011 at 12:19
  • 1
    \$\begingroup\$ @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. \$\endgroup\$ May 4, 2011 at 15:29
  • 1
    \$\begingroup\$ int class has both imag and real attrs... \$\endgroup\$
    – JBernardo
    Jul 5, 2011 at 22:08
4
\$\begingroup\$

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

\$\endgroup\$
2
  • 1
    \$\begingroup\$ 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. \$\endgroup\$
    – DocMax
    Jun 14, 2011 at 6:45
  • \$\begingroup\$ Thanks for the regex bit. As for the accuracy issue, I used SQRT2 instead and switched the multiplication to division. \$\endgroup\$
    – Casey Chu
    Jun 14, 2011 at 10:22
3
\$\begingroup\$

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
\$\endgroup\$
2
\$\begingroup\$

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)
\$\endgroup\$
2
\$\begingroup\$

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

\$\endgroup\$
2
\$\begingroup\$

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.

\$\endgroup\$
2
\$\begingroup\$

C (gcc), 155 152 bytes

-3 bytes thanks to 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);}

Try it online!

\$\endgroup\$
0
0
\$\begingroup\$

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
\$\endgroup\$
0
\$\begingroup\$

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

Try it online!

\$\endgroup\$
0
\$\begingroup\$

J, 93 bytes

[:0j3&":@+.@(1#.".@>@{:*(0j1^2%~i.8){~<;._1@' E NE N NW W SW S SE'i.{.)@|:[:(<;._1);._1', ',]

Try it online!

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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