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\$
  • 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\$ – Gabriel Benamy Dec 2 '16 at 21:07
  • 2
    \$\begingroup\$ It's very different ! We only have rotations ! \$\endgroup\$ – Labo Dec 2 '16 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\$ – Level River St Dec 2 '16 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\$ – Mego Dec 3 '16 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\$ – Mego Dec 3 '16 at 9:33
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\$
  • \$\begingroup\$ 1-2*(r[0]<'R') will save you 2 bytes :) \$\endgroup\$ – Labo Dec 3 '16 at 8:55
  • \$\begingroup\$ Don't make a function, reading from the input make you save more chars! \$\endgroup\$ – Labo Dec 3 '16 at 8:57
  • \$\begingroup\$ Assign 2 variables in the same line to save 2 bytes : d=p=0 \$\endgroup\$ – Labo Dec 3 '16 at 8:58
  • \$\begingroup\$ I golfed again your answer and it makes 99 chars ! pastie.org/private/hm7lejqosdqnkgo000u7q \$\endgroup\$ – Labo Dec 3 '16 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 Dec 3 '16 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
    \$\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\$ – Jonathan Allan Dec 3 '16 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
    \$\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 Dec 3 '16 at 11:49

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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