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 }