github.com/agrigoryan/aoc_2023_go@v0.0.0-20231216221323-4ace361ec685/day3/d3p1.go (about)

     1  package day3
     2  
     3  import (
     4  	"fmt"
     5  	"strconv"
     6  	"strings"
     7  	"unicode"
     8  )
     9  
    10  func d3p1(input string) int {
    11  	lines := strings.Split(input, "\n")
    12  
    13  	sum := 0
    14  	const empty = '.'
    15  
    16  	hasSymbol := func(parts []string) bool {
    17  		for _, p := range parts {
    18  			for _, r := range p {
    19  				if !unicode.IsDigit(r) && r != empty {
    20  					return true
    21  				}
    22  			}
    23  		}
    24  		return false
    25  	}
    26  
    27  	digitFound := func(numLine int, line string, start int, end int) int {
    28  		pStart := max(start-1, 0)
    29  		pEnd := min(end+1, len(line))
    30  		partsToCheck := []string{line[pStart:pEnd]}
    31  
    32  		if numLine > 0 {
    33  			partsToCheck = append(partsToCheck, lines[numLine-1][pStart:pEnd])
    34  		}
    35  		if numLine < len(lines)-1 {
    36  			partsToCheck = append(partsToCheck, lines[numLine+1][pStart:pEnd])
    37  		}
    38  
    39  		if hasSymbol(partsToCheck) {
    40  			if num, err := strconv.Atoi(line[start:end]); err == nil {
    41  				return num
    42  			}
    43  		}
    44  		return 0
    45  	}
    46  	for i, line := range lines {
    47  		digitStart := -1
    48  		for j, r := range line {
    49  			if unicode.IsDigit(r) {
    50  				if digitStart == -1 {
    51  					digitStart = j
    52  				}
    53  			} else if digitStart != -1 {
    54  				sum += digitFound(i, line, digitStart, j)
    55  				digitStart = -1
    56  			}
    57  		}
    58  		if digitStart != -1 {
    59  			sum += digitFound(i, line, digitStart, len(line))
    60  		}
    61  	}
    62  	fmt.Println(sum)
    63  	return sum
    64  }