20
\$\begingroup\$

Guide the Alphabet

Given an array of directions, where the directions are defined as follows:

NW  N  NE
W   .   E
SW  S  SE

Or as indexes (you may use these indices for directions instead of the strings above):

0 1 2
3 . 4
5 6 7

You may choose either format, supporting both is not required by the challenge. Generate the corresponding alphabet String that represents the drawn path, starting with A. The number of directions will never exceed 25, meaning that it can never go past Z, so you don't have to handle this scenario. No other input formats will be accepted unless you can explain why these formats do not work due to a language limitation. This is easier to explain using a verbosely worked out example.


So, lets look at a quick example:

[E,SE,N,S,S,S,NW,W,N] or [4,7,1,6,6,6,0,3,1]

Always start with A.

A

Go East to B.

A-B

Go South East to C.

A-B 
   \
    C

Go North to D.

A-B D
   \|
    C

Go back South to E, overwriting C.

A-B D
   \|
    E

Continue South for 2 cycles to both F and G.

A-B D
   \|
    E
    |
    F
    |
    G

Go North West to H.

A-B D
   \|
    E
    |
  H F
   \|
    G

Go West to I.

A-B D
   \|
    E
    |
I-H F
   \|
    G

End to the North at point J.

A-B D
   \|
J   E
|   |
I-H F
   \|
    G

The final value you would return is by reading the final graph left to right, top to bottom:

ABD
JE
IHF
G

Resulting in:

ABDJEIHFG

This is , lowest byte-count wins.

\$\endgroup\$
  • 1
    \$\begingroup\$ Related \$\endgroup\$ – FlipTack Jan 24 '17 at 17:28
  • 1
    \$\begingroup\$ Can we take as input 7 distinct pair of values instead of your proposed values. for example instead of 0 we get [-1 -1] or for 1 we get [-1 0]? \$\endgroup\$ – rahnema1 Jan 24 '17 at 17:55
  • \$\begingroup\$ @rahnema1 no, the input is as described. \$\endgroup\$ – Magic Octopus Urn Jan 24 '17 at 18:23
  • \$\begingroup\$ Can we return an array of chars instead of a string \$\endgroup\$ – Cows quack Jan 24 '17 at 20:00
  • 2
    \$\begingroup\$ Is it possible that you can return a test case where the values end up to the left of A such that A won't be the first result printed? \$\endgroup\$ – Suever Jan 24 '17 at 23:23
6
\$\begingroup\$

MATL, 64 58 57 50 46 40 37 36 35 30 bytes

O'!":<TUV '59-G)hYsIH$6#u64+c!

Try it at MATL Online

Explanation

O           % Push the number 0 to the stack
'!":<TUV '  % String literal
59-         % Converts this string literal into [-26 -25 -1 1 25 26 27 -27]. These
            % are deltas for the linear indexes into the matrix corresponding to each
            % of the directions. Note that the -27 is at the end since a 0 index wraps
            % around to the end
i)          % Grab the input and use it to index into the delta array 
h           % Horizontally concatenate this with the 0 (our starting point)
Ys          % Take the cumulative sum to get the absolute linear index (location) of
            % each successive letter
IH$6#u      % Find the index of the last (sorted) occurrence of each location
64+         % Add 64 to this index to create ASCII codes
c!          % Convert to character, transpose, and display
\$\endgroup\$
  • 1
    \$\begingroup\$ Oh wow! I thought Mendo did this! Nice :). Usually he wins my matrix questions, good to see someone else using this language. I'm trying to lear nit too. \$\endgroup\$ – Magic Octopus Urn Feb 15 '17 at 17:46
12
\$\begingroup\$

JavaScript (ES6), 108 107 94 87 bytes

Saved a whopping 13 bytes, thanks to Titus!
Saved 7 more bytes, thanks to edc65!

let f =

a=>[i=9,...a].map(d=>r[p+=(d+=d>3)*9-d%3*8-28]=(++i).toString(36),r=[],p=646)&&r.join``

console.log(f([4,7,1,6,6,6,0,3,1]));

How it works

The formula (d += d > 3) * 9 - d % 3 * 8 - 28 translates the directions 0..7 into the following offsets:

0   1   2       -28 -27 -26
3   x   4  -->   -1  x   +1
5   6   7       +26 +27 +28

We use these offsets to move the pointer p into the one-dimensional array r and write the letters at the resulting positions.

We iterate on [i = 9, ...a] rather than just a in order to insert the starting letter 'a'. Because we initialize i to 9 at the same time, we introduce a special offset of 54 (the result of the above formula for d = 9). After the first iteration, p equals 646 + 54 = 700, which leaves just enough space to support up to 25 moves to North-West: 25 * -28 = -700. That's why p is initialized to 646.

Then we just have to join the array to get our final string. Undefined values in between letters are simply ignored by join().

\$\endgroup\$
  • \$\begingroup\$ d+=d>3,p+=d*9-d%3*8-28 saves 11 bytes. \$\endgroup\$ – Titus Jan 25 '17 at 12:21
  • \$\begingroup\$ @Titus Thanks, nice spot! (I can now initialize i in the array definition, saving 2 more bytes) \$\endgroup\$ – Arnauld Jan 25 '17 at 13:06
  • \$\begingroup\$ As OP specified that lowercase is allowed, maybe you can save 7 bytes starting from 9 and using (++i).toString(36) (still not trying to understand your math, but it seems to work) \$\endgroup\$ – edc65 Jan 26 '17 at 14:16
  • \$\begingroup\$ @edc65 Damn right. Thanks! \$\endgroup\$ – Arnauld Jan 26 '17 at 14:34
5
\$\begingroup\$

Octave, 145 138 131 123 105 103 90 87 85 bytes

