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\$
9
  • 1
    \$\begingroup\$ Related \$\endgroup\$
    – FlipTack
    Commented Jan 24, 2017 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
    Commented Jan 24, 2017 at 17:55
  • \$\begingroup\$ @rahnema1 no, the input is as described. \$\endgroup\$ Commented Jan 24, 2017 at 18:23
  • \$\begingroup\$ Can we return an array of chars instead of a string \$\endgroup\$
    – user41805
    Commented Jan 24, 2017 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
    Commented Jan 24, 2017 at 23:23

8 Answers 8

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\$
4
  • \$\begingroup\$ d+=d>3,p+=d*9-d%3*8-28 saves 11 bytes. \$\endgroup\$
    – Titus
    Commented Jan 25, 2017 at 12:21
  • \$\begingroup\$ @Titus Thanks, nice spot! (I can now initialize i in the array definition, saving 2 more bytes) \$\endgroup\$
    – Arnauld
    Commented Jan 25, 2017 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
    Commented Jan 26, 2017 at 14:16
  • \$\begingroup\$ @edc65 Damn right. Thanks! \$\endgroup\$
    – Arnauld
    Commented Jan 26, 2017 at 14:34
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
  • 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\$ Commented Feb 15, 2017 at 17:46
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\$
7
  • 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
    Commented Jan 24, 2017 at 20:58
  • \$\begingroup\$ Thanks,no need to load if the package is properly installed you can test it in Octave Online \$\endgroup\$
    – rahnema1
    Commented Jan 24, 2017 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
    Commented Jan 24, 2017 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
    Commented Jan 24, 2017 at 21:11
  • \$\begingroup\$ Ok then maybe it's fine. I was just going off of what I had seen before here. \$\endgroup\$
    – Suever
    Commented Jan 24, 2017 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\$
1
  • \$\begingroup\$ '%&''?AYZ['-64 nice trick... actually 66 bytes if you rewrite in octave \$\endgroup\$
    – rahnema1
    Commented Jan 25, 2017 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\$
1
  • \$\begingroup\$ You can save 5 easy bytes with ""<$n=$argv[1][$i] instead of ($n=$argv[1][$i])!=null \$\endgroup\$
    – Titus
    Commented Jan 31, 2017 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 and acknowledge you have read our privacy policy.

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