C、173の 160 156 155バイト
編集:@mIllIbyteからstrchrを使用して13バイトを削るというアイデアを借用
Edit2:最小/最大比較を合理化、-4バイト
Edit3:cは->からmain(c)で始まる任意の値を持つことができ、-1バイト
編集4:ungolf /説明を追加
p,l,j,m;main(c){char b[99],*s=gets(b);for(;j<m+2;p?putchar(c?l?32:c:10):l<j?j=l:l>m?m=l:0,l-=c?(c&=223)&&c-9?!!strchr("AEIOU",c):-1:(p=s=b,l+j++))c=*s++;}
ゴルフをしていないと説明:
/* declare and initialize these variables to int and 0 */
p,l,j,m;
/* declares main, but also int c */
main(c)
{
/* we can handle strings of length 98 (+1 for string-terminating 0) */
/* we declare and initialize s to point to the beginning of the input
string for the first pass through the for loop */
char b[99],*s=gets(b);
/* the for-loop actually contains nested loops, where the inner loops
behave differently depending on the outer loop parameter p as follows:
p attains the values false (0) and true (non-null pointer), in this order.
p == false:
the inner loop has the parameter s and passes through all the characters
in the string until the string is exhausted (*s == 0). l is the vertical
position of the current character relative to the first character
(l = 0), smaller number = higher up. The purpose here is simply to find
the range of vertical positions [j, m] present in the string. The
commands in execution order are:
-- loop over s --
// test does not do anything since j <= m by design
1. j < m+2
// puts current char in c and increments string counter
2. c = *s++
// ensures that j (m) equals the min (max) of the vertical positions (l)
encountered so far. At first step j = l = m = 0.
3. l<j?j=l:l>m?m=l:0
// c != 0, this updates the vertical position for the next character
// c = SPC or C = TAB -> lower (l increases by 1)
// c = "aeiouAEIOU" -> higher (l decreases by 1)
4a. l-=(c&=223)&&c-9?!!strchr("AEIOU",c):-1
-- loop over s ends --
// c == 0, this resets the string pointer s and puts p = true, and
// thereby initiates the next phase of the algorithm
// see rest of the explanation at p == true)
4b. p=s=b
p == true:
now there are two inner loops. The outer of these has the parameter j,
which ranges from the smallest vertical position+1 (the value of j after
the p == false pass) to the largest vertical position+1 (m+2 after the
p == true pass). The innermost loop has the parameter s and passes through
all characters in the string until the string is exhausted (*s == 0) just
as in the p == false inner loop. Here l is now the vertical position
relative to the current position j-1, so that l == 0 when a character is
at the current level. Such characters are printed as is, whereas
characters at other levels are replaced by space. The end-of-string
marker 0 outputs a newline. The commands in execution order are:
-- loop over j --
// at first step increments j to point to be one more than the
// current vertical position. At other steps moves the current position
// (j-1) one vertical position downwards. Also, at all steps, this
// biases the vertical position counter l to be zero at the current
// vertical position (j-1)
1. l=-j++
// compare j to stopping criteria, exit if j > m+1
2. j < m+2
-- loop over s --
// puts current char in c and increments string counter
3. c = *s++
// outputs character as follows:
// c == 0 (end of string), output newline
// c != 0 (middle of string)
// l == 0 (character at current vertcial position), output c
// l != 0 (character not at current vertical position), output space
4. putchar(c?l?32:c:10)
// c != 0, this updates the vertical position for the next character
// c = SPC or C = TAB -> lower (l increases by 1)
// c = "aeiouAEIOU" -> higher (l decreases by 1)
5a. l-=(c&=223)&&c-9?!!strchr("AEIOU",c):-1
-- loop over s ends --
// c == 0, this resets the string pointer s for next loop over s
// algorithm (see rest of the explanation at p == true)
5b. p=s=b
-- loop over j ends --
*/
for(;
j<m+2;
p?putchar(c?l?32:c:10):
l<j?j=l:l>m?m=l:0,
l-=c?(c&=223)&&c-9?!!strchr("AEIOU",c):-1:
(p=s=b,l+j++))
c=*s++;
}