# Advent of code 2021: Day 13

This article is part of a series where I'll be diving head first into the Advent of code 2021. I'll be documenting the challenge of solving such a puzzle and how I got to the answer. I want to prefix this by stating that I can't cheat for any of these challenges; with that, I mean I can't look up any other implementations online.

### Part 1

The puzzle input this time around is a list of points, visualize the points on a piece of transparent paper and use the fold instructions. The first question is: how many points are left visible after the first fold?

I didn’t think this challenge was especially hard, after writing my initial code and after some refactoring I got to the resulting code down below:

``````use std::fs;
use std::collections::HashSet;

type Points = HashSet<(usize, usize)>;
type Folds<'a> = Vec<(&'a str, usize)>;

fn fold_paper(points: &mut Points, folds: &Folds, times: usize) {
for i in 0..times {
let (axis, value) = folds[i];
let height = points.iter().map(|n| n.1).max().unwrap();
let width = points.iter().map(|n| n.0).max().unwrap();

let mut folds: Points = HashSet::new();
let mut unfolds: Points = HashSet::new();

for (x, y) in points.iter() {
let val = if axis == "y" { *y } else { *x };

if val > value {
folds.insert((*x, *y));
} else if val < value {
unfolds.insert((*x, *y));
}
}

for (x, y) in folds {
let folded_point = if axis == "y" {
(x, height - y)
} else {
(width - x, y)
};

points.remove(&(x, y));
points.insert(folded_point);
}
}
}
``````

The `fold_paper`-method changes whatever `HashSet` you pass to `points` inline. It takes a set of `folds` and the amount of fold instructions you want to execute on the `points` set. It first determines the maximum x-value and maximum y-value. Next up, it makes two lists, a list of points above (or left of) the fold and a list of points below (or right of) the fold. The next step is to move over all the points below (or right of) the fold and move it’s y-value or x-value, depending on which axis the fold occurs. The points list needs to remove the initial point below (or right of) the fold and insert instead the new `folded_point`. It can happen that `folded_point` already exists in the list of points, but considering I’m using a HashSet, this duplicate will not get added to the set.

To resolve the first part all I had to write is:

``````let mut points_clone = points.clone();
fold_paper(&mut points_clone, &folds, 1);
assert_eq!(points_clone.len(), 17);
``````

### Part 2

In the second part - and no surprises here - it asks to execute all the fold instructions. After doing so, an 8-letter code should appear when plotting the dots. This was a bit more tricky, but not because the code was hard, but more because the folds didn’t work. There was no other example in the puzzle, so I made my way to Reddit. It has a bug in the input, as this Reddit user points out . I tricked the input, but you can also do it with a mod-check according to the thread.

Another funny thing happened where the code contained a letter `V` in my case, which turned out to be a `U`. To make it more clear, I used the black and white square-emoji’s to display the letter, but it made it even less clear. I’ll blame this on the limitations of using a 4x6 raster to display a letter in.

``````fn display_paper(points: &Points) {
let height = points.iter().map(|n| n.1).max().unwrap() + 1;
let width = points.iter().map(|n| n.0).max().unwrap() + 1;
let mut paper = vec![vec!['⬛'; width]; height];

for (x, y) in points {
paper[*y][*x] = '⬜';
}

println!("");
for line in paper {
let s: String = line.into_iter().collect();
println!("{}", s);
}
}
``````

Code I wrote to execute the second part:

``````let mut points_clone = points.clone();
fold_paper(&mut points_clone, &folds, folds.len());
display_paper(&points_clone);
``````

Solved! ⭐️⭐️

### Sources

The full solution is available on GitHub.