Advent Of Vim, Episode 4
Solving AdventOfCode challenges in 30 seconds using VIM and Neovim!
AdventOfVim is part of the S909 project.
1. Getting Started
To begin, access today's challenge and carefully read the instructions below before attempting to solve it.
New here? scenario1
and scenario2
might be unfamiliar territory. These sprints are designed to stretch your limits – you'll need to tackle the problem from both angles, or your solution won't fly. So, if you're content to stay within your comfort zone, this sprint isn't for you. Start with the first episode and give it a go yourself. Spend at least 15 minutes grappling with both scenarios before peeking at the solutions.
Remember, make sure that you are in sync with your team, if you don't have a team yet submit your application here forms.gle/bwegPDvbgEuWKDF47
Good luck!
1.2 Sample data
The provided sample data should be used for testing the commands. Once you feel comfortable and confident, you can apply these commands to your actual input data.
Input:
2-4,6-8
2-3,4-5
5-7,7-9
2-8,3-7
6-6,4-6
2-6,4-8
Expected output:
part1: 2
part2: 4
2. Solutions
This guide assumes you've already watched the accompanying walk-through YouTube video. If you haven't, please do.
2.1 The First Scenario
2.1.1 Part One
To achieve our goal of parsing each line, checking if one range fully contains the other, and then printing the final score, we can leverage the power of awk.
First, let's ensure that awk can easily distinguish each column field by removing unnecessary delimiters and replacing them with spaces. Execute the following command in vim:
:%s/\D/ /g
Now, let's proceed with awk:
:%!awk '{s+= ($1 >= $3 && $2 <= $4) || ($3 >= $1 && $4 <= $2)} END{print s}'
2.1.2 Part Two
For the second part, our objective is to test if the two ranges are overlapping. One way to accomplish this is as follows:
:%!awk '{s+= ($1 >= $3 && $1 <= $4) || ($3 >= $1 && $3 <= $2)} END{print s}'
We've successfully solved the whole challenge. Well done!
2.2 The Second Scenario
Now, let's turn our attention to the second scenario. This time, we'll be writing a Vim script to achieve the desired outcome. Here's a step-by-step guide:
Read all lines.
Split each line by non-digit characters using
split(x, '\D')
.Convert the resulting substrings to numbers using
str2nr()
.Compare both ranges.
Echo the sum.
Feel free to craft your Vim script based on these guidelines. This approach provides a clear roadmap for processing the data and obtaining the desired result. Good luck!
5. Exercises
In case you care about this content, follow me on Twitter. I sometimes tweet the hints and solutions for these exercises, however I want you to spend some time with the exercises on your own and with your team.
Twitter is too noisy, make sure to enable notifications to be notified otherwise you'll miss out.
No matter which method we choose, some repetitions are unavoidable. However, our initial task is to streamline the data into a consistent format. Specifically, we want all ranges on the left to be smaller than those on the right. use awk to achieve this.
Using the refined data, solve Part1 and Part2. do you notice the difference—no need to repetitively test range2 against range1.
For a deeper dive into useful Vimscript functions, let's explore an alternative to
split(x, '\D')
. Instead, usesubstitute()
, thensplit()
. Finally, achieve the same result using onlymatchlist()
.In real-world scenarios, data often arrives in messy formats. Challenge yourself to solve Part1 and Part2 using only regex, treating the ranges as strings. Refer to the provided walkthrough video for hints. Generate ranges on each line, then utilize regex to compare them, and ultimately print the sum. Additionally, consider using
tr
, for example ifecho '1 2 3 4 5' | tr -d '1 2'
that means range[1,2]
is fully within because it was deleted from1 2 3 4 5
.You need to integrate your daily programming language inside Vim so that you can use it to generate data, manipulate data, and solve any hurdles that you might come across. This will help you save time and increase productivity.
Modify your setup so that you can use the language that you know best within Vim anytime you like.
Your main language may offer superior tools. For example, instead of re-implementing the wheel and wasting time, what if we can say
rangeA in rangeB
andx in rangeB
? We can save a lot of work.Help Vim understand your language so that it can call your language compiler seamlessly.
If your main language doesn’t have these cool features, you may already be familiar with libraries that you load all the time and maybe they are powerful. For example, if you are using JavaScript, Imagine that there is a super famous library called XY that gives us two awesome functions:
range(1,10).in(range(2,4))
orin(range(1,10), range(2,4))
. It would be awesome if we were able to solve the whole challenge using something like that.In normal/insert mode, you need to be capable of using your language and capturing its output and directly inserting it in the current buffer you are working at or replacing the line that it was invoked from (map a special key so that it can happen in less than a second). For example, if you are using JavaScript and you type
log('hi')
, then if you try to call node, it will throw an error thatlog doesn’t exist
. So, figure out a way to load all your favorite modules and libs automatically every time you call node.Now that you have enhanced your setup, and you can evaluate your main language in microseconds anywhere in Vim, it’s time to resolve part 1 and part 2 using your language.
Share your setup for the previous exercise in our Discord channel
#tips
. Please mention the programming language you use.