146 lines
4.0 KiB
Go
146 lines
4.0 KiB
Go
package day03
|
|
|
|
import (
|
|
"adventofcode2023/utils"
|
|
_ "adventofcode2023/utils"
|
|
_ "adventofcode2023/utils/grid2d"
|
|
"adventofcode2023/utils/inputs"
|
|
"errors"
|
|
"fmt"
|
|
"unicode"
|
|
)
|
|
|
|
type Coord struct {
|
|
x int
|
|
y int
|
|
}
|
|
type Part struct {
|
|
number string
|
|
location Coord
|
|
}
|
|
|
|
func Part1(input string) int {
|
|
grid := inputs.ToGrid2D(input, "\n", "", ".", func(c string) string { return c})
|
|
partLocs := []Coord{}
|
|
for j := 0; j < grid.SizeY(); j++ {
|
|
for i := 0; i < grid.SizeX(); i++ {
|
|
if !unicode.IsDigit(rune(grid.Get(i, j)[0])) { continue}
|
|
directions := [][]int{{0, 1}, {0, -1}, {1, 0}, {-1, 0},{-1,1},{1,1},{-1,-1},{1,-1}}
|
|
for _, dir := range directions {
|
|
x := i + dir[0]
|
|
y := j + dir[1]
|
|
if x < 0 || x >= grid.SizeX() || y < 0 || y >= grid.SizeY() {
|
|
continue
|
|
}
|
|
if !unicode.IsDigit(rune(grid.Get(x, y)[0])) && grid.Get(x, y) != "." {
|
|
fmt.Printf("partLoc x:%v y:%v %v\n", i, j, string(grid.Get(i, j)))
|
|
partLocs = append(partLocs, Coord{i, j})
|
|
break
|
|
}
|
|
}
|
|
}
|
|
}
|
|
fmt.Println(partLocs)
|
|
sum := 0
|
|
for _, partLoc := range partLocs {
|
|
if grid.Get(partLoc.x, partLoc.y) == "." {
|
|
continue
|
|
}
|
|
partNum := grid.Get(partLoc.x, partLoc.y)
|
|
for i:=1;unicode.IsDigit(rune(grid.Get(partLoc.x+i, partLoc.y)[0]));i++{
|
|
partNum += grid.Get(partLoc.x+i, partLoc.y)
|
|
grid.Set(partLoc.x+i, partLoc.y, ".")
|
|
}
|
|
for i:=-1;unicode.IsDigit(rune(grid.Get(partLoc.x+i, partLoc.y)[0]));i--{
|
|
partNum = grid.Get(partLoc.x+i, partLoc.y) + partNum
|
|
grid.Set(partLoc.x+i, partLoc.y, ".")
|
|
}
|
|
fmt.Println(partNum)
|
|
sum += utils.MustAtoi(partNum)
|
|
}
|
|
return sum
|
|
}
|
|
|
|
func Part2(input string) int {
|
|
grid := inputs.ToGrid2D(input, "\n", "", ".", func(c string) string { return c})
|
|
partLocs := []Coord{}
|
|
gearLocs := []Coord{}
|
|
for j := 0; j < grid.SizeY(); j++ {
|
|
for i := 0; i < grid.SizeX(); i++ {
|
|
if grid.Get(i, j) == "*" {
|
|
gearLocs = append(gearLocs, Coord{i, j})
|
|
}
|
|
if !unicode.IsDigit(rune(grid.Get(i, j)[0])) { continue}
|
|
directions := [][]int{{0, 1}, {0, -1}, {1, 0}, {-1, 0},{-1,1},{1,1},{-1,-1},{1,-1}}
|
|
for _, dir := range directions {
|
|
x := i + dir[0]
|
|
y := j + dir[1]
|
|
if x < 0 || x >= grid.SizeX() || y < 0 || y >= grid.SizeY() {
|
|
continue
|
|
}
|
|
if !unicode.IsDigit(rune(grid.Get(x, y)[0])) && grid.Get(x, y) != "." {
|
|
partLocs = append(partLocs, Coord{i, j})
|
|
break
|
|
}
|
|
}
|
|
}
|
|
}
|
|
fmt.Println(partLocs)
|
|
fmt.Println(gearLocs)
|
|
|
|
parts := []Part{}
|
|
for _, partLoc := range partLocs {
|
|
l := 0
|
|
if grid.Get(partLoc.x, partLoc.y) == "." {
|
|
continue
|
|
}
|
|
partNum := grid.Get(partLoc.x, partLoc.y)
|
|
for i:=1;unicode.IsDigit(rune(grid.Get(partLoc.x+i, partLoc.y)[0]));i++{
|
|
partNum += grid.Get(partLoc.x+i, partLoc.y)
|
|
grid.Set(partLoc.x+i, partLoc.y, ".")
|
|
}
|
|
l = partLoc.x
|
|
for i:=-1;unicode.IsDigit(rune(grid.Get(partLoc.x+i, partLoc.y)[0]));i--{
|
|
partNum = grid.Get(partLoc.x+i, partLoc.y) + partNum
|
|
grid.Set(partLoc.x+i, partLoc.y, ".")
|
|
l = partLoc.x+i
|
|
}
|
|
fmt.Println(partNum)
|
|
parts = append(parts, Part{number: partNum, location: Coord{x: l, y: partLoc.y}})
|
|
}
|
|
sum := 0
|
|
for _, gearLoc := range gearLocs {
|
|
var gearedParts [2]Part
|
|
|
|
directions := []Coord{{0,1},{0,-1},{1,0},{-1,0},{-1,1},{1,1},{-1,-1},{1,-1}}
|
|
for _, dir := range directions {
|
|
part, err := getPart(gearLoc, dir, parts)
|
|
if err != nil {continue}
|
|
if gearedParts[0] == (Part{}) {
|
|
gearedParts[0] = part
|
|
} else if gearedParts[0] == part {
|
|
fmt.Println("duplicate part found")
|
|
} else {
|
|
gearedParts[1] = part
|
|
}
|
|
}
|
|
fmt.Println(gearedParts)
|
|
if gearedParts[0] != (Part{}) && gearedParts[1] != (Part{}) {
|
|
sum += utils.MustAtoi(gearedParts[0].number) * utils.MustAtoi(gearedParts[1].number)
|
|
}
|
|
}
|
|
// fmt.Println(parts)
|
|
return sum
|
|
}
|
|
|
|
func getPart(gearloc Coord, offset Coord, parts []Part) (Part, error) {
|
|
coord := Coord{x: gearloc.x + offset.x, y: gearloc.y + offset.y}
|
|
for _, part := range parts {
|
|
if coord.x >= part.location.x &&
|
|
coord.x <= part.location.x + len(part.number) -1 &&
|
|
coord.y == part.location.y {
|
|
return part, nil
|
|
}
|
|
}
|
|
return Part{}, errors.New("Not Found")
|
|
} |