9
\$\begingroup\$

I though this would be a good challenge : http://adventofcode.com/2016/day/1

Task description

Given a sequence of rotations and distances following the pattern (L|R)[1-9][0-9]*, give the manhattan distance between the start and the ending points, that is the minimal number of vertical and horizontal moves on a grid.

Examples

For example, if we assume you started facing North:

Following R2, L3 leaves you 2 blocks East and 3 blocks North, or 5 blocks away. R2, R2, R2 leaves you 2 blocks due South of your starting position, which is 2 blocks away. R5, L5, R5, R3 leaves you 12 blocks away.

Technical details

You can choose the separator between the moves (e.g. : "\n", ", ", or ","). You must give the answer as an integer in base 10.

Not a duplicate!

It is not a duplicate for multiple reasons :

  • The moves are not the same. Here they are rotations, not directions.
  • I want the Manhattan distance, not the euclidian.
\$\endgroup\$
19
  • 3
    \$\begingroup\$ You should include a description of what the Manhattan distance is in your question. Just posting a link is kind of tacky. \$\endgroup\$ Commented Dec 2, 2016 at 21:07
  • 2
    \$\begingroup\$ It's very different ! We only have rotations ! \$\endgroup\$
    – Labo
    Commented Dec 2, 2016 at 21:22
  • 1
    \$\begingroup\$ @Labo I agree. Its not just about the fact that the answer here is in Manhattan distance whereas the other one is in Euclidean distance. This has turtle style movement while the other one specifies compass directions NSEW (the fact that it calls them UDLR is irrelevant.) \$\endgroup\$ Commented Dec 2, 2016 at 21:55
  • 2
    \$\begingroup\$ Please use the Sandbox in the future to get feedback on your challenges before posting them to the main site. \$\endgroup\$
    – user45941
    Commented Dec 3, 2016 at 9:28
  • 2
    \$\begingroup\$ @Labo That's fine, we don't expect new users to know all the ins and outs of this site immediately. It's just a gentle suggestion for next time. :) \$\endgroup\$
    – user45941
    Commented Dec 3, 2016 at 9:33

5 Answers 5

4
\$\begingroup\$

Python 3, 109 99 104 101 bytes

This is a simple answer that uses complex numbers, with input as a space-separated string or a newline-separated string. Golfing suggestions welcome!

Edit: -13 bytes thanks to Labo. +5 bytes for converting to an int.

d=p=0
for r in input().split():d+=1-2*(r<'R');p+=1j**d*int(r[1:])
print(int(abs(p.real)+abs(p.imag)))

Ungolfing

def manhattan_rotation(seq, nsew=0, pos = 0):
    for rot in seq.split():
        # change direction
        if rot[0] == "L":
            nsew += -1 
        else:
            nsew += 1
        # move in that direction rot[1:] times
        pos += 1j ** nsew * int(rot[1:])
    return int(abs(pos.real)+abs(pos.imag))
\$\endgroup\$
9
  • \$\begingroup\$ 1-2*(r[0]<'R') will save you 2 bytes :) \$\endgroup\$
    – Labo
    Commented Dec 3, 2016 at 8:55
  • \$\begingroup\$ Don't make a function, reading from the input make you save more chars! \$\endgroup\$
    – Labo
    Commented Dec 3, 2016 at 8:57
  • \$\begingroup\$ Assign 2 variables in the same line to save 2 bytes : d=p=0 \$\endgroup\$
    – Labo
    Commented Dec 3, 2016 at 8:58
  • \$\begingroup\$ I golfed again your answer and it makes 99 chars ! pastie.org/private/hm7lejqosdqnkgo000u7q \$\endgroup\$
    – Labo
    Commented Dec 3, 2016 at 8:59
  • 2
    \$\begingroup\$ @Labo I'm not sure you can edit the specification in a way that would invalidate existing answers, but let me ask some mods. \$\endgroup\$
    – Sherlock9
    Commented Dec 3, 2016 at 9:17
2
\$\begingroup\$

PHP, 93 bytes

while($m=$argv[++$i])${chr(80|3&$d+=(P<$m)-(M>$m))}+=substr($m,1);echo abs($P-$R)+abs($Q-$S);

