advent-of-code/aoc2024/day01/main.go

87 lines
1.3 KiB
Go
Raw Normal View History

2024-10-26 11:38:38 -06:00
package main
import (
"bufio"
_ "embed"
"fmt"
2024-12-01 11:38:06 -07:00
"iter"
"slices"
"sort"
2024-10-26 11:38:38 -06:00
aoc "go.sour.is/advent-of-code"
)
// var log = aoc.Log
func main() { aoc.MustResult(aoc.Runner(run)) }
type result struct {
valuePT1 int
valuePT2 int
}
func (r result) String() string { return fmt.Sprintf("%#v", r) }
func run(scan *bufio.Scanner) (*result, error) {
2024-12-01 11:38:06 -07:00
var (
left []int
right []int
)
2024-10-26 11:38:38 -06:00
for scan.Scan() {
2024-12-01 11:38:06 -07:00
txt := scan.Text()
2024-10-26 11:38:38 -06:00
2024-12-01 11:38:06 -07:00
var l, r int
_, err := fmt.Sscanf(txt, "%d %d", &l, &r)
if err != nil {
return nil, err
}
left = append(left, l)
right = append(right, r)
2024-10-26 11:38:38 -06:00
}
2024-12-01 11:38:06 -07:00
sort.Ints(left)
sort.Ints(right)
result := &result{}
result.valuePT1 = aoc.Reduce(func(i int, z pair[int, int], sum int) int {
return sum + aoc.ABS(z.L-z.R)
}, 0, zip(slices.Values(left), slices.Values(right)))
rmap := aoc.Reduce(func(i int, z int, m map[int]int) map[int]int {
m[z]++
return m
}, make(map[int]int), slices.Values(right))
for _, v := range left {
if r, ok := rmap[v]; ok {
result.valuePT2 += v*r
}
}
return result, nil
}
type pair[L, R any] struct {
L L
R R
2024-10-26 11:38:38 -06:00
}
2024-12-01 11:38:06 -07:00
func zip[L, R any](l iter.Seq[L], r iter.Seq[R]) iter.Seq[pair[L,R]] {
return func(yield func(pair[L, R]) bool) {
pullR, stop := iter.Pull(r)
defer stop()
for l := range l {
r, _ := pullR()
if !yield(pair[L, R]{L: l, R: r}) {
return
}
}
}
}