2023-12-01 12:12:28 +00:00
|
|
|
package day_03
|
2022-12-06 21:10:52 +00:00
|
|
|
|
2023-12-03 08:49:00 +00:00
|
|
|
import (
|
|
|
|
"fmt"
|
|
|
|
"strings"
|
|
|
|
|
|
|
|
"git.rpjosh.de/RPJosh/go-logger"
|
|
|
|
"rpjosh.de/adventOfCode/pkg/utils"
|
|
|
|
)
|
|
|
|
|
|
|
|
type Day struct {
|
|
|
|
engine []string
|
|
|
|
|
|
|
|
currentRow int
|
|
|
|
currentLine int
|
|
|
|
}
|
2022-12-06 21:10:52 +00:00
|
|
|
|
|
|
|
func (d *Day) Part1(in string) string {
|
2023-12-03 08:49:00 +00:00
|
|
|
|
|
|
|
// Initialize variables
|
|
|
|
sum := 0
|
|
|
|
d.currentLine = -1
|
|
|
|
d.engine = strings.Split(in, "\n")
|
|
|
|
|
|
|
|
for _, val := range d.engine {
|
|
|
|
if val == "" {
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
|
|
|
|
// Initialize variables
|
|
|
|
strVal := ""
|
|
|
|
isSymbolNear := false
|
|
|
|
d.currentRow = 0
|
|
|
|
d.currentLine++
|
|
|
|
|
|
|
|
// Loop through all characters and find ints
|
|
|
|
for _, str := range val {
|
|
|
|
if utils.IsInt(string(str)) {
|
|
|
|
strVal += string(str)
|
|
|
|
if !isSymbolNear {
|
|
|
|
// Check if a symbol is near
|
|
|
|
isSymbolNear = d.isSymbolNear()
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
// It's a '.' or a symbole
|
|
|
|
if strVal != "" && isSymbolNear {
|
|
|
|
logger.Debug("Found value %q", strVal)
|
|
|
|
sum += utils.ToInt(strVal)
|
|
|
|
}
|
|
|
|
|
|
|
|
// Reset variables
|
|
|
|
strVal = ""
|
|
|
|
isSymbolNear = false
|
|
|
|
}
|
|
|
|
|
|
|
|
d.currentRow += 1
|
|
|
|
}
|
|
|
|
|
|
|
|
// End of line
|
|
|
|
if strVal != "" && isSymbolNear {
|
|
|
|
logger.Debug("Found value %q", strVal)
|
|
|
|
sum += utils.ToInt(strVal)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return fmt.Sprintf("%d", sum)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (d *Day) isSymbolNear() bool {
|
|
|
|
|
|
|
|
// Left and right
|
|
|
|
if d.isSymbole(d.currentRow-1, d.currentLine, ' ') || d.isSymbole(d.currentRow+1, d.currentLine, ' ') {
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
|
|
|
|
// Top and bottom
|
|
|
|
if d.isSymbole(d.currentRow, d.currentLine-1, ' ') || d.isSymbole(d.currentRow, d.currentLine+1, ' ') {
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
|
|
|
|
// Diagonale
|
|
|
|
if d.isSymbole(d.currentRow-1, d.currentLine-1, ' ') || d.isSymbole(d.currentRow-1, d.currentLine+1, ' ') {
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
if d.isSymbole(d.currentRow+1, d.currentLine-1, ' ') || d.isSymbole(d.currentRow+1, d.currentLine+1, ' ') {
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
|
|
|
|
// isGearNear returns weather a * is near and the index of that gear
|
|
|
|
// (row,line)
|
|
|
|
func (d *Day) isGearNear() (bool, string) {
|
|
|
|
|
|
|
|
// Left and right
|
|
|
|
if d.isSymbole(d.currentRow-1, d.currentLine, '*') {
|
|
|
|
return true, fmt.Sprintf("%d,%d", d.currentRow-1, d.currentLine)
|
|
|
|
}
|
|
|
|
if d.isSymbole(d.currentRow+1, d.currentLine, '*') {
|
|
|
|
return true, fmt.Sprintf("%d,%d", d.currentRow+1, d.currentLine)
|
|
|
|
}
|
|
|
|
|
|
|
|
// Top and bottom
|
|
|
|
if d.isSymbole(d.currentRow, d.currentLine-1, '*') {
|
|
|
|
return true, fmt.Sprintf("%d,%d", d.currentRow, d.currentLine-1)
|
|
|
|
}
|
|
|
|
if d.isSymbole(d.currentRow, d.currentLine+1, '*') {
|
|
|
|
return true, fmt.Sprintf("%d,%d", d.currentRow, d.currentLine+1)
|
|
|
|
}
|
|
|
|
|
|
|
|
// Diagonale
|
|
|
|
if d.isSymbole(d.currentRow-1, d.currentLine-1, '*') {
|
|
|
|
return true, fmt.Sprintf("%d,%d", d.currentRow-1, d.currentLine-1)
|
|
|
|
}
|
|
|
|
if d.isSymbole(d.currentRow-1, d.currentLine+1, '*') {
|
|
|
|
return true, fmt.Sprintf("%d,%d", d.currentRow-1, d.currentLine+1)
|
|
|
|
}
|
|
|
|
if d.isSymbole(d.currentRow+1, d.currentLine-1, '*') {
|
|
|
|
return true, fmt.Sprintf("%d,%d", d.currentRow+1, d.currentLine-1)
|
|
|
|
}
|
|
|
|
if d.isSymbole(d.currentRow+1, d.currentLine+1, '*') {
|
|
|
|
return true, fmt.Sprintf("%d,%d", d.currentRow+1, d.currentLine+1)
|
|
|
|
}
|
|
|
|
|
|
|
|
return false, ""
|
|
|
|
}
|
|
|
|
|
|
|
|
// isSymbole checks if the characters at the given position is a rune.
|
|
|
|
// If an invalid line or row is provided, this function returns false
|
|
|
|
func (d *Day) isSymbole(row, line int, symbole rune) bool {
|
|
|
|
// Check out of bounds
|
|
|
|
if row < 0 || line < 0 || line >= len(d.engine) || row >= len(d.engine[line]) {
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
|
|
|
|
val := d.engine[line][row]
|
|
|
|
return val != '.' && !utils.IsInt(string(val)) && (symbole == ' ' || symbole == rune(val))
|
2022-12-06 21:10:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func (d *Day) Part2(in string) string {
|
2023-12-03 08:49:00 +00:00
|
|
|
// Initialize variables
|
|
|
|
d.currentLine = -1
|
|
|
|
d.engine = strings.Split(in, "\n")
|
|
|
|
gears := make(map[string][]int, 0)
|
|
|
|
|
|
|
|
for _, val := range d.engine {
|
|
|
|
if val == "" {
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
|
|
|
|
// Initialize variables
|
|
|
|
strVal := ""
|
|
|
|
isGearNear := false
|
|
|
|
isGearNearPos := ""
|
|
|
|
d.currentRow = 0
|
|
|
|
d.currentLine++
|
|
|
|
|
|
|
|
// Loop through all characters and find ints
|
|
|
|
for _, str := range val {
|
|
|
|
if utils.IsInt(string(str)) {
|
|
|
|
strVal += string(str)
|
|
|
|
// Check if a symbol is near
|
|
|
|
if isNear, pos := d.isGearNear(); isNear {
|
|
|
|
isGearNear = true
|
|
|
|
isGearNearPos = pos
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
// It's a '.' or a symbole
|
|
|
|
if strVal != "" && isGearNear {
|
|
|
|
logger.Debug("Found pos %q with value %q", isGearNearPos, strVal)
|
|
|
|
gears[isGearNearPos] = append(gears[isGearNearPos], utils.ToInt(strVal))
|
|
|
|
}
|
|
|
|
|
|
|
|
// Reset variables
|
|
|
|
strVal = ""
|
|
|
|
isGearNear = false
|
|
|
|
isGearNearPos = ""
|
|
|
|
}
|
|
|
|
|
|
|
|
d.currentRow += 1
|
|
|
|
}
|
|
|
|
|
|
|
|
// End of line
|
|
|
|
// Check if a symbol is near
|
|
|
|
if isGearNear {
|
|
|
|
logger.Debug("Found pos %q with value %q", isGearNearPos, strVal)
|
|
|
|
gears[isGearNearPos] = append(gears[isGearNearPos], utils.ToInt(strVal))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
sum := 0
|
|
|
|
for _, values := range gears {
|
|
|
|
if len(values) == 2 {
|
|
|
|
sum += values[0] * values[1]
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return fmt.Sprintf("%d", sum)
|
2022-12-06 21:10:52 +00:00
|
|
|
}
|