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]

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.

• Related Jan 24 '17 at 17:28
• 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]? Jan 24 '17 at 17:55
• @rahnema1 no, the input is as described. Jan 24 '17 at 18:23
• Can we return an array of chars instead of a string Jan 24 '17 at 20:00
• 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? Jan 24 '17 at 23:23

JavaScript (ES6), 10810794 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().

• d+=d>3,p+=d*9-d%3*8-28 saves 11 bytes. Jan 25 '17 at 12:21
• @Titus Thanks, nice spot! (I can now initialize i in the array definition, saving 2 more bytes) Jan 25 '17 at 13:06
• 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) Jan 26 '17 at 14:16
• @edc65 Damn right. Thanks! Jan 26 '17 at 14:34

MATL, 645857504640373635 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
• 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. Feb 15 '17 at 17:46

Octave, 1451381311231051039087 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!

@(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

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}
• I believe that since you need the image package part of your bytecount has to be loading the image package pkg load image Jan 24 '17 at 20:58
• Thanks,no need to load if the package is properly installed you can test it in Octave Online Jan 24 '17 at 21:03
• I believe that's only because Octave Online calls pkg load * at the beginning. ideone.com may be a better choice Jan 24 '17 at 21:06
• package should be installed this way pkg install -auto image-1.0.0.tar.gz so can it load automatically Please see the manual Jan 24 '17 at 21:11
• Ok then maybe it's fine. I was just going off of what I had seen before here. Jan 24 '17 at 21:13

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,''];
• '%&''?AYZ['-64 nice trick... actually 66 bytes if you rewrite in octave Jan 25 '17 at 5:59

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

Python 2, 180 178 176 bytes

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

PHP, 121 bytes

$r=chr(65);for(;($n=$argv[$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.

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

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="")