# Follow the path

The challenge is to follow (draw) the path:

• ^n - up by n lines
• vn - down by n lines
• >n - right by n character positions
• <n - left by n characters positions

• n is an integer, greater than zero (i.e. you can't receive a command like >-2).
• There're no separators between the commands, the well-formed input looks like this: >5v8<10^3, no other form of input allowed.
• The number of commands is unlimited.
• No more characters are supposed to creep into the input.

Examples.

1. Input is an empty string, output:

*

2. Input is either >3 or <3: note that this doesn't make any difference to the output:

****

3. Similar for ^3 and v3:

*
*
*
*

4. Input: >1v2, output:

**
*
*

5. Input: ^4>3v2<1, output:

****
*  *
* **
*
*

6. If you go back and use the same path, don't draw anything new. E.g. >5<5

******

7. ...though you don't draw anything new, you obviously change the position. Hence, if your input looks like this: >4<2v3, the output is:

*****
*
*
*

8. This is a more complex example: 1) the path can cross itself 2) note that the last three steps of the last command shift the whole path to the right. Input: v6>4^3<7, output:

   *
*
*
********
*   *
*   *
*****

9. ^2v2>3<3v3>4^5v5>3^5>4v2<4v3>4^3v3>3^5>4v2<4v3>7^5>4v2<4v3>9^3<2^2v2>4^2v2<2v3>8^5>2v4>2^4v5<3>6^5>5<5v2>5<5v2>5<4v1>8^3<1^2v2>1v2>2^3v3>2^2>1^2v2<1v3<3>11^3<2^2v2>4^2v2<2v3>5^5>5<5v2>5<5v2>5<4v1>7^5>4v2<4v3>4^3v3>3^5>4v2<3v1<1v2>3^1>1v1


Output:

*   *  *****  *****  *****  *   *     *** *  ******  *     *    *   *  ******  *****  *****
*   *  *   *  *   *  *   *  *   *     * * *  *       *  *  *    *   *  *       *   *  *   *
*****  *****  *****  *****  *****     * * *  ******  ** * **    *****  ******  *****  *****
*   *  *   *  *      *        *       * * *  *        * * *       *    *       *   *  **
*   *  *   *  *      *        *       * ***  ******   *****       *    ******  *   *  *  **
*******************************************************************************************

• As you have posted this challenge today, I think this will be a proper test case: ^2v2>3<3v3>4^5v5>3^5>4v2<4v3>4^3v3>3^5>4v2<4v3>7^5>4v2<4v3>9^3<2^2v2>4^2v2<2v3>8^5>2v4>2^4v5<3>6^5>5<5v2>5<5v2>5<4v1>8^3<1^2v2>1v2>2^3v3>2^2>1^2v2<1v3<3>11^3<2^2v2>4^2v2<2v3>5^5>5<5v2>5<5v2>5<4v1>7^5>4v2<4v3>4^3v3>3^5>4v2<3v1<1v2>3^1>1v1. Dec 31, 2015 at 15:44
• Could you possibly provide a reference implementation? Dec 31, 2015 at 15:54
• Isn't that actually a dupe though? Please decide :D Dec 31, 2015 at 16:51
• @nicael: I'd say it isn't; the I/O is different, and it seems paths can't cross in the other one. I think this one is simpler in ways that could allow different golfing strategies. However, I wasn't aware I was suddenly able to reopen these all by myself, I thought I was merely casting a vote. Dec 31, 2015 at 16:52
• @marinus Ok then. So, related: Yarr! A map to the hidden treasure!. Dec 31, 2015 at 17:01

# JavaScript (ES6), 204 211 210

Edit 1 Bug fix - output '*' for void input
Edit 2 Simpler decoding of direction to x and y diff

Here is my answer to The treasure map, revised to fulfill the specs.

F=m=>(m.replace(/\D(\d+)/g,(d,z)=>{for(;z--;r=[...r],r[x]=m,p[y]=r.join)for(d<'>'?--x:d<'^'?++x:d<'v'?--y:++y,p=~x?~y?p:[y=0,...p]:p.map(r=>' '+r,x=0),r=p[y]||'';!r[x];)r+=' '},x=y=0,p=[m='*']),p.join
)


