## DEV Community

Minna N. for Ompeluseura LevelUP Koodarit

Posted on • Updated on

# What I've learned from the Advent of Code so far (days 1-5)

I consider myself an advanced beginner in programming. I lack a lot of knowledge in best practices, gotchas, elegance... let alone algorithms, optimizations... I have no clue.

I'm quite sure I won't make it through Advent of Code but I wanted to give it a go anyway. I first thought to use Java to solve the puzzles because I'm more comfortable processing line-by-line input and doing "tricks" with it (I did a comprehensive course on it just at the beginning of this year), but decided on JavaScript because it's more beneficial for the things I'm learning at the moment.

On the first five days, I had a couple of facepalm moments ๐คฆ but also some proud moments ๐.

Here are some of the things that have helped me on puzzle-solving days 1-5.

# Neat feature: Destructuring

On day 2 I was quite proud of myself for remembering the destructuring assignment feature. The task is to process a list with the following data:

``````int-int char: string
``````

For example:

``````1-3 a: abcde
1-3 b: cdefg
2-9 c: ccccccccc
``````

One line contains a password policy and a password, so first I separated the policy from the password

``````const [policy, password] = line.split(': ');
``````

Then I separated the numbers from the character in the policy:

``````const [amount, character] = policy.split(' ');
``````

And finally the first number and the second number (representing min and max values in the first part of the puzzle and two positions in the second part):

``````const [min, max] = amount.split('-');
``````

Very handy!

# Neat method: Array.from()

For the colour code validation on day 4, I use `indexOf()`. First I had an array with the possible values like so:

``````let validChars = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'];
``````

I got a tip to make it sooo much more elegant:

``````let validChars = Array.from('0123456789abcdef');
``````

Coolio! ๐ As it sounds like, here `Array.from()` creates an array from the given string.

If you are wondering why I'm processing the numbers as strings, it's just so much simpler because the valid characters are either numbers or strings. And actually, the value comes as a string to validation so `===` works more reliably this way.

I'm really digging this array of valid values, too. First I had

``````if (value === 'amb' ||
value === 'blu' ||
value === 'brn' ||
value === 'gry' ||
value === 'grn' ||
value === 'hzl' ||
value === 'oth' ) { ... }
``````

for the hair colour validation ๐ but I just changed it to

``````let validColors = ['amb', 'blu', 'brn', 'gry', 'grn', 'hzl', 'oth'];

if (validColors.indexOf(value) != -1) { ... }
``````

# Tip: Break up processing into functions

On day 4 you have to do data validation and I was puzzled by how I'd be able to end processing of an invalid value in a nested loop and get back to the outer loop to validate the next value. I got a tip โ one that I should remember by now โ that I should make more helper functions. There's no such thing as too many functions (within reason). ๐

My colour code validation was made much simpler with a helper function that returns either true or false.

``````function hexValidity(hexValue) {
let validChars = Array.from('0123456789abcdef');
let colourArray = Array.from(hexValue);

if (colourArray[0] != '#' || colourArray.length != 7) {
return false;
}

for (let i = 1; i < colourArray.length; i++) {
let currentChar = colourArray[i];

if (validChars.indexOf(currentChar) === -1) {
return false;
}
}
return true;
}
``````

# Tip: Create variables more often

The code is easier to read when you first assign results of functions, values from arrays, etc. in variables and use them in another structure. For example in my colour validation code for day 4, I first had:

``````if (validChars.indexOf(colourArray[i]) === -1) {
return false;
}
``````

Compare with

``````let currentChar = colourArray[i];

if (validChars.indexOf(currentChar) === -1) {
return false;
}
``````

# Tip: Use modulo where you can

I keep forgetting how useful (and multi-use) modulo `%` is.

For my toboggan trajectory on day 3, I skip to the beginning of the line ("horizontal index" 0) when I go over the length of the array (31) so in my code, I subtract the length from the horizontal index if it's over 30 (last possible index). With modulo, I could just use `index % 31` and be done with it.

If you have a situation where a value has to loop back to 0 at some point, use modulo.

# Best practice: Early exit

It's best to start by validating your data so you can break out of a loop/function as early as possible. For example on day 4, it's wise to check if the passport ID even has the required 9 characters before you start validating if each of the characters is a digit. Same with the hex colour codes: if it doesn't have a hash `#` at the beginning and exactly 6 characters after it, there's no point validating it in more detail.

# Take heed: Scope of variables

This was a moment of a huge facepalm. On day 4 you have to do data validation, which in itself is quite complicated to do for seven different value types.

