diff --git a/.gitignore b/.gitignore index 29963da..ad48c9b 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ /.direnv/ +/.go diff --git a/day3/day-three.go b/day3/day-three.go new file mode 100644 index 0000000..0e1ddcc --- /dev/null +++ b/day3/day-three.go @@ -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 +} diff --git a/day3/example b/day3/example new file mode 100644 index 0000000..b20187f --- /dev/null +++ b/day3/example @@ -0,0 +1,10 @@ +467..114.. +...*...... +..35..633. +......#... +617*...... +.....+.58. +..592..... +......755. +...$.*.... +.664.598.. diff --git a/main.go b/main.go index 4ed891d..7a45a15 100644 --- a/main.go +++ b/main.go @@ -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) }