I worked my way up (or down, if you want) to the best score of Remember FizzBuzz? at VimGolf, but I have a hard time interpreting the solution:
33o<CR> Fizz<CR><C-H><Esc><C-V>A4k<C-H>.@.<C-U>Buzz<Esc>@.<C-V>GI0<Esc>gvg<C-A>ZZ
I understand
the beginning part of adding lines with "Fizz" –
33o<CR> Fizz<CR><C-H><Esc>
– and the end where the preceding line numbers are added –<C-V>GI0<Esc>gvg<C-A>ZZ
but I don't understand
the middle part where the "Buzz" lines are added, i.e.
<C-V>A4k<C-H>.@.<C-U>Buzz<Esc>@.
.4k<C-H>
moves the cursor to the correct place and the last@.
executes the content of the.
register, but that's as much as I can fathom.
Can someone explain the Vim magic used here? 🧙♂️
The first part:
33o<CR> Fizz<CR><C-H><Esc>
puts Fizz
on every line that is a multiple of 3, solving the first requirement of FizzBuzz. It's done with 33 iterations of:
Fizz
on next line,33 blocks of 3 lines are added after line 1 so you get 100 lines in total and the cursor is left on line 100.
See :help o
.
The second part:
<C-V>A4k<C-H>.@.<C-U>Buzz<Esc>
essentially creates a recursive macro that appends Buzz
to lines that are a multiple of 5, instrumental in solving the second and third requirements of FizzBuzz.
In detail:
<C-v>A
to start insertion on column 2, aligned with the Fizz
s from part 1,4k
,<C-h>
to delete the k
,.@.
,<C-u>
to delete everything that was inserted on the current line,Buzz
,<Esc>
.That is a lot of work just to insert Buzz
on one line but this part actually serves three purposes:
Buzz
to the current line (that is incidentally the last multiple of 5),.
,.
.The macro in register .
is:
4k
, move up 4 lines,<C-h>
, move the cursor back one character,.
repeat last edit, so append Buzz
to curent line (if there's Fizz
, get FizzBuzz
, if not, get Buzz
),@.
play back macro in register .
.See :help v_b_A
, :help i_ctrl-u
, :help .
, help ".
, :help @
.
The third part:
@.
plays back the recursive macro described above so it goes up 4 lines, then up 4 lines, and so on, solving the second and third requirements of FizzBuzz
.
The fourth part:
<C-V>GI0<Esc>
inserts a 0
at the beginning of each line.
See :help v_b_I
.
The fifth part:
gvg<C-A>
reselects the last visual block and then increments each 0
sequentially.
See :help gv
and :help v_g_ctrl-a
.
The sixth part:
ZZ
writes the file and quits Vim.
See :help ZZ
.