github.com/frodejac/aoc-2022@v0.0.0-20221213081734-037c741b1c89/internal/aoc/day02/day02.go (about)

     1  package day02
     2  
     3  import (
     4  	"strconv"
     5  	"strings"
     6  
     7  	"github.com/frodejac/aoc-2022/pkg/arraytools"
     8  	"github.com/frodejac/aoc-2022/pkg/maptools"
     9  )
    10  
    11  func getPriorities() map[string]int {
    12  	priorities := make(map[string]int)
    13  	for i, c := range strings.Split("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ", "") {
    14  		priorities[c] = i + 1
    15  	}
    16  	return priorities
    17  }
    18  
    19  type rucksack struct {
    20  	compartment1 map[string]int
    21  	compartment2 map[string]int
    22  }
    23  type Day02 struct {
    24  	rucksacks  []rucksack
    25  	priorities map[string]int
    26  }
    27  
    28  func Solver(input []byte) *Day02 {
    29  	return &Day02{rucksacks: parseInput(string(input)), priorities: getPriorities()}
    30  }
    31  
    32  func parseInput(input string) []rucksack {
    33  	input = strings.TrimSpace(input)
    34  	lines := strings.Split(input, "\n")
    35  	rucksacks := make([]rucksack, len(lines))
    36  	for i := 0; i < len(lines); i++ {
    37  		rucksacks[i] = rucksack{compartment1: make(map[string]int), compartment2: make(map[string]int)}
    38  		chars := strings.Split(lines[i], "")
    39  		for j := 0; j < len(chars)/2; j++ {
    40  			rucksacks[i].compartment1[chars[j]]++
    41  		}
    42  		for j := len(chars) / 2; j < len(chars); j++ {
    43  			rucksacks[i].compartment2[chars[j]]++
    44  		}
    45  	}
    46  	return rucksacks
    47  }
    48  
    49  func findDuplicate(r rucksack) string {
    50  	for a := range r.compartment1 {
    51  		for b := range r.compartment2 {
    52  			if a == b {
    53  				return a
    54  			}
    55  		}
    56  	}
    57  	return ""
    58  }
    59  
    60  func (d *Day02) SolvePart1() string {
    61  	total := 0
    62  	for _, r := range d.rucksacks {
    63  		commonItem := findDuplicate(r)
    64  		total += d.priorities[commonItem]
    65  	}
    66  	return strconv.Itoa(total)
    67  }
    68  
    69  func findGroupBadge(group []rucksack) string {
    70  	r := maptools.Merge(group[0].compartment1, group[0].compartment2)
    71  	intersection := maptools.Keys(r)
    72  
    73  	for _, g := range group[1:] {
    74  		r := maptools.Merge(g.compartment1, g.compartment2)
    75  		intersection = arraytools.Intersect(intersection, maptools.Keys(r))
    76  	}
    77  
    78  	if len(intersection) == 1 {
    79  		return intersection[0]
    80  	}
    81  
    82  	return ""
    83  }
    84  
    85  func (d *Day02) SolvePart2() string {
    86  	groupSize := 3
    87  	total := 0
    88  	for i := 0; i < len(d.rucksacks); i += groupSize {
    89  		group := d.rucksacks[i : i+groupSize]
    90  		badge := findGroupBadge(group)
    91  		total += d.priorities[badge]
    92  	}
    93  	return strconv.Itoa(total)
    94  }