Less golfed and explained more or less

f=m=>(
x=y=0, // starting position
p=['*'], // output string array (initialized with minimum output)
m.replace( /\D(\d+)/g,
(d,z) => // execute the following for each group direction/length. Length in z, direction in d[0]
{
while( z--)  // repeat for the len
{
// check d to change values of x and y
// all the comparison are with > and <, not equal
// so that they work with the whole d, not just d[0]
d<'>'?--x:d<'^'?++x:d<'v'?--y:++y,
// now if x or y are < 0 then p must be adjusted
p = ~x
? ~y
? p // both x and y are >= 0, p is not changed
: [y = 0, ...p] // y < 0, shift p by on adding a 0 element and set y to 0
: p.map(r=> ' ' + r, x = 0); // x < 0, add a space to the left for each row in p and set x to 0
r = p[y] || ''; // get current row in r
for( ; !r[x]; ) // if the current row is empty or too short
r += ' '; // ... add spaces up to position x
// set character in x position
r = [...r], // the shorter way is converting to array ...
r[x] = '*', // setting the element
p[y] = r.join // and the back to string using join
}
}),
p.join\n // return output array as a newline separated string
}


Test

F=m=>(m.replace(/\D(\d+)/g,(d,z)=>{for(;z--;r=[...r],r[x]='*',p[y]=r.join)for(d<'>'?--x:d<'^'?++x:d<'v'?--y:++y,p=~x?~y?p:[y=0,...p]:p.map(r=>' '+r,x=0),r=p[y]||'';!r[x];)r+=' '},x=y=0,p=['*']),p.join
)

// TEST
console.log = x => O.textContent += x + '\n';

console.log(F('')+'\n')

console.log(F('v6>4^3<7')+'\n')

console.log(F('^2v2>3<3v3>4^5v5>3^5>4v2<4v3>4^3v3>3^5>4v2<4v3>7^5>4v2<4v3>9^3<2^2v2>4^2v2<2v3>8^5>2v4>2^4v5<3>6^5>5<5v2>5<5v2>5<4v1>8^3<1^2v2>1v2>2^3v3>2^2>1^2v2<1v3<3>11^3<2^2v2>4^2v2<2v3>5^5>5<5v2>5<5v2>5<4v1>7^5>4v2<4v3>4^3v3>3^5>4v2<3v1<1v2>3^1>1v1'))
<pre id=O></pre>

• Seems to work perfectly. Dec 31, 2015 at 19:57
• With one only exception: when the input is empty, the requirement is to write *. Dec 31, 2015 at 20:14
• To ones who's browsers are having problems with interpreting ES6: jsfiddle.net/2vrrd1wt. Dec 31, 2015 at 20:15
• @nicael thanks for noticing. Fixed for 1 byte Jan 1, 2016 at 1:09

# MATL, 71 bytes

1thj'.\d+'XX"@Z)XK6L)U:"K1)XK118=K94=-K62=K60=-hv]]YstY)X<1--lqg10*32+c


Uses current release (6.0.0) of the language/compiler. Works in Matlab and in Octave.

EDIT (June 21, 2016): due to changes in the language, the code requires a few modifications to run in current release (16.0.0). You can try it online including the needed modifications.

### Examples

>> matl
> 1thj'.\d+'XX"@Z)XK6L)U:"K1)XK118=K94=-K62=K60=-hv]]YstY)X<1--lqg10*32+c
>
> ^4>3v2<1
****
*  *
* **
*
*

