Draw Spiral Words [closed]

The Scenario

Given an input of ASCII lowercase letters and spaces, draw a spiral of characters that traces the original input of characters excluding spaces.

The Rules

1) The characters shall spiral counterclockwise to the left in an outwardly fashion. If a left turn is not possible, then move straight.

Given: abcdefg
Output:
g
baf
cde


2) The characters can spiral into previous characters so long as rule #1 is not violated. Also, if that character is spiraled into, then that character is uppercased. Once a character is uppercased, it will stay uppercased regardless of the number of times it is reused.

Given: apples appeal
Output:
PAs
PLe
ea


• So if the word keeps into the spiral but violates the next character then the program stops?
– Matt
Mar 15 '16 at 2:28
• I think what makes this a good challenge is you would have to "rewind the stack" so to speak and resume at a point that makes rule #1 always work. Mar 15 '16 at 13:51
• The current wording makes rule 2 seem entirely optional. If it should be compulsory then I think a much more comprehensive test suite is necessary. Apr 29 '16 at 12:49
• What should the output be for input abcdefghab? Jun 3 '17 at 15:03

JavaScript, 225221 212 bytes

-9 bytes thanks to Conor O'Brien

Please note that your text cases conflict with each other. Your first test case starts in the middle of the spiral. Your second test case starts in the top middle of the spiral. I went with your first test case, because it was the first one I saw. You haven't edited your question in over a year, so sorry for the presumption.

First Test Case:

9<-8<-7
|     |
2<-1  6
|     |
3->4->5


Second Test Case:

2<-1<-6
|     |
3->4->5
|     |
7->8->9


Without any further adieu, here is the golfed code. I am 100% sure that if the community chips it this could be cut significantly. This returns a multiline array.

s=>eval("s=[...s.replace(/ /g,'')];i=0;k=j=1;a=[[],[],[]];b='00122210';c=b*100+'';for(;;){for(l=0;l<8;l++){if(!s[i])break;if(a[k][j]==s[i])s[i]=s[i].toUpperCase();a[k][j]=s[i];k=b[l];j=c[l];i++}if(!s[i])break}a")


Prettification snippet (prints a multiline string to console). Please note the different in my test case #2 and OP's test case #2 (see above if you have not already):

(if someone with more experience with snippets wants to fix this into HTML input feel free to edit this, I need to go to bed).

f=
s=>eval("s=[...s.replace(/ /g,'')];i=0;k=j=1;a=[[],[],[]];b='00122210';c=b*100+'';for(;;){for(l=0;l<8;l++){if(!s[i])break;if(a[k][j]==s[i])s[i]=s[i].toUpperCase();a[k][j]=s[i];k=b[l];j=c[l];i++;g(a)}if(!s[i])break}a")

//replace argument here to change output
var arr = f("apples appeal");

function g(ar) {
var str = "";

for (x = 0; x < 3; x++) {
for (y = 0; y < 3; y++) {
str += ar[y][x] || " ";
}
str += "\n";
}
console.log(str);
}

Ungolfed and Explanation

f=(input)=>{
//remove spaces
input = input.replace(/ /g, "");

//convert to array (so I can uppercase individual letters)
input = input.split("");

//position in input
var pos = 0;

//positions inside output
var xPos = 1;
var yPos = 1;

//output container (3 rows, 3 columns)
var arr = [[],[],[]];

//counterclockwise indexes for x
var xOrder = "00122210";

//counterclockwise indexes for y
//var yOrder = "12221000"
var yOrder = xOrder * 100 + "";

//loop infinitely (breaks when input[pos] is undefined)
for (;;) {
//loop around circle
for (var i = 0; i < 8; i++) {
if (!input[pos]) {
break;
}

//if item already in array equal next item in input, set next item in input to caps before
if (arr[xPos][yPos] == input[pos]) {
input[pos] = input[pos].toUpperCase();
}

//write or overwrite in array with current from input
arr[xPos][yPos] = input[pos];

//increment last because we do not prime our loops
xPos = xOrder[i];
yPos = yOrder[i];
pos++;
}
if(!input[pos]) {
break;
}
}
return arr;
}

• a.split("") is equivalent to [...a]; s=>{...;return a;} is equivalent to s=>eval("...;a") (and the ; is optional in the less golfed version); all semicolons followed by a } are optional May 26 '17 at 22:55
• @ConorO'Brien thank you :) May 26 '17 at 23:37
• What output do you get for the test case apples appeal? I'm seeing ppa eas aLe, which is definitely not correct because there's no l next to the ps. Jun 3 '17 at 9:47
• @PeterTaylor the output is correct, according to the spiral order of the first test case, which I based my program on. The second test case uses a different spiral order (starts on the top). I added a log for each iteration of the snippet. Look at that - it might make more sense. Jun 3 '17 at 14:16
• By the logic of the first test case the output would be eppa apas lple s. Jun 3 '17 at 15:01