|
@ -12,11 +12,17 @@ func isdigit(b byte) bool { |
|
|
return b >= 48 && b <= 57 |
|
|
return b >= 48 && b <= 57 |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
func engineparts(buf *bufio.Reader) []int { |
|
|
type enginepart struct { |
|
|
parts := make([]int, 0, 150) |
|
|
value int |
|
|
|
|
|
pos int |
|
|
|
|
|
raw string |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
func engineparts(buf *bufio.Reader) []enginepart { |
|
|
|
|
|
parts := make([]enginepart, 0, 150) |
|
|
|
|
|
|
|
|
outer: |
|
|
outer: |
|
|
for { |
|
|
for pos := 0; ; pos++ { |
|
|
head, err := buf.ReadByte() |
|
|
head, err := buf.ReadByte() |
|
|
if err != nil { |
|
|
if err != nil { |
|
|
return parts |
|
|
return parts |
|
@ -30,10 +36,15 @@ outer: |
|
|
// continue reading until number is exhausted
|
|
|
// continue reading until number is exhausted
|
|
|
for { |
|
|
for { |
|
|
digit, err := buf.ReadByte() |
|
|
digit, err := buf.ReadByte() |
|
|
if !isdigit(digit) || err == io.EOF { |
|
|
if !isdigit(digit) { |
|
|
value, _ := strconv.Atoi(string(b)) |
|
|
value, _ := strconv.Atoi(string(b)) |
|
|
for range b { |
|
|
for range b { |
|
|
parts = append(parts, value) |
|
|
parts = append(parts, enginepart{value: value, pos: pos, raw: string(b)}) |
|
|
|
|
|
} |
|
|
|
|
|
pos += len(b) - 1 |
|
|
|
|
|
|
|
|
|
|
|
if err == io.EOF { |
|
|
|
|
|
return parts |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
buf.UnreadByte() |
|
|
buf.UnreadByte() |
|
@ -45,11 +56,11 @@ outer: |
|
|
|
|
|
|
|
|
} else if head != '.' { |
|
|
} else if head != '.' { |
|
|
// head is a symbol
|
|
|
// head is a symbol
|
|
|
parts = append(parts, -1) |
|
|
parts = append(parts, enginepart{value: -1, pos: pos, raw: string(head)}) |
|
|
|
|
|
|
|
|
} else { |
|
|
} else { |
|
|
// head is a '.'
|
|
|
// head is a '.'
|
|
|
parts = append(parts, 0) |
|
|
parts = append(parts, enginepart{value: 0, pos: pos, raw: string(head)}) |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
@ -58,7 +69,7 @@ type day03 struct{} |
|
|
|
|
|
|
|
|
func (d day03) solve1(r io.Reader) string { |
|
|
func (d day03) solve1(r io.Reader) string { |
|
|
sum := 0 |
|
|
sum := 0 |
|
|
parts := make([][]int, 0, 100) |
|
|
parts := make([][]enginepart, 0, 100) |
|
|
scanner := bufio.NewScanner(r) |
|
|
scanner := bufio.NewScanner(r) |
|
|
|
|
|
|
|
|
for scanner.Scan() { |
|
|
for scanner.Scan() { |
|
@ -68,18 +79,25 @@ func (d day03) solve1(r io.Reader) string { |
|
|
parts = append(parts, lineparts) |
|
|
parts = append(parts, lineparts) |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
for i := 1; i < len(parts)-1; i++ { |
|
|
for row := range parts { |
|
|
for j := 1; j < len(parts[i])-1; j++ { |
|
|
for item := range parts[row] { |
|
|
cursor := parts[i][j] |
|
|
if sym := parts[row][item]; sym.value == -1 { |
|
|
if cursor == -1 { |
|
|
|
|
|
row: |
|
|
for i := -1; i < 2; i++ { |
|
|
for i2 := -1; i2 <= 1; i2++ { |
|
|
for j := -1; j < 2; { |
|
|
for j2 := -1; j2 <= 1; j2++ { |
|
|
x := row + i |
|
|
val := parts[i+i2][j+j2] |
|
|
y := item + j |
|
|
if val > 0 { |
|
|
|
|
|
sum += val |
|
|
if x >= 0 && y >= 0 && x < len(parts) && y < len(parts[row]) { |
|
|
continue row |
|
|
part := parts[x][y] |
|
|
|
|
|
if part.value > 0 { |
|
|
|
|
|
sum += part.value |
|
|
|
|
|
j += (part.pos + len(part.raw) - y) |
|
|
|
|
|
} else { |
|
|
|
|
|
j++ |
|
|
|
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|