aoc2025/day5/main.go

126 lines
2.3 KiB
Go
Raw Permalink Normal View History

2025-12-06 20:49:51 -05:00
package main
import (
"fmt"
"os"
"sort"
"strconv"
"strings"
)
func main() {
filename := "input0.txt"
if len(os.Args) > 1 {
filename = os.Args[1]
}
lines := readLines(filename)
kitchen := parseKitchen(lines)
fmt.Printf("%d\n", kitchen.countFreshIngredients())
fmt.Printf("%d\n", kitchen.countEverythingFresh())
}
func readLines(filename string) []string {
raw, err := os.ReadFile(filename)
if err != nil {
panic(err)
}
return strings.Split(string(raw), "\n")
}
type container struct {
start uint64
stop uint64
}
func (i container) contains(id uint64) bool {
return i.start <= id && i.stop >= id
}
type kitchen struct {
coolers []container
ingredients []uint64
}
func (k kitchen) countFreshIngredients() uint64 {
total := uint64(0)
INGREDIENTS:
for _, ingredient := range k.ingredients {
for _, cooler := range k.coolers {
if cooler.contains(ingredient) {
total++
continue INGREDIENTS
}
}
}
return total
}
func parseKitchen(lines []string) kitchen {
k := kitchen{
coolers: []container{},
ingredients: []uint64{},
}
coolers := true
for _, line := range lines {
if line == "" {
coolers = false
continue
}
if coolers {
parts := strings.Split(line, "-")
cooler := container{}
cooler.start, _ = strconv.ParseUint(parts[0], 10, 64)
cooler.stop, _ = strconv.ParseUint(parts[1], 10, 64)
k.coolers = append(k.coolers, cooler)
} else {
id, _ := strconv.ParseUint(line, 10, 64)
k.ingredients = append(k.ingredients, id)
}
}
return k
}
func (k kitchen) countEverythingFresh() uint64 {
type pivot struct {
id uint64
start bool
}
pivots := []pivot{}
for _, cooler := range k.coolers {
pivots = append(pivots,
pivot{id: cooler.start, start: true},
pivot{id: cooler.stop, start: false},
)
}
sort.Slice(pivots, func(i, j int) bool {
pi, pj := pivots[i], pivots[j]
if pi.id < pj.id {
return true
}
if pi.id > pj.id {
return false
}
if !pi.start && pj.start {
return false
}
return true
})
total := uint64(0)
insideStarted := uint64(0)
within := uint16(0)
for _, pivot := range pivots {
if pivot.start {
if within == 0 {
insideStarted = pivot.id
}
within++
} else {
within--
if within == 0 {
total += 1 + pivot.id - insideStarted
}
}
}
return total
}