2023-12-03 18:42:12 +01:00

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
}