advent-of-code/aoc2023/day03/main.go

129 lines
2.5 KiB
Go
Raw Permalink Normal View History

2023-12-03 10:13:40 -07:00
package main
import (
"bufio"
_ "embed"
"fmt"
"strconv"
2023-12-15 15:13:24 -07:00
aoc "go.sour.is/advent-of-code"
2023-12-09 14:57:02 -07:00
)
2023-12-03 10:13:40 -07:00
2023-12-13 08:32:37 -07:00
func main() { aoc.MustResult(aoc.Runner(run)) }
2023-12-03 10:13:40 -07:00
type partNumber struct {
number int
row int
col int
end int
hasSymbol bool
}
type symbol struct {
2023-12-03 10:34:13 -07:00
symbol rune
row int
col int
adjacentParts []*partNumber
2023-12-03 10:13:40 -07:00
}
2023-12-03 10:34:13 -07:00
type symbolTab map[int]map[int]*symbol
2023-12-03 10:13:40 -07:00
2023-12-03 12:59:14 -07:00
func (tab symbolTab) hasSymbol(row, col int, p partNumber) bool {
2023-12-03 10:13:40 -07:00
if cols, ok := tab[row]; ok {
2023-12-03 10:34:13 -07:00
s, ok := cols[col]
if ok {
s.adjacentParts = append(s.adjacentParts, &p)
cols[col] = s
}
2023-12-03 10:13:40 -07:00
return ok
}
return false
}
2023-12-03 12:59:14 -07:00
func (tab symbolTab) scanSymbol(p partNumber) bool {
2023-12-03 10:13:40 -07:00
rowStart, rowEnd := max(p.row-1, 0), p.row+1
colStart, colEnd := max(p.col-1, 0), p.end+1
for i := rowStart; i <= rowEnd; i++ {
for j := colStart; j <= colEnd; j++ {
2023-12-03 12:59:14 -07:00
ok := tab.hasSymbol(i, j, p)
2023-12-03 10:13:40 -07:00
if ok {
return true
}
}
}
return false
}
2023-12-03 12:59:14 -07:00
// 553079
// 84363105
2023-12-09 14:57:02 -07:00
type result struct {
valuePT1 int
valuePT2 int
}
2023-12-03 10:13:40 -07:00
2023-12-09 14:57:02 -07:00
func run(scan *bufio.Scanner) (*result, error) {
2023-12-03 10:13:40 -07:00
parts := []partNumber{}
2023-12-03 10:34:13 -07:00
symbols := make(symbolTab)
symbolList := []*symbol{}
2023-12-03 12:59:14 -07:00
row := 0
2023-12-03 10:13:40 -07:00
for scan.Scan() {
text := scan.Text()
2023-12-03 12:59:14 -07:00
row += 1
2023-12-03 10:13:40 -07:00
slice := make([]rune, 0, 3)
var col int
for i, a := range text {
col = i
if a >= '0' && a <= '9' {
slice = append(slice, a)
continue
}
if v, err := strconv.Atoi(string(slice)); err == nil {
parts = append(parts, partNumber{number: v, row: row, col: col - len(slice), end: col - 1})
slice = slice[:0]
}
if a != '.' {
cols, ok := symbols[row]
if !ok {
2023-12-03 10:34:13 -07:00
cols = make(map[int]*symbol)
2023-12-03 10:13:40 -07:00
}
2023-12-03 10:34:13 -07:00
s := &symbol{row: row, col: col, symbol: a}
cols[col] = s
2023-12-03 10:13:40 -07:00
symbols[row] = cols
2023-12-03 10:34:13 -07:00
symbolList = append(symbolList, s)
2023-12-03 10:13:40 -07:00
}
}
if v, err := strconv.Atoi(string(slice)); err == nil {
parts = append(parts, partNumber{number: v, row: row, col: col - len(slice), end: col - 1})
slice = slice[:0]
2023-12-09 14:57:02 -07:00
_ = slice
2023-12-03 10:13:40 -07:00
}
}
2023-12-13 08:32:37 -07:00
sum := aoc.SumIFunc(
func(i int, p partNumber) int {
ok := symbols.scanSymbol(p)
parts[i].hasSymbol = ok
if ok {
return p.number
}
return 0
2023-12-15 15:13:24 -07:00
}, parts...)
2023-12-03 10:13:40 -07:00
2023-12-13 08:32:37 -07:00
sumGears := aoc.SumFunc(
func(s *symbol) int {
if s.symbol == '*' && len(s.adjacentParts) == 2 {
return s.adjacentParts[0].number * s.adjacentParts[1].number
}
return 0
}, symbolList...)
2023-12-03 10:34:13 -07:00
2023-12-03 12:59:14 -07:00
// fmt.Println(parts)
// fmt.Println(symbols)
// fmt.Println(symbolList)
fmt.Println("part1:", sum)
fmt.Println("part2:", sumGears)
2023-12-09 14:57:02 -07:00
return &result{sum, sumGears}, nil
2023-12-03 10:13:40 -07:00
}