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
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|