FizzBuzz - The vim way
Tags: vim, productivity
Published: 2020-11-17 19:30:32

Ever wanted to knock the socks off your interviewer? This article is for you.

## What is FizzBuzz?
FizzBuzz is 2 player children's game, where you count upwards from 1, and every time there is a multiple of 3, you say Fizz instead of the number, and every time there is a multiple of 5, you say Buzz. And when there is a multiple of both 3 and 5, you say FizzBuzz. This is also a classic interview question, where the interviewer asks you to write a program that outputs FizzBuzz for the number 1 to 50.

## Vim macros
According to the [Vim tips wiki](https://vim.fandom.com/wiki/Macros)
> Recording a macro is a great way to perform a one-time task, or to get things done quickly when you don't want to mess with Vim script or mappings, or if you do not yet know how to do it more elegantly.

So in a nutshell, it allows to record a certain sequence of manipulations and repeat them as and when we want.

Macros can be assigned to a letter or number, so a lot of macros can be recorded.

### How do record a macro?
To start recording macros, enter command mode by pressing `<Esc>`. There you can press `q` followed by the letter / number to assign the macro to. Then you can do the manipulations, and press `q` again to stop recording.

We record a simple macro to insert the word `Hello` followed by a new line. Start the recording by pressing `qw` and then enter insert mode to type hello followed by a new line, and then close the macro by pressing `q` in command mode. This records your macro to the key `w`. The macro can be re-played using `@w` in command mode.

## FizzBuzz

**Warning:** the following section assumes that you know the basics of text manipulation in vim.

### Step 1 - Inserting the numbers
For this, we will start with a blank line (this will help in later macros). So insert `1` in the 2nd line. We will record our first macro which will duplicate the current line, and increment the number by 1. Start the recording on the letter `p` using `qp`. Type the following in command mode

```
yypC-aq
```

Seems complex? Trust me it isn't. Let me do a break-down here.
- `yy` yanks the current line (1) into the clipboard
- `p` pasts the yanked buffer
- `C-a` increments the current number by 1, giving 2
- `q` closes the recording.

As we will do it 50, let's replay the macro 48 more times. `48@p` will replay the macro 48 times.

Here is an asciinema for step 1

{% asciinema 373559 %}

### Step 2 - Fizz
First, we will go to the top of the file using `gg`. The numbers at the multiples of 3 have to be replaced with "Fizz". We will start by recording a new macro on the key `o`. Start the recording using `qo`, and as before, type the following in command mode.

```
3j0d$iFizz<esc>q
```

Again, this might seem complex, so let me give a breakdown
- `3j` moves the cursor 3 lines down
- `0` moves the cursor at the start of the line
- `d$` removes everything till the end of the line
- `i` activates the insert mode, and subsequently we type "Fizz"
- `<esc>` drops us back into the command mode
- `q` stops the recording.

We will now again move to the top of the buffer, and play this macro 16 times (as (int) 50 / 3 = 16) using `16@o`.

Here is an asciinema for step 2

{% asciinema 373565 %}

### Step 3 - Buzz
Just like step 2, we will go to the top of the file using `gg`. Now the numbers at the multiples of 5 need to be replaced with "Buzz". We will start a new recording on the key `i`. Start the recording with `qo`. And again, here is a dump of the commands

```
5j0d$iBuzz<esc>q
```

This might look familiar, but here is a breakdown again
- `5j` moves the cursor 5 lines down
- `0` moves the cursor at the start of the line
- `d$` removes everything till the end of the line
- `i` activates the insert mode, and subsequently we type "Buzz"
- `<esc>` drops us back into the command mode
- `q` stops the recording.

We will now again move to the top of the buffer, and play this macro 10 times (as (int) 50 / 5 = 10) using `10@i`.

Here is an asciinema for step 3

{% asciinema 373567 %}

### Step 4 - FizzBuzz
The numbers having both 3 and 5 as its factors should be replaced with "FizzBuzz". Here we again start by moving to the top of the buffer. This time, we will record the macro on the key `u`. The following commands may seem familiar this time

```
15j0d$iFizzBuzz<esc>q
```

Here is a breakdown, yet again
- `15j` moves the cursor 15 lines down
- `0` moves the cursor at the start of the line
- `d$` removes everything till the end of the line
- `i` activates the insert mode, and subsequently we type "FizzBuzz"
- `<esc>` drops us back into the command mode
- `q` stops the recording.

Why move 15 lines down? Well... the numbers having both 3 and 5 as factors should have 15 as a factor. This time, we will play this macro 3 times (as (int) 50 / 15 = 3). After moving to the top, run `3@u`.

Here, again, is an asciinema

{% asciinema 373568 %}

### Step 5 - The master macro
Just to show the power of macros, we will combine all the previously recorded macros in a single, master macro which will play all the macros. This time, we will record it on the key `p`. After opening a new file, and recording using `pp`, insert a new line and "1". After that, 

```
49@pgg16@ogg10@igg3@uggddq
```

This seems complex? Well it isn't, here, again is a breakdown
- `49@p` will play the macro `o` 49 times, generating the sequence of numbers till 50
- `gg16@o` will move the cursor to the top, and play back the "Fizz" macro 16 times
- `gg10@i` will move the cursor to the top again, and play back the "Buzz" macro 10 times
- `gg3@u` will again move the cursor to the top, and play back the "FizzBuzz" macro 3 times
- `ggdd` will remove the extra line at the top, and finally
- `q` will close the macro

## The final result

{% asciinema 373566 %}

> Inspired by Ben Awad's [FizzBuzz - You Suck at Coding [0]
](https://www.youtube.com/watch?v=mZWsyUKwTbg)