< up >
2022-12-01

aoc22-1 - reaching for the stars (again)

This year’s AoC starts right in the rain forest with a nutrition puzzle.

Problem: Find the elves (one for part 1 and three for part 2) carrying the most calories.

Solution:

Stellar

I created a utility lib for reoccurring problems: Stellar. While the puzzle such as pretty trivial, extracting and generalizing the ‘find-max-n-values’ approach was more interesting.

Original solution:

func part2(data []string) int {
  calories := make([]int, 0)
  // ...add all sums to the calories array 

  sort.Ints(calories)
  l := len(calories)
  return calories[l-1] + calories[l-2] + calories[l-3]
}

Generic max-n solution for Stellar:

func MaxN[T Number](nums []T, n int) []T {
  if len(nums) < n {
    return nil
  }

  sort.Slice(nums, func(i, j int) bool { return nums[i] > nums[j] })
  return nums[0:n]
}

Solution using MaxN:

func maxCalories(data []string, n int) int {
  calories := make([]int, 0)
  currentCalories := 0
  for i, row := range data {
    if row != "" && i < len(data)-1 {
      currentCalories += strings.ToInt(row)
      continue
    }

    calories = append(calories, currentCalories)
    currentCalories = 0
  }

  return math.Sum(math.MaxN(calories, n))
}

For completeness, I also added MinN by inverting the sort comparison:

func MinN[T Number](nums []T, n int) []T {
  if len(nums) < n {
    return nil
  }

  sort.Slice(nums, func(i, j int) bool { return nums[i] < nums[j] })
  return nums[0:n]
}