Exploded substrings
Perl, 32 28 24 bytes
Includes +1 for -n
Code:
/.+(??{say$"x"@-".$&})/
Run with the string on STDIN:
perl -nE '/.+(??{say$"x"@-".$&})/' <<< abcd
The golfing languages are so close and yet so far away...
Explanation
/.+/
matches a substring. Unfortunately it stops once it matched one. So I use the runtime regex construct (??{})
to extend the regex so it fails and backtracking will try the following substring, in the end trying them all before giving up in disgust.
Inside the (??{})
I print the current substring prefixed by as many spaces as the offset of the substring using $"x"@-"
So the output neatly documents how regex backtracking works:
abcd
abc
ab
a
bcd
bc
b
cd
c
d
MATL, 20 18 bytes
Inspired by the pattern of substrings generated by @aditsu's answer
tt!+gR*c`t3Lt3$)tn
Try it online!
The pattern of substrings is generated by an upper triangular matrix the same size as the input, and all submatrices obtained by successively removing the last row and column.
Explanation
t % implicit input. Duplicate
t!+g % square matrix with size as input
R % keep upper triangular part
*c % multiply element-wise with broadcast. Convert to char
` % do...while
t % duplicate
3Lt3$) % remove last row and column
tn % number of remaining elements. Used as loop condition
% implicitly end loop and display
Old approach (Cartesian power)
I'm keeping this approach in case it serves as inspiration for other answers
tn0:2Z^!S!2\Xu4LY)*c
In the online compiler this runs out of memory for the longest test case.
Try it online!
Explanation
This generates all patterns of values 0
, 1
and 2
in increasing order, and then transforms 2
into 0
. This gives all possible patterns of 0
and 1
where the 1
values are contiguous. These are used to mark which characters are taken from the original string.
As an example, for string 'abc'
the patterns are generated as follows. First the Cartesian power of [0 1 2]
raised to the number of input characters is obtained:
0 0 0
0 0 1
0 0 2
0 1 0
0 1 1
···
2 2 1
2 2 2
Sorting each row gives
0 0 0
0 0 1
0 0 2
0 0 1
0 1 1
···
1 2 2
2 2 2
Transforming 2
into 0
(i.e. mod(...,2)
) and removing duplicate rows gives the final pattern
0 0 0
0 0 1
0 1 1
0 1 0
1 1 1
1 1 0
1 0 0
in which each row is a mask corresponding to a (contiguous) substring. The first row needs to be removed because it corresponds to the empty substring.
t % Implicitly get input. Duplicate
n % Number of elements
0:2 % Vector [0 1 2]
Z^ % Cartesian power. Each result is a row
!S! % Sort each row
2\ % Modulo 2: transform 2 into 0
Xu % Unique rows
4LY) % Remove first (corresponds to the empty substring)
* % Element-wise multiplication by original string
c % Convert to char. Implicitly display
Retina, 48 32 31 bytes
Thanks to Kenny Lau for saving 3 bytes and paving the way for many more.
Byte count assumes ISO 8859-1 encoding.
M&!r`.+
%+`( *)\S(.+)$
$&¶$1 $2
Try it online!
Order of the generated substrings:
abcde
bcde
cde
de
e
abcd
bcd
cd
d
abc
bc
c
ab
b
a
Explanation
M&!r`.+
This gets us all the prefixes of the input. This is done by matching (M
) any substring (.+
) starting from the end (r
), considering overlapping matches (&
) and returning all of those matches joined with linefeeds (!
).
Now all we need to do is carve out the successive prefixes of those prefixes (by replacing them with spaces). We do this step by step with a loop:
%+`( *)\S(.+)$
$&¶$1 $2
The %
means that this entire thing is done to each line individually (considering it a separate string for time being, and joining it all back together with linefeeds at the end). The +
tells Retina to run this substitution in a loop until the output stops changing (which in this case means that the regex no longer matches). The regex then tries to match the last line of the input with at least two non-space characters, and appends a new row where the first of those is replaced with a space.