github.com/vpayno/adventofcode-2022-golang-workspace@v0.0.0-20230605190011-dbafed5593de/internal/day01/app.go (about)

     1  // Package day01 is the module with the cli logic for the application.
     2  package day01
     3  
     4  import (
     5  	"bufio"
     6  	"fmt"
     7  	"sort"
     8  	"strconv"
     9  
    10  	"github.com/vpayno/adventofcode-2022-golang-workspace/internal/aocshared"
    11  )
    12  
    13  // Run is called my the gain function. It's basically the main function of the app.
    14  func Run(conf Config) error {
    15  	file, err := aocshared.GetFile(conf.inputFileName)
    16  	if err != nil {
    17  		return err
    18  	}
    19  
    20  	scanner := aocshared.GetScanner(file)
    21  
    22  	data, err := loadData(scanner)
    23  	if err != nil {
    24  		return err
    25  	}
    26  
    27  	topCalories := getMaxCalories(data)
    28  
    29  	aocshared.ShowResult(topCalories)
    30  
    31  	topThreeCalories := getResultTopThreeCalories(data)
    32  
    33  	aocshared.ShowResult(topThreeCalories)
    34  
    35  	return nil
    36  }
    37  
    38  func loadData(file *bufio.Scanner) (map[string]int, error) {
    39  	var err error
    40  
    41  	data := map[string]int{}
    42  
    43  	var elfCounter = 1
    44  	var calories int
    45  
    46  	for file.Scan() {
    47  		line := file.Text()
    48  
    49  		elfName := fmt.Sprintf("%s%d", "elf", elfCounter)
    50  
    51  		if line == "" {
    52  			elfCounter++
    53  			data[elfName] = calories
    54  			calories = 0
    55  
    56  			continue
    57  		}
    58  
    59  		calorie, err := strconv.Atoi(line)
    60  		if err != nil {
    61  			return map[string]int{}, err
    62  		}
    63  
    64  		calories += calorie
    65  	}
    66  
    67  	return data, err
    68  }
    69  
    70  func getMaxCalories(data map[string]int) int {
    71  	var result int
    72  
    73  	for _, calories := range data {
    74  		if calories > result {
    75  			result = calories
    76  		}
    77  	}
    78  
    79  	return result
    80  }
    81  
    82  func getTopThreeSum(calories []int) int {
    83  	var sum int
    84  
    85  	var start int
    86  
    87  	if len(calories) > 3 {
    88  		start += len(calories) - 3
    89  	}
    90  
    91  	sort.Ints(calories)
    92  
    93  	for _, calorie := range calories[start:] {
    94  		sum += calorie
    95  	}
    96  
    97  	return sum
    98  }
    99  
   100  func getResultTopThreeCalories(data map[string]int) int {
   101  	totals := []int{}
   102  
   103  	for _, calories := range data {
   104  		totals = append(totals, calories)
   105  	}
   106  
   107  	result := getTopThreeSum(totals)
   108  
   109  	return result
   110  }