2023 Day 3 Complete!
This commit is contained in:
110
2023/day03/main.go
Normal file
110
2023/day03/main.go
Normal file
@@ -0,0 +1,110 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
h "git.bullercodeworks.com/brian/adventofcode/helpers"
|
||||
)
|
||||
|
||||
func main() {
|
||||
inp := h.StdinToStringSlice()
|
||||
part1(inp)
|
||||
part2(inp)
|
||||
}
|
||||
|
||||
func part1(input []string) {
|
||||
bm := h.StringSliceToCoordByteMap(input)
|
||||
symbols := bm.FindAllNot('0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '.')
|
||||
// Gather a list of numbers that are adjacent to the symbols
|
||||
nums := make(map[h.Coordinate]int)
|
||||
for k, _ := range symbols {
|
||||
wrk := findPartNumsFrom(bm, k)
|
||||
for coord, val := range wrk {
|
||||
nums[coord] = val
|
||||
}
|
||||
}
|
||||
var sum int
|
||||
for _, v := range nums {
|
||||
sum += v
|
||||
}
|
||||
fmt.Println("# Part 1")
|
||||
fmt.Println(sum)
|
||||
}
|
||||
|
||||
func part2(input []string) {
|
||||
bm := h.StringSliceToCoordByteMap(input)
|
||||
maybeGears := bm.FindAll('*')
|
||||
var ratioSum int
|
||||
for _, k := range maybeGears {
|
||||
wrk := findPartNumsFrom(bm, k)
|
||||
if len(wrk) != 2 {
|
||||
// It's not a gear
|
||||
continue
|
||||
}
|
||||
var second bool
|
||||
var ratio int
|
||||
for _, v := range wrk {
|
||||
if !second {
|
||||
ratio += v
|
||||
second = true
|
||||
} else {
|
||||
ratio *= v
|
||||
}
|
||||
}
|
||||
ratioSum += ratio
|
||||
}
|
||||
fmt.Println("# Part 2")
|
||||
fmt.Println(ratioSum)
|
||||
}
|
||||
|
||||
func findPartNumsFrom(m h.CoordByteMap, c h.Coordinate) map[h.Coordinate]int {
|
||||
partNums := make(map[h.Coordinate]int)
|
||||
for _, chk := range []h.Coordinate{
|
||||
c.North(),
|
||||
c.NE(),
|
||||
c.East(),
|
||||
c.SE(),
|
||||
c.South(),
|
||||
c.SW(),
|
||||
c.West(),
|
||||
c.NW(),
|
||||
} {
|
||||
if m.Get(chk) >= '0' && m.Get(chk) <= '9' {
|
||||
v, pos := parseNumAt(m, chk)
|
||||
partNums[pos] = v
|
||||
}
|
||||
}
|
||||
return partNums
|
||||
}
|
||||
|
||||
// parseNumAt returns the number at c and the Coordinate
|
||||
// that the first digit of that number is at
|
||||
func parseNumAt(m h.CoordByteMap, c h.Coordinate) (int, h.Coordinate) {
|
||||
var resStr string
|
||||
startCoord := c
|
||||
// From 'c' move left until we find the first digit
|
||||
chk := m.Get(startCoord)
|
||||
for coordIsNum(m, startCoord) {
|
||||
startCoord = startCoord.West()
|
||||
chk = m.Get(startCoord)
|
||||
}
|
||||
startCoord = startCoord.East()
|
||||
|
||||
// Now put the number at 'startCoord' together
|
||||
parseNum := startCoord
|
||||
chk = m.Get(startCoord)
|
||||
for coordIsNum(m, parseNum) {
|
||||
resStr = fmt.Sprintf("%s%s", resStr, string(chk))
|
||||
parseNum = parseNum.East()
|
||||
chk = m.Get(parseNum)
|
||||
}
|
||||
if resStr == "" {
|
||||
return -1, h.Coordinate{X: -1, Y: -1}
|
||||
}
|
||||
return h.Atoi(resStr), startCoord
|
||||
}
|
||||
|
||||
func coordIsNum(m h.CoordByteMap, c h.Coordinate) bool {
|
||||
wrk := m.Get(c)
|
||||
return wrk >= '0' && wrk <= '9'
|
||||
}
|
||||
Reference in New Issue
Block a user