diff --git a/day03.go b/day03.go new file mode 100644 index 0000000..7613d23 --- /dev/null +++ b/day03.go @@ -0,0 +1,94 @@ +package main + +import ( + "bufio" + "fmt" + "io" + "strconv" + "strings" +) + +func isdigit(b byte) bool { + return b >= 48 && b <= 57 +} + +func engineparts(buf *bufio.Reader) []int { + parts := make([]int, 0, 150) + +outer: + for { + head, err := buf.ReadByte() + if err != nil { + return parts + } + + if isdigit(head) { + // start recording digits + b := make([]byte, 0, 10) + b = append(b, head) + + // continue reading until number is exhausted + for { + digit, err := buf.ReadByte() + if !isdigit(digit) || err == io.EOF { + value, _ := strconv.Atoi(string(b)) + for range b { + parts = append(parts, value) + } + + buf.UnreadByte() + continue outer + } + + b = append(b, digit) + } + + } else if head != '.' { + // head is a symbol + parts = append(parts, -1) + + } else { + // head is a '.' + parts = append(parts, 0) + } + } +} + +type day03 struct{} + +func (d day03) solve1(r io.Reader) string { + sum := 0 + parts := make([][]int, 0, 100) + scanner := bufio.NewScanner(r) + + for scanner.Scan() { + line := scanner.Text() + buf := bufio.NewReader(strings.NewReader(line)) + lineparts := engineparts(buf) + parts = append(parts, lineparts) + } + + for i := 1; i < len(parts)-1; i++ { + for j := 1; j < len(parts[i])-1; j++ { + cursor := parts[i][j] + if cursor == -1 { + row: + for i2 := -1; i2 <= 1; i2++ { + for j2 := -1; j2 <= 1; j2++ { + val := parts[i+i2][j+j2] + if val > 0 { + sum += val + continue row + } + } + } + } + } + } + + return fmt.Sprintf("%d", sum) +} + +func (d day03) solve2(r io.Reader) string { + return "" +} diff --git a/main.go b/main.go index 0c83c3a..a289836 100644 --- a/main.go +++ b/main.go @@ -22,6 +22,7 @@ var ( puzzles = []puzzle{ &day01{}, &day02{}, + &day03{}, } ) diff --git a/main_test.go b/main_test.go index e45abb1..25588cf 100644 --- a/main_test.go +++ b/main_test.go @@ -60,3 +60,24 @@ Game 5: 6 red, 1 blue, 3 green; 2 blue, 1 red, 2 green` } } + +func TestDay03(t *testing.T) { + input1 := `467..114.. +...*...... +..35..633. +......#... +617*...... +.....+.58. +..592..... +......755. +...$.*.... +.664.598..` + + puzzle := day03{} + + ans1 := "4361" + res1 := puzzle.solve1(strings.NewReader(input1)) + if res1 != ans1 { + t.Errorf("day 3 solution 1 = %s; wanted %s", res1, ans1) + } +}