>> matl
> 1thj'.\d+'XX"@Z)XK6L)U:"K1)XK118=K94=-K62=K60=-hv]]YstY)X<1--lqg10*32+c
>
> ^2v2>3<3v3>4^5v5>3^5>4v2<4v3>4^3v3>3^5>4v2<4v3>7^5>4v2<4v3>9^3<2^2v2>4^2v2<2v3>8^5>2v4>2^4v5<3>6^5>5<5v2>5<5v2>5<4v1>8^3<1^2v2>1v2>2^3v3>2^2>1^2v2<1v3<3>11^3<2^2v2>4^2v2<2v3>5^5>5<5v2>5<5v2>5<4v1>7^5>4v2<4v3>4^3v3>3^5>4v2<3v1<1v2>3^1>1v1
*   *  *****  *****  *****  *   *     *** *  ******  *     *    *   *  ******  *****  *****
*   *  *   *  *   *  *   *  *   *     * * *  *       *  *  *    *   *  *       *   *  *   *
*****  *****  *****  *****  *****     * * *  ******  ** * **    *****  ******  *****  *****
*   *  *   *  *      *        *       * * *  *        * * *       *    *       *   *  **
*   *  *   *  *      *        *       * ***  ******   *****       *    ******  *   *  *  **
*******************************************************************************************


### Explanation

The program has four main steps:

1. Read input string and split into its components.
2. Build a 2-column matrix where each row describes a unit displacement in the appropriate direction. For example, [0 -1] indicates one step to the left. The first row is the origin of the path, [1 1]
3. Compute the cumulative sum of that matrix along the first dimension . Now each row describes the coordinates of a *. Normalize to minumum value 1
4. Create a new matrix that contains 1 at the coordinates indicated by the matrix from step 3, and 0 otherwise. This is then transformed into a char matrix.

Code:

1th                         % row vector [1 1]. Initiallize matrix of step 2
j                           % (step 1) read input string
'.\d+'XX                    % split into components. Creates cell array of substrings
"                           % (step 2) for each component
@Z)XK                    % unbox to obtain substring and copy
6L)U:                    % obtain number and build vector of that size
"                        % repeat as many times as that number
K1)                   % paste substring. Get first character: '^', 'v', '>', '<'
XK118=K94=-           % vertical component of unit displacement: -1, 0 or 1
K62=K60=-             % horizontal component of unit displacement: -1, 0 or 1
h                     % concatenate horizontally
v                     % append vertically to existing matrix
]                        % end
]                           % end
Ys                          % (step 3) cumulative sum along first dimension
tY)X<1--                    % normalize to minimum value 1
lqg                         % (step 4) build matrix with 0/1
10*32+c                     % replace 0 by space and 1 by asterisk

• Does it work for the last example? Jan 1, 2016 at 14:56
• How nice! Yes, it does. I have edited my answer to include it Jan 1, 2016 at 17:01

# Perl, 174 bytes

@M=(['*']);pop=~s/(.)(\d+)/($z=ord$1)&64?($y+=$z&8?-1:1)<0&&unshift@M,[$y++]:($x+=($z&2)-1)<0?@M=map{[$x=0,@$_]}@M:0,$M[$y][$x]='*'for1..$2/gre;print map{map{$_||$"}@$_,$/}@M  Expects input as commandline argument. Be sure to quote the argument! Example: perl 177.pl "<1^2>3v4<5^6>7v8<9^10>11" Somewhat readable: @M=(['*']); # output origin/starting position pop=~ # apply regex to cmdline arg s!(.)(\d+)! # match$1=direction, $2=count ($z=ord$1) # get ASCII code for char &64 # 'v^' have this bit set, '<>' don't ? # adjust y: ($y += $z&8 ? -1 : 1) # '^' has bit set, 'v' doesn't < 0 && # negative y? unshift @M, [$y++]              # prepend row; abuse [] for $y++ saving 3 bytes : # adjust x: ($x+= ($z&2) -1 ) # '>' has bit set: 2-1=1, '<' hasn't: 0-1=-1 < 0 ? # negative x? @M = map{ [$x=0,@$_] } @M # prepend column, reset x :0 # '?:0' shorter than '&&()' , # oh, and also:$M[$y][$x]='*'                      # output current position.

for 1..$2 # iterate count !grex; print map{ map{$_||$"} @$_, \$/ } @M         # iterate rows/cols, print '*' or space


# 05AB1E, 27 bytes

">^v<"žCÍS1ú‡#¦εć)>}ø'*s<Λ
`

Try it online! (2020 is close enough so why not)