# Turn a string into a windmill

The code on this site is rapidly being depleted. We need to invest in renewable strings. So you must write a program that takes a string and converts it into a windmill.

# The Challenge

Let's take a simple wind-mill string as an example. Take the string abc. The pivot is the center character, in this case b. Since the string is 3 chars long, every output will be exactly three lines tall and three characters wide. Here is your output on step 1. (Note the whitespace)


abc



To get the next step, rotate each character around the pivot clockwise. Here is step 2:

a
b
c


Here are steps 3-8:

 a
b
c

  a
b
c


cba


c
b
a

 c
b
a

  c
b
a


And on the ninth step, it comes around full circle to the original string:


abc



Note that the b stayed in the same spot the whole time. This is because b is the pivot character. You must write a program or function that takes a string as input and repeatedly prints out this sequence until the program is closed.

# Clarifications

• All input strings will have an odd number of characters. (So that every windmill will have a pivot)

• To keep the challenge simple, all strings will only contain upper and lowercase alphabet characters.

• The output must be len(input_string) characters wide and tall.

• It doesn't matter which step of the sequence you start on, just as long as you continue rotating and looping forever.

# More Test IO:

Since the post is already pretty long, here is a link to the output for "windmill":

# Sidenote:

Since this is supposed to be a windmill, it would be awesome if you include some boilerplate code to animate it with a small time delay or a user input between each step. However, since some languages don't have time builtins, this is not mandatory. The competing part of your submission can just print the sequence as fast as possible.

# MATL, 3533 21 bytes

jtn2/kYaG1$XdwtD3X!T  The following will animate the windmill (26 bytes) jtn2/kYaG1$XdwtXxDlY.3X!T


Online Demo

In this version , the Xx specifies to clear the display and the 1Y. is a 1-second pause.

Explanation

The basic idea is that we want to create two versions of the input. An "orthogonal" version

+-----+
|     |
|     |
|abcde|
|     |
|     |
+-----+


And a "diagonal" version

+-----+
|a    |
| b   |
|  c  |
|   d |
|    e|
+-----+


We push these two versions onto the stack. Each time through the loop, we switch the order of stack and rotate the top one clockwise.

j       % Grab the input as a string
t       % Duplicate the input

%--- Create the "orthogonal" version ---%

n2/     % Determine numel(input) / 2
k       % Round down to nearest integer
Ya      % Pad the input string with floor(numel(input)/2) rows above and below

%--- Create the "diagonal" version ---%

G       % Grab the input again
1$Xd % Place the input along the diagonal of a matrix  % do...while loop w % Flip the order of the first two elements on the stack t % Duplicate the top of the stack %--- OCTAVE ONLY (converts NULL to space chars) ---% O % Create a scalar zero 32 % Number literal (ASCII code for ' ') XE % Replaces 0 elements in our 3D array with 32 (' ') %--- END OCTAVE ONLY ---% D % Display the element 3X! % Rotate this element 90 degrees counter-clockwise 3 times (clockwise) T % Explicit TRUE to create an infinite loop % Implicit end of while loop  ## JavaScript (ES6), 291 bytes r=a=>{w.textContent=a.map(a=>a.join).join ;for(i=j=h=a.length>>1;j++,i--;){t=a[i][i];a[i][i]=a[h][i];a[h][i]=a[j][i];a[j][i]=a[j][h];a[j][h]=a[j][j];a[j][j]=a[h][j];a[h][j]=a[i][j];a[i][j]=a[i][h];a[i][h]=t}} s=w=>{a=[...w=[...w]].map(_=>w.map(_=>' '));a[w.length>>1]=w;setInterval(r,1000,a)} s("windmills") <pre id=w> • Couldn't you golf away a few bytes by reducing the weight time? – MayorMonty Jul 31 '16 at 22:28 # 05AB1E, 88 53 bytes Code: ¹VYg;ïU[2FX¶×DYsJ,YvNð×y¶J?}YvðX×yJ,}Yv¹gN>-ð×yJ,}YRV  Try it online!. Make sure to hit the kill button right after you run it, because it goes into an infinite loop. • That was savage. – Nick Rameau Apr 3 '16 at 3:15 # Ruby, 122119 bytes ->n{c=0 loop{i=[l=n.size,m=l+1,m+1,1][3-c=c+1&7]*(3.5<=>c) s=(' '*l+$/)*l
l.times{|j|s[m*l/2-1+(j-l/2)*i]=n[j]}
$><<s}}  Ungolfed version with sleep, in test program The rotation isn't very convincing at full console height. But if you reduce the height to the the length of the input string, the rotation is a lot more convincing. f=->n{ c=0 #loop counter m=1+l=n.size #l=string length. m=l+1 loop{ #start infinite loop s=(' '*l+$/)*l                        #make a string of l newline-terminated lines of l spaces. Total m characters per line.
i=[m-1,m,m+1,1][3-c=c+1&7]*(3.5<=>c)  #array contains positive distance between characters in string 1=horizontal, m=vertical, etc.
#c=c+1&7 cycles through 0..7. Array index 3..-4 (negative indices count from end of array, so 3=-1, 0=-4 etc)
#(3.5<=>c) = 1 or -1. We use to flip the sign. This is shorter than simply using 8 element array [m-1,m,m+1,1,1-m,-m,-m+1,-1]
l.times{|j|s[m*l/2-1+i*(j-l/2)]=n[j]} #for each character in n, write the appropriate space character in s to the character in n
puts s                                #print s
sleep 1                               #sleep for 1 second
}
}

