Jesper Dramsch , , read in 3 minutes

## What is Advent of Code?

In this little series, I want to write about the thought processes I have behind solving the puzzles presented in Advent of Code.

During the Advent of Code small coding puzzles are presented with varying levels of difficulty. They're always Christmas-themed text puzzles where you help elves out of some mess to save the holidays. The puzzles are deliberately ambiguous to not bias puzzlers into a certain solution, they always have an example input in the text to explain some details and an input file for each day that comes in the form of a text file you can download. The solution is a simple number or a string you enter, which is checked by the website automatically. After you finish part 1, part 2 unlocks, which is a variation on part 2. This can be a little twist on part 1 or a large twist that changes the problem formulation into a problem that would take brute force solutions to compute longer than the heat death of the universe would take.

These descriptions won't be a perfect narrative, but rather how I think about these problems and where I see different solutions. I apologise for the possibility of rambling!

## The example input

The name is "Tuning Troubles" and this as the only example? We're cracking codes today!

```mjqjpqmgbljsphdztnvjfqwrcgsmlb
```

Let's explore!

## The implementation

So we need to find the first "unique" start marker in a stream of data.

It feels like part 1 is fairly easy to solve and I have no idea what part 2 could be, so I don't want to optimise early for what I anticipate to come.

Don't over-complicate, when the specification is really that simple.

I'm going back to sets, because the task is to find non-unique items. So I'd easily have the length of just the variable, instead of having to come up with some logic of comparing everything to everything.

```(x, set(day.data[x-i] for i in range(4))) for x in range(3, len(day.data))
```

## Part Deux

Keeping it simple turned out well, some refactoring into a function, and I was able to abstract both marker finders into a one-liner

```def find_marker(data, length):
for x in range(length - 1, len(data)):
items = set(data[x-length:x])
if len(items) == length:
return x
```

When these get long enough, it'd be smart to build in a way to skip indices, once we have a duplicate. But this ran quick enough, so I'll keep it for now, because it'd also imply a pretty significant change away from the `set` logic.

## Error Log

A couple of indexing errors in this one, the usual...

• Got an empty list, but caught that early, because I didn't want to mess up with this new data. There are no splits and it's a singular string, so I figured my standard loader might not love it.
• Put the data `mjqjpqmgbljsphdztnvjfqwrcgsmlb` as the solution to the test example. That was a simple enough brain fart.
• `day.data = [i, set(day.data[x-i] for i in range(4)) for x in range(3, len(day.data))] SyntaxError: invalid syntax`, forgot parantheses
• `IndexError: list index out of range` messing up the index shifting in the stream
• Off-by-one error, because the puzzle expects 1-indexed numbers.
• Didn't change the variable name from `day.data` to `data` when refactoring into a function for part 2.