##SWI Prolog, 234 bytes
##SWI Prolog, 234 bytes
SWI Prolog, 234 bytes
% helper function recursive base case,
% matches when counter is 0, other input has any values, and empty list 'output'.
helper(_,0,_,_,[]).
% helper function recursively generates substrings
% matching a padded input Text, a line Counter
% a substring starting Offset, a line Length,
% and an output list with a Head and a Tail
helper(Text, Counter, Offset, LineLength, [Head|Tail]):-
sub_string(Text, Offset, LineLength, _, Head), % The list Head matches
% a substring of Text starting
% from Offset, of LineLength chars
% and
NextCounter is Counter-1, % decrement the Counter
NextOffset is Offset+1, % increment the offset
hhelper(Text, NextCounter, NextOffset, LineLength, Tail). % Recurse for list Tail
% Result is a superacrostic for an input string Text, if
superacrostic(Text, Result):-
string_length(Text, Length), % Length is length of input,
% Text = 'ABXCD', Length = 5
% and
findall('_',between(1,Length,_),PaddingList), % PaddingList is a list of padding
% chars Length items long,
% ['_', '_', '_', '_', '_']
% and
string_chars(PaddingString, PaddingChars), % PaddingString is the string from
% joining up that list of chars
% '_____'
% and
string_concat(PaddingString, Text, Temp), % Temp is Text input with a
% padding prefix
% Temp = '_____ABXCD'
% and
string_concat(Temp, PaddingString, PaddedText), % PaddedText is Temp with
% a padded suffix
% Temp = '_____ABXCD_____'
% and
S is Length - ((Length - 1) / 2), % Starting offset S for the substring
% is just past the padding,
% then half the input length back
% '_____ABXCD_____'
% |
% to start the first line,
% and
helper(PaddedText, Length, S, Length, Result). % Result is the list generated from
% the helper function,
% to recurse Length times for that many output rows, S starting offset,
% Length linelength, and Result 'output'.
% helper function recursive base case,
% matches when counter is 0, other input has any values, and empty list 'output'.
helper(_,0,_,_,[]).
% helper function recursively generates substrings
% matching a padded input Text, a line Counter
% a substring starting Offset, a line Length,
% and an output list with a Head and a Tail
helper(Text, Counter, Offset, LineLength, [Head|Tail]):-
sub_string(Text, Offset, LineLength, _, Head), % The list Head matches
% a substring of Text starting
% from Offset, of LineLength chars
% and
NextCounter is Counter-1, % decrement the Counter
NextOffset is Offset+1, % increment the offset
h(Text, NextCounter, NextOffset, LineLength, Tail). % Recurse for list Tail
% Result is a superacrostic for an input string Text, if
superacrostic(Text, Result):-
string_length(Text, Length), % Length is length of input,
% Text = 'ABXCD', Length = 5
% and
findall('_',between(1,Length,_),PaddingList), % PaddingList is a list of padding
% chars Length items long,
% ['_', '_', '_', '_', '_']
% and
string_chars(PaddingString, PaddingChars), % PaddingString is the string from
% joining up that list of chars
% '_____'
% and
string_concat(PaddingString, Text, Temp), % Temp is Text input with a
% padding prefix
% Temp = '_____ABXCD'
% and
string_concat(Temp, PaddingString, PaddedText), % PaddedText is Temp with
% a padded suffix
% Temp = '_____ABXCD_____'
% and
S is Length - ((Length - 1) / 2), % Starting offset S for the substring
% is just past the padding,
% then half the input length back
% '_____ABXCD_____'
% |
% to start the first line,
% and
helper(PaddedText, Length, S, Length, Result). % Result is the list generated from
% the helper function,
% to recurse Length times for that many output rows, S starting offset,
% Length linelength, and Result 'output'.
% helper function recursive base case,
% matches when counter is 0, other input has any values, and empty list 'output'.
helper(_,0,_,_,[]).
% helper function recursively generates substrings
% matching a padded input Text, a line Counter
% a substring starting Offset, a line Length,
% and an output list with a Head and a Tail
helper(Text, Counter, Offset, LineLength, [Head|Tail]):-
sub_string(Text, Offset, LineLength, _, Head), % The list Head matches
% a substring of Text starting
% from Offset, of LineLength chars
% and
NextCounter is Counter-1, % decrement the Counter
NextOffset is Offset+1, % increment the offset
helper(Text, NextCounter, NextOffset, LineLength, Tail). % Recurse for list Tail
% Result is a superacrostic for an input string Text, if
superacrostic(Text, Result):-
string_length(Text, Length), % Length is length of input,
% Text = 'ABXCD', Length = 5
% and
findall('_',between(1,Length,_),PaddingList), % PaddingList is a list of padding
% chars Length items long,
% ['_', '_', '_', '_', '_']
% and
string_chars(PaddingString, PaddingChars), % PaddingString is the string from
% joining up that list of chars
% '_____'
% and
string_concat(PaddingString, Text, Temp), % Temp is Text input with a
% padding prefix
% Temp = '_____ABXCD'
% and
string_concat(Temp, PaddingString, PaddedText), % PaddedText is Temp with
% a padded suffix
% Temp = '_____ABXCD_____'
% and
S is Length - ((Length - 1) / 2), % Starting offset S for the substring
% is just past the padding,
% then half the input length back
% '_____ABXCD_____'
% |
% to start the first line,
% and
helper(PaddedText, Length, S, Length, Result). % Result is the list generated from
% the helper function,
% to recurse Length times for that many output rows, S starting offset,
% Length linelength, and Result 'output'.
##SWI Prolog, 234 bytes
h(_,0,_,_,[]).
h(T,N,S,L,[H|U]):-sub_string(T,S,L,_,H),M is N-1,A is S+1,h(T,M,A,L,U).
s(T,R):-string_length(T,L),findall('_',between(1,L,_),A),string_chars(B,A),
string_concat(B,T,C),string_concat(C,B,D),S is L-((L-1)/2),h(D,L,S,L,R).
Maybe try online here: http://swish.swi-prolog.org/p/hEKigfEl.pl
NB.
- The last line is one long line, I added a linebreak and spaces here just to avoid horizontal scrollbar in this answer.
- The question involves spaces for padding, but Swish online doesn't show them cleanly because of HTML rendering interactions, you have to view source in browser dev tools to check they are present (they are). I've changed the padding to be
_
here, as it demonstrates it working and doesn't affect the byte count.
Examples running in Swish:
Approach, basically the first thing I could make work at all, and doubtless a skilled Prolog user could shorten it a lot:
- Given a string of length L, the output will have L lines, and each line will be L characters long, so 'L' shows up a lot. Countdown from L to 0 for the number of lines, L for the substring length for each line.
- Create a padding string of L spaces (underscores) long, add it to both ends of the input string, because that's a simple length which is definitely going to be enough padding.
- Calculate a starting offset into this triple-length string and recurse, generating a substring each time, into a list of results.
Explained and commented code (might not run), read from superacrostic()
down, then helper()
main body, then helper()
base case:
% helper function recursive base case,
% matches when counter is 0, other input has any values, and empty list 'output'.
helper(_,0,_,_,[]).
% helper function recursively generates substrings
% matching a padded input Text, a line Counter
% a substring starting Offset, a line Length,
% and an output list with a Head and a Tail
helper(Text, Counter, Offset, LineLength, [Head|Tail]):-
sub_string(Text, Offset, LineLength, _, Head), % The list Head matches
% a substring of Text starting
% from Offset, of LineLength chars
% and
NextCounter is Counter-1, % decrement the Counter
NextOffset is Offset+1, % increment the offset
h(Text, NextCounter, NextOffset, LineLength, Tail). % Recurse for list Tail
% Result is a superacrostic for an input string Text, if
superacrostic(Text, Result):-
string_length(Text, Length), % Length is length of input,
% Text = 'ABXCD', Length = 5
% and
findall('_',between(1,Length,_),PaddingList), % PaddingList is a list of padding
% chars Length items long,
% ['_', '_', '_', '_', '_']
% and
string_chars(PaddingString, PaddingChars), % PaddingString is the string from
% joining up that list of chars
% '_____'
% and
string_concat(PaddingString, Text, Temp), % Temp is Text input with a
% padding prefix
% Temp = '_____ABXCD'
% and
string_concat(Temp, PaddingString, PaddedText), % PaddedText is Temp with
% a padded suffix
% Temp = '_____ABXCD_____'
% and
S is Length - ((Length - 1) / 2), % Starting offset S for the substring
% is just past the padding,
% then half the input length back
% '_____ABXCD_____'
% |
% to start the first line,
% and
helper(PaddedText, Length, S, Length, Result). % Result is the list generated from
% the helper function,
% to recurse Length times for that many output rows, S starting offset,
% Length linelength, and Result 'output'.