breakdown

while($m=$argv[++$i])       // loop through arguments:
    ${                      // 5. use as variable name
        chr(                // 4. cast to character (P,Q,R,S) 
        80|                 // 3. add 80
        3&                  // 2. modulo 4
        $d+=(P<$m)-(M>$m)   // 1. change direction depending on letter
    )}+=substr($m,1);       // 6. add number to variable
echo abs($P-$R)+abs($Q-$S); // calculate distance, print
\$\endgroup\$
2
\$\begingroup\$

Python 2, 86 bytes

x=y=0
for d in input().split():c=cmp(d,'M');x,y=int(d[1:])-y*c,x*c
print abs(x)+abs(y)

Tracks the current x and y coordinates. When turning, instead of updating the direction, rotates the current value so that the motion is always in the x-positive direction. Complex numbers were too costly to extract the coordinates from.

\$\endgroup\$
1
\$\begingroup\$

Python 2, 103 102 bytes

l=c=0
for i in input().split():c+=cmp(i[0],'N');l+=1j**c*int(i[1:])
print int(abs(l.imag)+abs(l.real))

repl.it

Input is a string of space delimited directions, e.g. "R5 L5 R5 R3".
Prints out the Manhattan distance between the starting location and the destination.

How?

Starts at the origin of the complex plane, l=0;

With a cumulative quarter-right turn counter, c=0;

For each instruction, i, the rotation is parsed is by comparing the first character of the direction to the character 'N', and c is adjusted accordingly.

The distance to travel is parsed with int(i[1:]) and the instruction is enacted by taking that many block sized steps in the direction given by taking the cth power of 0+1j with 1j**c.

The final Manhattan distance is the sum of the absolute distances from the origin in the two directions - imaginary and real; achieved with abs(l.imag)+abs(l.real)

\$\endgroup\$
1
  • 1
    \$\begingroup\$ @Sherlock9 - Oh, um answer convergence. Save 2 bytes by switching to Python 2 and using cmp like my answer, let me know and I will delete. \$\endgroup\$ Commented Dec 3, 2016 at 13:26
0
\$\begingroup\$

JavaScript (ES2016), 98 100

2 bytes saved thx @Neil

d=>d.replace(/.(\d+)/g,(d,l)=>(o+=d>'M'||3,l*=~-(o&2),o&1?x-=l:y+=l),x=y=o=0)&&(x*x)**.5+(y*y)**.5

100 bytes for ES6

d=>d.replace(/.(\d+)/g,(d,l)=>(o+=d>'M'||3,l*=~-(o&2),o&1?x-=l:y+=l),x=y=o=0)&&(x>0?x:-x)+(y>0?y:-y)

Less golfed

d => d.replace(/.(\d+)/g,
  (d,l)=>( // L or R in d, distance in l
    o += d>'M' || 3, // orientation in o, used %4
    l *= ~-(o&2), // convert to number and change sign if needed
    o&1 ? x -= l : y += l // move based on orientation
  ), x = y = o = 0)
&& (x>0?x:-x) + (y>0?y:-y)

Test (ES6)

F=
d=>d.replace(/.(\d+)/g,(d,l)=>(o+=d>'M'||3,l*=~-(o&2),o&1?x-=l:y+=l),x=y=o=0)&&(x>0?x:-x)+(y>0?y:-y)

function update() {
  O.textContent=F(I.value)
}

update()
<input id=I value='R5, L5, R5, R3' oninput='update()'><pre id=O></pre>

\$\endgroup\$
1
  • 1
    \$\begingroup\$ My ES6 answer was originally 106 bytes; copying your intermediate variable saved me 3 bytes; switching from match to your replace saved me 2 bytes, and copying your processing the direction and distance at the same time saved me a final byte, resulting in this: s=>s.replace(/.(\d+)/g,(c,n)=>(d+=c<'R'||3,n*=~-(d&2),d&1?x+=n:y+=n),x=y=d=0)&&(x<0?-x:x)+(y<0?-y:y), which is now two bytes shorter than your ES6 answer, thanks to the c<'R'||3 and n*=~-(d&2) tricks. \$\endgroup\$
    – Neil
    Commented Dec 3, 2016 at 11:49

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.