Triangulating Text
Python, 81 bytes
def f(s,p=''):
i=-int(len(2*s)**.5)
if s:f(s[:i],p+' ');print p+' '.join(s[i:])
A recursive function. Goes from the end of s
, chopping off and printing characters. The number of characters to take is computed from the length of s
. The function is set up to prints in reverse order of the recursive calls, which terminate when s
is empty and then resolve back up the line. Each layer, the prefix p
has an extra space added.
In Python 3, the if
can be done via short circuiting, though this doesn't seem to save chars:
def f(s,p=''):i=-int(len(2*s)**.5);s and[f(s[:i],p+' '),print(p+' '.join(s[i:]))]
An equally-long alternative with inequality chaining:
def f(s,p=''):i=-int(len(2*s)**.5);''<s!=f(s[:i],p+' ')!=print(p+' '.join(s[i:]))
Both print
and f
return None
, which is hard to use.
Pyth, 22 bytes
jua+L\ GjdHfTczsM._UzY
Try it online: Demonstration or Test Suite
Explanation:
jua+L\ GjdHfTczsM._UzY implicit: z = input string
Uz create the list [0, 1, ..., len(z)-1]
._ all prefixes of this list: [[0], [0,1], [0,1,2], ...]
sM sum up each sublist: [0, 1, 3, 6, 10, ...]
cz split z at these indices
fT remove all the unnecessary empty strings
this gives us the list of strings of the triangle
u Y reduce this list, with the initial value G = []
+L\ G prepend a space to each string in G
jdH join the current string with spaces
a and append it to G
j print each string on a separate line
Candy, 67 59 57 bytes
&iZ1-=yZ1+Z*2/>{0g}0=z@1i&{|.}bYR(" ";=)ZR(=a&{;}" ";)"\n";Y1-=ya1j
&1-8*1+r1-2/=y@1i&{|.}bYR(" ";=)ZR(=a&{;}" ";)"\n";Y1-=ya1j
&8*7-r1-2/=y@1i&{|.}bYR(" ";=)ZR(=a&{;}" ";)"\n";Y1-=ya1j
or:
&
8 *
7 - r
1 - 2 /
= y @ 1 i
& { | . } b
Y R ( " " ;
= ) Z R ( = a &
{ ; } " " ; ) "
\ n " ; Y 1 - = y a
1 j
long form:
stackSz
digit8 # Y = (sqrt((numCh - 1) * 8 + 1) - 1) / 2 using pythagorean
mult # Y = (sqrt(numCh * 8 - 7) - 1) / 2 equivalent but shorter
digit7
sub
root
digit1
sub
digit2
div
popA
YGetsA
label digit1
incrZ
stackSz # bail if we're out of letters
if
else
retSub
endif
stack2
pushY # print the leading spaces (" " x Y)
range1
while
" " printChr
popA
endwhile
pushZ
range1 # output this row of characters (Z of them)
while
popA
stack1
stackSz
if
printChr # bail on unbalanced tree
endif
" " printChr
endwhile
"\n" printChr
pushY
digit1
sub
popA
YGetsA
stack1
digit1 jumpSub # loop using recursion