day3, example

This commit is contained in:
efim 2023-12-03 07:14:21 +00:00
parent afde84519f
commit c9f9766866
4 changed files with 149 additions and 3 deletions

1
.gitignore vendored
View File

@ -1 +1,2 @@
/.direnv/
/.go

135
day3/day-three.go Normal file
View File

@ -0,0 +1,135 @@
package day3
import (
"fmt"
"os"
"strings"
"unicode"
)
func Run() int {
filename := "day3/example"
bytes, err := os.ReadFile(filename)
if err != nil {
panic(fmt.Sprint(err, filename))
}
text := string(bytes)
matrix := ReadMatrix(text)
fmt.Println(matrix.String())
numbers := ReadNumbers(&matrix)
fmt.Println(numbers)
partNumbersSum := 0
for _, num := range numbers {
if len(num.Specials) > 0 {
partNumbersSum += num.Num
}
}
return partNumbersSum
}
type Matrix [][]rune
func ReadMatrix(text string) Matrix {
text = strings.TrimSpace(text)
lines := strings.Split(text, "\n")
matrix := make([][]rune, len(lines))
for i, lineStr := range strings.Split(text, "\n") {
for _, r := range lineStr {
matrix[i] = append(matrix[i], r)
}
}
return matrix
}
func (m *Matrix)String() string {
res := make([]string, len(*m))
for _, row := range *m {
res = append(res, string(row) + "\n")
}
return strings.Join(res, "")
}
// and now from matrix, i want to scan top-down, left-right
// when encountering digit - start new number, read it in
// and when finished reading : scan around for the special symbols
type SpecialSymbol struct {
Symb rune
X, Y int
}
func (s SpecialSymbol) String() string {
return fmt.Sprintf("('%s' at x:%d,y:%d)", string(s.Symb), s.X, s.Y)
}
func (s SpecialSymbol) Equal() bool {
return false
}
type MatrixNumber struct {
Num int
Specials map[SpecialSymbol]any
}
func ReadNumbers(m *Matrix) []MatrixNumber {
res := make([]MatrixNumber, 0)
var curNum *MatrixNumber
for x, row := range *m {
for y, symb := range row {
if unicode.IsDigit(symb) {
digit := int(symb - '0')
// seing digit
if curNum == nil {
curNum = &MatrixNumber{
Num: digit,
Specials: make(map[SpecialSymbol]any),
}
} else {
curNum.Num = curNum.Num*10 + digit
}
// on each digit - scan around for special symbols
for i := x-1; i <= x+1; i++ {
for j := y-1; j <= y+1; j++ {
if isValidCoord(i, j, m) {
checkingForSpecial := (*m)[i][j]
if checkingForSpecial != '.' && !unicode.IsDigit(checkingForSpecial) {
special := SpecialSymbol{
Symb: checkingForSpecial,
X: i,
Y: j,
}
curNum.Specials[special] = struct{}{}
}
}
}
}
// now let's check for special symbols around and save them
}
if symb == '.' {
if curNum != nil {
res = append(res, *curNum)
curNum = nil
}
}
}
}
return res
}
// x is row, y is column. from top-left to bottom-right
func isValidCoord(x, y int, m *Matrix) bool {
if x < 0 || y < 0 || x >= len(*m) || y >= len((*m)[x]) {
return false
}
return true
}

10
day3/example Normal file
View File

@ -0,0 +1,10 @@
467..114..
...*......
..35..633.
......#...
617*......
.....+.58.
..592.....
......755.
...$.*....
.664.598..

View File

@ -3,11 +3,11 @@ package main
import (
"log"
"sunshine.industries/aoc2023/day2"
"sunshine.industries/aoc2023/day3"
)
func main() {
log.Print("> starting run:")
result := day2.Run()
log.Printf("day2 result: %d", result)
result := day3.Run()
log.Printf("day3 result: %d", result)
}