18
\$\begingroup\$

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. Input:

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

    *   *  *****  *****  *****  *   *     *** *  ******  *     *    *   *  ******  *****  *****
    *   *  *   *  *   *  *   *  *   *     * * *  *       *  *  *    *   *  *       *   *  *   *
    *****  *****  *****  *****  *****     * * *  ******  ** * **    *****  ******  *****  *****
    *   *  *   *  *      *        *       * * *  *        * * *       *    *       *   *  **
    *   *  *   *  *      *        *       * ***  ******   *****       *    ******  *   *  *  **
    *******************************************************************************************
    
\$\endgroup\$
7
  • 6
    \$\begingroup\$ 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. \$\endgroup\$ Dec 31 '15 at 15:44
  • \$\begingroup\$ Could you possibly provide a reference implementation? \$\endgroup\$ Dec 31 '15 at 15:54
  • \$\begingroup\$ Isn't that actually a dupe though? Please decide :D \$\endgroup\$
    – nicael
    Dec 31 '15 at 16:51
  • \$\begingroup\$ @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. \$\endgroup\$
    – marinus
    Dec 31 '15 at 16:52
  • \$\begingroup\$ @marinus Ok then. So, related: Yarr! A map to the hidden treasure!. \$\endgroup\$
    – nicael
    Dec 31 '15 at 17:01
2
\$\begingroup\$

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
\$\endgroup\$
2
  • \$\begingroup\$ Does it work for the last example? \$\endgroup\$
    – nicael
    Jan 1 '16 at 14:56
  • \$\begingroup\$ How nice! Yes, it does. I have edited my answer to include it \$\endgroup\$
    – Luis Mendo
    Jan 1 '16 at 17:01
8
\$\begingroup\$

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>

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

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

05AB1E, 27 bytes

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

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

\$\endgroup\$

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.