(({2,$~1} |\+|{2,$~1} )$2{$~1-2}!)\+$1
Takes input as a command-line argument. Try it here!
Explanation
Here, we're going to (ab)use Regenerate's backtracking algorithm. The regex describes several possibilities for a single line, and the -a
flag instructs Regenerate to output all possible matches. I'm going to start with a slightly different version that doesn't work for input \$n=1\$, and then discuss how to deal with that corner case afterwards.
Space is represented by underscore for better visibility.
(({2,$~1} |\+|{2,$~1} )$2{$~1-2})\+$1
( ) Group 1: the part before the central + character:
either n-1 spaces or n-1 + characters
( ) Group 2: which character to use
Option 1:
{2,$~1} Repeat empty string between 2 and n times
(this causes the backtracker to try n-1 different
options, all of them equal to empty string)
_ followed by space
| Option 2:
\+ + character
| Option 3:
{2,$~1}_ Same deal as option 1
$2 Group 2 again...
{$~1-2} ... repeated n-2 times, for a total of n-1
\+ The central + character
$1 followed by group 1 again
When backtracking over group 2, Regenerate will try space \$n-1\$ times, then +
, then space another \$n-1\$ times. So the list of all possible matches will be \$n-1\$ lines of spaces with a +
in the middle, one line of +
characters with a + in the middle, and \$n-1\$ more lines of spaces with a +
in the middle--exactly the output we want.
There is a problem with \$n=1\$, however. We want group 1 to match the empty string, so that the only possible match for the full regex is +
. However, with input of \$1\$, group 1 fails to match. The culprit is $2{$~1-2}
, "repeat group 2's contents \$n-2\$ times." It's not possible to repeat something \$-1\$ times, so the whole group fails.
We can get around this failure by providing empty string as another alternative inside group 1. However, using |
here raises another issue: we don't want the empty string to be tried if the first alternative succeeded, only if it failed. (Since we're asking for all possible matches, we would get a stray +
at the end of the output for \$n>1\$.)
The solution is to use !
, a greedy version of |
. If its left side matches at all, it takes the left side's match(es) and never tries the right side. It only tries the right side if its left side fails entirely. Thus, our final solution is:
((...)$2{$~1-2}!)\+$1
( ) Group 1: the part before the central + character
(...) Group 2: same options as before
$2{$~1-2} Repeat group 2 again n-2 times
! Or, iff that fails because n-2 < 0...
Empty string
\+ The central + character
$1 followed by group 1 again