< up >
2020-12-01 13:03:45 +0100 CET

AoC day 1

The puzzles of day one were easy to solve in the first place, but have more potential to optimize than I thought.

Problem

Find n summands which add up to 2020. Solution of the puzzle is the product of all summands where n=2 in puzzle one and n=3 in puzzle two.

Solution

The idea was to find all unique subsets with n elements, where n=2 in the algorithm below.

// ex: input array of integers
for i := 0; i < len(ex); i++ {
  for j := i + 1; j < len(ex); j++ {
    if ex[i]+ex[j] == 2020 {
      fmt.Printf("Found %d + %d = 2020\n", ex[i], ex[j])
      fmt.Printf("%d x %d = %d\n", ex[i], ex[j], ex[i] * ex[j])
    }
  }
}

The count of nested loops is equal to n which makes each subset accessible in the innermost loop. To ensure that the subset is unique, each inner loop starts with the index of the next outer loop plus one. By adding one all subsets are being skipped which share the same number.

Uniquness is important to conquer both: Performance and wrong solutions. With unique subsets less than half the sums have to be calculated. Despite that, the puzzle says that all summands have to be different.

Visualization

On n=2, a simple brute force approach where the indices of all nested loops start at zero could be visualized with the following table. It shows the sum of all subsets with two elements made up from the input .

1 2 3 4
1 2 3 4 5
2 3 4 5 6
3 4 5 6 7
4 5 6 7 8

The first observation one can make is the symmetry of the table. This is caused by the commutation property of addition which basically states that x+y = y+x. Good for us, we can get rid of almost one half and reduce the iteration count.

The next observation, is the diagonal. It is only made up of sums where the summands are equal. Better for us, we can get rid of them either.