136 lines
3.5 KiB
Go
136 lines
3.5 KiB
Go
package day03
|
|
|
|
import (
|
|
"regexp"
|
|
"strconv"
|
|
|
|
utils "git.anthonygueguen.fr/g3po/aoc2023/internal"
|
|
)
|
|
|
|
func GetParts(content []string) []int {
|
|
var parts []int
|
|
re_num := regexp.MustCompile(`\d+`)
|
|
re_symbol := regexp.MustCompile(`[^\w\s.]`)
|
|
|
|
for i, line := range content {
|
|
matches := re_num.FindAllStringIndex(line, -1)
|
|
for _, idx := range matches {
|
|
adjContent := getAdjUpLine(content, i, idx[0], idx[1])
|
|
adjContent = adjContent + getAdjDownLine(content, i, idx[0], idx[1])
|
|
adjContent = adjContent + getAdjInLine(content, i, idx[0], idx[1])
|
|
if re_symbol.MatchString(adjContent) {
|
|
num_str := string(line[idx[0]:idx[1]])
|
|
num := utils.Must(strconv.Atoi(num_str))
|
|
parts = append(parts, num)
|
|
}
|
|
}
|
|
}
|
|
return parts
|
|
}
|
|
|
|
func getAdjUpLine(content []string, line, start, end int) string {
|
|
adjContent := ""
|
|
if line > 0 {
|
|
adjContent = adjContent + string(content[line-1][start:end])
|
|
if start > 0 {
|
|
adjContent = adjContent + string(content[line-1][start-1])
|
|
}
|
|
if end < len(content[line])-1 {
|
|
adjContent = adjContent + string(content[line-1][end])
|
|
}
|
|
}
|
|
return adjContent
|
|
}
|
|
|
|
func getAdjDownLine(content []string, line, start, end int) string {
|
|
adjContent := ""
|
|
if line < len(content)-1 {
|
|
adjContent = adjContent + string(content[line+1][start:end])
|
|
if start > 0 {
|
|
adjContent = adjContent + string(content[line+1][start-1])
|
|
}
|
|
if end < len(content[line])-1 {
|
|
adjContent = adjContent + string(content[line+1][end])
|
|
}
|
|
}
|
|
return adjContent
|
|
}
|
|
|
|
func getAdjInLine(content []string, line, start, end int) string {
|
|
adjContent := ""
|
|
if start > 0 {
|
|
adjContent = adjContent + string(content[line][start-1])
|
|
}
|
|
if end < len(content[line])-1 {
|
|
adjContent = adjContent + string(content[line][end])
|
|
}
|
|
return adjContent
|
|
}
|
|
|
|
func GetRatio(content []string) int {
|
|
ratio := 0
|
|
re_gear := regexp.MustCompile(`\*`)
|
|
for i, line := range content {
|
|
matches := re_gear.FindAllStringIndex(line, -1)
|
|
for _, match := range matches {
|
|
start, end := match[0], match[1]
|
|
var num []int
|
|
num = append(num, getUpRatio(content, i, start, end)...)
|
|
num = append(num, getDownRatio(content, i, start, end)...)
|
|
num = append(num, getInlineRatio(content, i, start, end)...)
|
|
if len(num) == 2 {
|
|
ratio += (num[0] * num[1])
|
|
}
|
|
}
|
|
}
|
|
return ratio
|
|
}
|
|
|
|
func getUpRatio(content []string, line, start, end int) []int {
|
|
var num []int
|
|
if line == 0 {
|
|
return num
|
|
}
|
|
re_num := regexp.MustCompile(`\d+`)
|
|
matches := re_num.FindAllStringIndex(content[line-1], -1)
|
|
for _, match := range matches {
|
|
mStart, mEnd := match[0], match[1]
|
|
if mEnd >= start && end >= mStart {
|
|
str := string(content[line-1][mStart:mEnd])
|
|
num = append(num, utils.Must(strconv.Atoi(str)))
|
|
}
|
|
}
|
|
return num
|
|
}
|
|
|
|
func getDownRatio(content []string, line, start, end int) []int {
|
|
var num []int
|
|
if line >= len(content)-1 {
|
|
return num
|
|
}
|
|
re_num := regexp.MustCompile(`\d+`)
|
|
matches := re_num.FindAllStringIndex(content[line+1], -1)
|
|
for _, match := range matches {
|
|
mStart, mEnd := match[0], match[1]
|
|
if mEnd >= start && end >= mStart {
|
|
str := string(content[line+1][mStart:mEnd])
|
|
num = append(num, utils.Must(strconv.Atoi(str)))
|
|
}
|
|
}
|
|
return num
|
|
}
|
|
|
|
func getInlineRatio(content []string, line, start, end int) []int {
|
|
var num []int
|
|
re_num := regexp.MustCompile(`\d+`)
|
|
matches := re_num.FindAllStringIndex(content[line], -1)
|
|
for _, match := range matches {
|
|
mStart, mEnd := match[0], match[1]
|
|
if mEnd >= start && end >= mStart {
|
|
str := string(content[line][mStart:mEnd])
|
|
num = append(num, utils.Must(strconv.Atoi(str)))
|
|
}
|
|
}
|
|
return num
|
|
}
|