ugly and slow, but it works
This commit is contained in:
parent
2cf787a203
commit
0314b26843
162
03/main.go
162
03/main.go
@ -33,18 +33,176 @@ func makeScanner(test bool) *bufio.Scanner {
|
||||
return bufio.NewScanner(reader)
|
||||
}
|
||||
|
||||
type schematic map[string]entry
|
||||
|
||||
type entry struct {
|
||||
num string
|
||||
symb string
|
||||
}
|
||||
|
||||
func key(row, col int) string {
|
||||
return fmt.Sprintf("%d.%d", row, col)
|
||||
}
|
||||
|
||||
func isSymbol(s schematic, row, col int) bool {
|
||||
if c, ok := s[key(row, col)]; ok {
|
||||
return c.symb != ""
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func partOne() {
|
||||
scanner := makeScanner(false)
|
||||
|
||||
row := 0
|
||||
schematic := schematic{}
|
||||
// read the whole thing in
|
||||
for scanner.Scan() {
|
||||
// line := scanner.Text()
|
||||
line := scanner.Text()
|
||||
i := struct {
|
||||
tmp []rune
|
||||
col int
|
||||
}{}
|
||||
for col, c := range line {
|
||||
switch c {
|
||||
case '.':
|
||||
if len(i.tmp) != 0 {
|
||||
schematic[key(row, i.col)] = entry{num: string(i.tmp)}
|
||||
i.tmp = []rune{}
|
||||
}
|
||||
continue
|
||||
case '1', '2', '3', '4', '5', '6', '7', '8', '9', '0':
|
||||
if len(i.tmp) == 0 {
|
||||
i.tmp = append(i.tmp, c)
|
||||
i.col = col
|
||||
} else {
|
||||
i.tmp = append(i.tmp, c)
|
||||
}
|
||||
continue
|
||||
default:
|
||||
if len(i.tmp) != 0 {
|
||||
schematic[key(row, i.col)] = entry{num: string(i.tmp)}
|
||||
i.tmp = []rune{}
|
||||
}
|
||||
schematic[key(row, col)] = entry{symb: string(c)}
|
||||
continue
|
||||
}
|
||||
}
|
||||
// check if we have a number still to save but ran out of line
|
||||
if len(i.tmp) != 0 {
|
||||
schematic[key(row, i.col)] = entry{num: string(i.tmp)}
|
||||
i.tmp = []rune{}
|
||||
}
|
||||
row++
|
||||
}
|
||||
sum := 0
|
||||
// now, map back over the schematics and find the parts
|
||||
for row := 0; row <= 139; row++ {
|
||||
for col := 0; col <= 139; col++ {
|
||||
if num, ok := schematic[key(row, col)]; ok && num.num != "" {
|
||||
part := mustAtoi(num.num)
|
||||
if isSymbol(schematic, row, col-1) {
|
||||
// look behind
|
||||
sum += part
|
||||
} else if isSymbol(schematic, row, col+len(num.num)) {
|
||||
// look ahead
|
||||
sum += part
|
||||
} else {
|
||||
for i := -1; i < len(num.num)+1; i++ {
|
||||
// check row above and below
|
||||
if isSymbol(schematic, row-1, col+i) {
|
||||
sum += part
|
||||
break
|
||||
} else if isSymbol(schematic, row+1, col+i) {
|
||||
sum += part
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
fmt.Println(sum)
|
||||
}
|
||||
|
||||
func partTwo() {
|
||||
scanner := makeScanner(false)
|
||||
|
||||
row := 0
|
||||
schematic := schematic{}
|
||||
// read the whole thing in
|
||||
for scanner.Scan() {
|
||||
// line := scanner.Text()
|
||||
line := scanner.Text()
|
||||
i := struct {
|
||||
tmp []rune
|
||||
col int
|
||||
}{}
|
||||
for col, c := range line {
|
||||
switch c {
|
||||
case '1', '2', '3', '4', '5', '6', '7', '8', '9', '0':
|
||||
if len(i.tmp) == 0 {
|
||||
i.tmp = append(i.tmp, c)
|
||||
i.col = col
|
||||
} else {
|
||||
i.tmp = append(i.tmp, c)
|
||||
}
|
||||
continue
|
||||
default:
|
||||
if len(i.tmp) != 0 {
|
||||
schematic[key(row, i.col)] = entry{num: string(i.tmp)}
|
||||
i.tmp = []rune{}
|
||||
}
|
||||
if c == '*' { // no longer care about other symbols
|
||||
schematic[key(row, col)] = entry{symb: string(c)}
|
||||
}
|
||||
continue
|
||||
}
|
||||
}
|
||||
// check if we have a number still to save but ran out of line
|
||||
if len(i.tmp) != 0 {
|
||||
schematic[key(row, i.col)] = entry{num: string(i.tmp)}
|
||||
i.tmp = []rune{}
|
||||
}
|
||||
row++
|
||||
}
|
||||
gears := map[string][]int{}
|
||||
// map back over the schematics and find the gears
|
||||
for row := 0; row <= 139; row++ {
|
||||
for col := 0; col <= 139; col++ {
|
||||
if num, ok := schematic[key(row, col)]; ok && num.num != "" {
|
||||
part := mustAtoi(num.num)
|
||||
if isSymbol(schematic, row, col-1) {
|
||||
if schematic[key(row, col-1)].symb == "*" {
|
||||
gears[key(row, col-1)] = append(gears[key(row, col-1)], part)
|
||||
}
|
||||
} else if isSymbol(schematic, row, col+len(num.num)) {
|
||||
if schematic[key(row, col+len(num.num))].symb == "*" {
|
||||
gears[key(row, col+len(num.num))] = append(gears[key(row, col+len(num.num))], part)
|
||||
}
|
||||
} else {
|
||||
for i := -1; i < len(num.num)+1; i++ {
|
||||
// check row above and below
|
||||
if isSymbol(schematic, row-1, col+i) {
|
||||
if schematic[key(row-1, col+i)].symb == "*" {
|
||||
gears[key(row-1, col+i)] = append(gears[key(row-1, col+i)], part)
|
||||
}
|
||||
break
|
||||
} else if isSymbol(schematic, row+1, col+i) {
|
||||
if schematic[key(row+1, col+i)].symb == "*" {
|
||||
gears[key(row+1, col+i)] = append(gears[key(row+1, col+i)], part)
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
sum := 0
|
||||
for _, g := range gears {
|
||||
if len(g) == 2 {
|
||||
sum += g[0] * g[1]
|
||||
}
|
||||
}
|
||||
fmt.Println(sum)
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user