@(a){[~,k]=unique(cumsum([1 fix((z=a+(a>3))/3);1 mod(z,3)]'-1),'rows');[k'+64 '']}{2}

Try It Online

Thanks to Suever 2 bytes saved!

Previous answer 103 bytes:

@(a)[nonzeros(accumarray(cumsum([1 fix((z=a+(a>3))/3);1 mod(z,3)]'-1)+30,65:nnz(++a)+65,[],@max)')' '']

Try It Online!

First try 145 byts

@(a){[x y]=find(~impad(1,1,1));c=cumsum([0 0;([y x]-2)(++a,:)]);c=c-min(c)+1;n=nnz(a);[nonzeros(sparse(c(:,1),c(:,2),65:n+65,'unique')')' '']}{5}

Some Explanations

@(a){
    [x y]=find([1 0 1]|[1;0;1]);                            %generate 2d coordinates corresponding to 1d input indices
    XY = [y x]-2;
    c=cumsum([0 0;XY(++a,:)]);                              %cumulative sum of coordinates to find position of characters
    c=c-min(c)+1;n=nnz(a);
    [nonzeros(sparse(c(:,1),c(:,2),65:n+65,'unique')')' ''] %using sparse matrix to place characters at specified positions
    }{5}
\$\endgroup\$
  • 1
    \$\begingroup\$ I believe that since you need the image package part of your bytecount has to be loading the image package pkg load image \$\endgroup\$ – Suever Jan 24 '17 at 20:58
  • \$\begingroup\$ Thanks,no need to load if the package is properly installed you can test it in Octave Online \$\endgroup\$ – rahnema1 Jan 24 '17 at 21:03
  • \$\begingroup\$ I believe that's only because Octave Online calls pkg load * at the beginning. ideone.com may be a better choice \$\endgroup\$ – Suever Jan 24 '17 at 21:06
  • \$\begingroup\$ package should be installed this way pkg install -auto image-1.0.0.tar.gz so can it load automatically Please see the manual \$\endgroup\$ – rahnema1 Jan 24 '17 at 21:11
  • \$\begingroup\$ Ok then maybe it's fine. I was just going off of what I had seen before here. \$\endgroup\$ – Suever Jan 24 '17 at 21:13
5
\$\begingroup\$

MATLAB, 87 85 bytes

saved 2 bytes thanks to Luis Mendo

function a=f(s);i='()*BD\]^'-67;[~,a]=unique([0 cumsum(i(s+1))],'last');a=[a'+64,''];
\$\endgroup\$
  • \$\begingroup\$ '%&''?AYZ['-64 nice trick... actually 66 bytes if you rewrite in octave \$\endgroup\$ – rahnema1 Jan 25 '17 at 5:59
4
\$\begingroup\$

PHP, 93 bytes

Operating on a single array like Kodos Johnson´s answer.
But this has so many more ideas that I posted on my own.

for($r=[$c=A];""<$d=$argv[++$i];)$r[$p+=($d+=$d>3)*9-$d%3*8-28]=++$c;ksort($r);echo join($r);

takes numbers from command line arguments. Run with -nr.

moving the cursor

initial calculation:

$d+=$d>3;           // if $d>3, add 1
$p+= ($d/3-1|0)*26  // add/subtract 26 for line change
    +$d%3-1;        // add/substract 1 for column change

golfing:

$d+=$d>3;$p+=($d/3-1|0)*27+$d%3-1;          // +0: multiple of 3 instead of 26
$d+=$d>3;$p+=($d/3|0)*27-27+$d%3-1;         // +1: distribute `line-1`
$d+=$d>3;$p+=($d/3)*27-$d%3/3*27-27+$d%3-1; // +8: distribute `|0`
$d+=$d>3;$p+=$d*9-$d%3*9-27+$d%3-1;         // -8: `/3*27` -> `*9`
$d+=$d>3;$p+=$d*9-$d%3*8-28;                // -7: combine duplicates

merging the assignments doesn´t save anything, but kind of improves readability:

for(init;input loop;$p=$d...)$d+=$d>3;
for(init;input loop;)$p=($d+=$d>3)...;

breakdown

for($r=[$c=A];                  // init result, init letter
    ""<$d=$argv[++$i];)         // loop through command line arguments
    $r[
        $p+=($d+=$d>3)*9-$d%3*8-28  // move cursor
    ]=++$c;                         // increment letter, plot
ksort($r);                      // sort result by index
echo join($r);                  // print result
\$\endgroup\$
3
\$\begingroup\$

Python 2, 180 178 176 bytes

def f(d,a=[[""]*26 for _ in[1]*26],x=0,y=0,j=66):
 a[0][0]="A"
 for i in d:y+=(i>4)-(i<3);x+=(`i`in'247')-(`i`in'035');a[y][x]=chr(j);j+=1
 return"".join("".join(i)for i in a)
\$\endgroup\$
2
\$\begingroup\$

PHP, 121 bytes

$r[0]=chr(65);for(;($n=$argv[1][$i])!=null;)$r[$c+=[-27,-26,-25,-1,1,25,26,27][$n]]=chr($i+++66);ksort($r);echo join($r);

This runs in the command line with the -r flag and takes a char array (string) of indices as an argument.

\$\endgroup\$
  • \$\begingroup\$ You can save 5 easy bytes with ""<$n=$argv[1][$i] instead of ($n=$argv[1][$i])!=null \$\endgroup\$ – Titus Jan 31 '17 at 14:18
1
\$\begingroup\$

R, 160 bytes

a=scan()
e=f=26
x=matrix(0,51,51)
x[e,f]="A"
for(i in a){g=function(q)grepl(q,i)
T=T+1
f=f-g("N")+g("S")
e=e-g("W")+g("E")
x[e,f]=LETTERS[T]}
cat(x[x>0],sep="")
\$\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.