After I'd extracted the value validation itself into a separate function, as mentioned above, I found myself facing an infinite loop. The code was able to process the first three values ok but then it got stuck looping with second and third value. A lot of debugging later, I was this much wiser: ๐ก remember to always declare the initial variable of a `for` loop ๐ก or the code may end up using a completely wrong variable.

I had forgotten the `let` from a couple of `for` loops where used `i` as the index counter. ๐คฆ

This actually brings to mind another tip for myself: keep in mind the existence of `for/of` loop! I could've made my code a lot simpler with it.

# A proud moment on day 3

First I was completely at a loss with the puzzle on day 3: how am I supposed to figure out a trajectory through lines of data? I don't know about vectors or any map algorithms.

I started visualizing the problem as a matrix, but then was unsure how that would be done in JavaScript (would've been easy-peasy in Java) but it got me a step further: I put the lines into an array (array item per line) for vertical movement and used `charAt` for the horizontal dimension of my "matrix". Once I had my function for the part 1 working and I was looking at part 2, I first thought "oh no, the function is going to be so messy with the for loop times 5". But then I realized, if I refactor my first function a bit I can reuse it by giving the numbers for traversing (x steps right, y steps down) as parameters and just assign the results to variables. ๐

Cover photo by Markus Spiske on Unsplash

Saija Saarenpรครค

Great post! I haven't had time to participate in the Advent of Code, but I still occasionally enjoy reading from others doing the tasks. I have one suggestion. Not necessarily an improvement, but an alternative way for the for loop for checking the hex code validity. This is also using the `includes` Ilรช Caian already mention about:

``````function hexValidity(hexValue) {
let validChars = Array.from('0123456789abcdef');
let colourArray = Array.from(hexValue);

if (colourArray[0] != '#' || colourArray.length != 7) {
return false;
}

return colourArray.slice(1).every(character => {
return validChars.includes(character);
});
}
``````

The `slice` function gives a sub array starting from the index 1, so it will omit the # sign. `every` function for the array iterates over every character of the array and returns true if all of the iterations return true. In case any of the iterations return false, the whole function returns false.

Minna N.

Ah, clever! Thanks for the code example!

Ilรช Caian

Awesome post! I'm also taking adventures at the Advent of Code this year and I think I can give some thoughts too:

• use of `Array.includes()`: returns `true` or `false` instead of the index
``````let validColors = ['amb', 'blu', 'brn', 'gry', 'grn', 'hzl', 'oth'];

if (validColors.includes(value)) { ... }
``````
• you can "empty-split" strings
``````const validChars = '0123456789abcdef'.split();
``````
• make use of `const` on variables that do not change (consider capitalizing some of them too)
``````const VALID_CHARS = '0123456789abcdef'.split();

if (VALID_CHARS.includes(letter)) { ... }
``````

I would also suggest using some of RegExp here and there. You can make good use of `.match()` and `.replace()` where you need to find patterns in repetitive strings. As an example, you can check the usage of `.replace()` at this solution

Keep coding!! ๐

Minna N.

Very good tips, thank you! I should've noticed `includes` and when I can use `const`. Actually, in my day 7 code (bags...) I use `includes`!

Thank you also for that code sample! I didn't know you can assign the groups into variables like that. ๐

A question which is either "hey, I'm able to give you a suggestion too!" OR there's some optimization magic going on that I don't know about. About the regex, you have:

`/(\d*)-(\d*) (\w): (\w*)/g,`

Is there a reason why you use `*` instead of `+`? Why not:

`/(\d)-(\d) (\w): (\w+)/g,`

(or \d+ in case the numbers are double or more digits)

Ilรช Caian

Thanks for noticing it! It's true that I could've used `+` instead of `*`!

About maintaining `\d`, I didn't see if the file has values with more than 1 digit, but with `*` or `+` will cover it! ๐

It's just a habit using `*` instead of `+` and maybe it could be optimized as you said!

Anniina Sallinen

Very nice post, sounds like you have learned a lot! The destructuring is available also in Python and Clojure, but I tend to forget it all the time ๐คฆโโ๏ธ For example when solving the Advent of Code puzzles ๐

syentix

I don't know why but my first thought with the validation on day 4 was RegEx

Minna N.

Oh yes, I would've done regex but I didn't know how. ๐ I'd come across regex in a search and replace usage only. I've improved a lot of my code "retroactively" so I'll probably look into regex solution as well because I like regex. ๐

Minna N.

Such luck: there is a post titled "How to use Regular Expressions in JavaScript" under Trending on DEV. Gotta check that out.

syentix

Regex is something yeah :D this site is great for testing out statements, also has useful tips :)

Minna N.