Make a "Ceeeeeeee" program
Vim, 27, 26, 25 bytes
DJqqYp:s/.\zs[^<C-r>-]<CR>@qq@qD
Try it online!
Input comes in this format:
e
codegolf.stackexchange.com
My naive first approach is three bytes longer:
i:s/.\zs[^<Right>]<Esc>"addqqYp@a@qq@qdd
I'm also happy with this answer because it starts with my name.
DJqq:t$|s/.\zs[^<C-r>"]<CR>@qq@qD
DJMcMayhem
See the similarity? Eh?
Less successful approaches:
i:s/.\zs[^<Right>]<Esc>"addqqYp@a@qq@qdd
i:s/.\zs[^<Right>]<CR>@q<Esc>"adkqqYp@aq@qdd
DJ:s/.\zs[^<C-r>"]<CR>uqqYp@:@qq@qdd
DJqq:t.|$s/.\zs[^<C-r>"]<CR>@qq@qdd
Explanation:
D " Delete everything on this first line
J " Remove this empty line
qq " Start recording into register 'q'
Y " Yank this line
p " And paste it
:s/ " Run a substitute command on the last line in the buffer. Remove:
. " Any character
\zs " Move the selection forward (so we don't delete the first one)
[^<C-r>-] " Followed by anything *except* for the character we deleted
<CR> " Run the command
@q " Call register 'q'
q " Stop recording
@q " Run the recursive macro
D " Delete our extra line
MATL, 20 16 bytes
y-f1X-"t[]@X@q-(
Try it online! Or verify test cases: 1, 2, 3, 4, 5.
Bonus
Modified code to see the string being gradually shrunk (offline compiler):
y-f1X-"tt.3Y.XxD[]@X@q-(].3Y.XxDvx
Or try it at MATL Online!
Explanation
y % Implicitly input string and char. Duplicate string onto top
- % Subtract. Gives nonzero for chars in the input string that are
% different from the input char
f % Array of indices of nonzero values
1X- % Remove 1 from that array. This gives an array of the indices of
% chars to be removed from the string
" % For each
t % Duplicate previous string
[] % Push empty array
@ % Push index of char to be removed. But this index needs to be
% corrected to account for the fact that previous chars have
% already been removed...
X@q- % ... So we correct by subtracting the 0-based iteration index
( % Assign empty array to that position, to remove that char
% Implicitly end for each
% Implicitly display
Haskell, 50 bytes
w@(a:x)%c|(d,_:y)<-span(==c)x=w:(a:d++y)%c|0<1=[w]
Defines a function (%)
returning a list of strings.
Explanation
(%)
is called as w%c
, with w
being the input string, and c
the character to keep. In short, this definition works by separating w
into the first character (a
) and the remainder (x
), splitting x
at the first occurrence of a character other than c
, and recursively calling itself with that one character dropped.
w@(a:x)%c -- define (%) with w separated into a and x.
|(d,_:y)<-span(==c)x -- split x; bind the string of `c` to d, and the rest
-- to _:y, dropping first character and calling the rest y.
=w:(a:d++y)%c -- if there was a character to drop, cons w onto the
-- sequence gained by recursively calling (%) with that
-- character removed (i.e. call with a:d++y).
|0<1=[w] -- if nothing needed to be dropped, the result sequence is
-- simply the one-element list [w]