Custom Customs
Tags: adventofcode, algorithms, computerscience, programming
Published: 2022-04-11 18:28:02

## [Advent of Code 2020 Day 6](https://adventofcode.com/2020/day/6)

## Task: Solve for X where...
Part 1:
```
X = the sum of each group's count of unique questions answered 'yes'
```

Part 2:
```
X = the sum of each group's count of shared questions answered 'yes'
```

### Example input
```
abc

a
b
c

ab
ac

a
a
a
a

b
```

It represents
- Questions answered 'yes'
- By a single passenger per line
- By a group of passengers separated by empty lines

## Part 1
1. Is it as simple as counting unique values in a set?
2. Yes, it was that simple!

### Is it as simple as counting unique values in a set?
Given this group:
```
abcx
abcy
abcz
```

Represented as a string:
```js
'abcx\nabcy\nabcz'
```

With new line characters removed
```js
'abcxabcyabcz'
```

Split into an array of characters:
```
['a','b','c','x','a','b','c','y','a','b','c','z']
```

Each character added to a set of unique values
```
abcxabcyabcz
++++xxx+xxx+

abcx   y   z

abcxyz
```

Return the size of the set
```
6
```

### Yes, it was that simple!
```
Split the input at each double-new-line character to generate an array of strings

For each string, accumulate a sum - starting from 0
  Add to the sum the result of these operations:
    Remove any new-line characters in the current string
    Split the string into an array of characters
    For each character, accumulate a unique set of values - starting empty
      Attempt to add the current character to the set
      Return the set containing all unique characters added
    Return the size of the unique set

Return the sum of all set sizes
```

Here's that algorithm written in JavaScript
- a stands for accumulator
- c stands for current

```js
input
  .split('\n\n')
  .reduce((a,c) => a += c
    .replaceAll('\n','')
    .split('')
    .reduce((a,c) => a.add(c), new Set()).size
   ,0)
```

Here's a visualization of that algorithm
![Visualization of Part 1 algorithm](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rfpdqfh4wha4xyt2u0v7.gif)

## Part 2

### Refactoring Part 1 in a jiffy
```
Split the input at each double-new-line character to generate an array of strings

For each string, accumulate a sum - starting from 0
  Add to the sum the result of these operations:
    Store as the variable, groups:
      Split each string at the new-line character to create an array of strings
      Split each string into an array of characters
    Checking only the first array in groups:
      For each character, accumulate a unique set of values - starting empty
        If the character exists in each of the arrays inside groups
          Attempt to add the current character to the set
        Return the set containing all unique characters added
      Return the size of the unique set

Return the sum of all set sizes
```

Here's my algorithm written in JavaScript
```js
stream
  .split('\n\n')
  .reduce(
    (a1, c1) => {
      let groups = c1
        .split('\n')
        .map(el => el.split(''))
      return a1 += groups[0]
        .reduce(
          (a2,c2) => groups.every(i => i.includes(c2)) 
            ? a2.add(c2)
            : a2, new Set()
        )
        .size
    }, 0)
```

Here's a visualization of my algorithm
![Visualization of Part 2's algorithm](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/h9cq7bn5v72o48a8rpgr.gif)

That puzzle felt easy.

Which is proof of how much I've learned.

Because I recall skipping this puzzle nearly a year ago when I first skimmed the instructions.

Hooray for the demonstrable feeling of self-improvement and accomplishment!