f[gets.chomp]                             #get input, remove newline, call function


# MATL, 47 44 bytes

' 'jntX"tGtnXyg(wGtnQ2/Y(XJDXKDJ@_X!DK3X!DT


Try it online! (but kill it immediately, infinite loop)

With 1-second pause: 56 bytes

' 'jntX"tGtnXyg(wGtnQ2/Y(XJD1Y.XKD1Y.J@_X!D1Y.K3X!D1Y.T


Try it online! (again, infinite loop)

# Python 3, 193 bytes

def c(a):e=' ';s=len(a);l=int(s/2);b=range(s);m='\n'*l;print(m,a,m);for x in b:print(e*x,a[x]);for x in b:print(e*l,a[x]);for x in b:print(e*(s-1-x),a[x]); a=input();while True:c(a);c(a[::-1]);


Ungolfed

def c(a):
e=' ';s=len(a);l=int(s/2);b=range(s);m='\n'*l;
print(m,a,m);
for x in b:print(e*x,a[x]);
for x in b:print(e*l,a[x]);
for x in b:print(e*(s-1-x),a[x]);
a=input();
while True:
c(a);
c(a[::-1]);


## Recursive, 177 bytes

(crash after a few seconds)

def c(a):e=' ';s=len(a);l=int(s/2);b=range(s);m='\n'*l;print(m,a,m);for x in b:print(e*x,a[x]);for x in b:print(e*l,a[x]);for x in b:print(e*(s-1-x),a[x]);c(a[::-1]);c(input());


Ungolfed

def c(a):
e=' ';s=len(a);l=int(s/2);b=range(s);m='\n'*l;
print(m,a,m);
for x in b:print(e*x,a[x]);
for x in b:print(e*l,a[x]);
for x in b:print(e*(s-1-x),a[x]);
c(a[::-1])
c(input());


## Another solution, 268 bytes

import itertools as i;def w(a):e=' ';s=len(a);l=int(s/2);t='\n';m=(l-1)*t;h=list(i.chain.from_iterable((e*x+a[x],e*l+a[x],e*(s-1-x)+a[x]) for x in range(s)));print(m,a,m,t.join(h[::3]),t.join(h[1::3]),t.join(h[2::3]),sep=t,end='');a=input();while True:w(a);w(a[::-1]);


Ungolfed

import itertools as i;
def w(a):
e=' ';s=len(a);l=int(s/2);t='\n';m=(l-1)*t;
h=list(i.chain.from_iterable((e*x+a[x],e*l+a[x],e*(s-1-x)+a[x]) for x in range(s)))
print(m,a,m,t.join(h[::3]),t.join(h[1::3]),t.join(h[2::3]),sep=t,end='');
a=input();
while True:
w(a);
w(a[::-1]);

• Can I borrow this? – Leaky Nun Apr 3 '16 at 2:56
• By the way, welcome to PPCG! – Leaky Nun Apr 3 '16 at 3:19
• Also, you forgot to reverse the string at the end (first-level-indentation). – Leaky Nun Apr 3 '16 at 3:19
• This output is invalid. Steps one and five are missing leading whitespace. – James Apr 3 '16 at 3:24
• changed! @MyHamDJ – p1714825 Apr 3 '16 at 15:30

# Pyth, 48 bytes

JlzK/J2#*btKz*btKM+*dG@zHVJgNN)VJgKN)VJg-JNN)=_z


Try it online! (Note: this is a version that does not forever loop, because it would crash the interpreter.)

Shamelessly translated from the Python 3 solution by @ByHH.

How it works:

JlzK/J2#*btKz*btKM+*dG@zHVJgNN)VJgKN)VJg-JNN)=_z
assign('z',input())
Jlz                                              assign("J",Plen(z))
K/J2                                          assign("K",div(J,2))
#                                         loop-until-error:
*btK                                      imp_print(times(b,tail(K)))
z                                     imp_print(z)
*btK                                 imp_print(times(b,tail(K)))
@memoized
M                                def gte(G,H):
+*dG@zH                          return plus(times(d,G),lookup(z,H))
VJ   )                   for N in num_to_range(J):
gNN                     imp_print(gte(N,N))
VJ   )             for N in num_to_range(J):
gKN               imp_print(gte(K,N))
VJ     )     for N in num_to_range(J):
g-JNN       imp_print(gte(minus(J,N),N))
=_z  assign('z',neg(z))
`
• This output is invalid. Steps one and five are missing leading whitespace. – James Apr 3 '16 at 3:24
• Is it ok now??? – Leaky Nun Apr 3 '16 at 3:40
• Yep that looks great. ;) – James Apr 3 '16 at 3:40