148 lines
2.4 KiB
Go
148 lines
2.4 KiB
Go
|
package main
|
||
|
|
||
|
import (
|
||
|
"bufio"
|
||
|
"fmt"
|
||
|
"os"
|
||
|
"strconv"
|
||
|
"time"
|
||
|
)
|
||
|
|
||
|
func mustAtoi(line byte) int {
|
||
|
i, _ := strconv.Atoi(string(line))
|
||
|
return i
|
||
|
}
|
||
|
|
||
|
func main() {
|
||
|
start := time.Now()
|
||
|
partOne()
|
||
|
duration := time.Since(start)
|
||
|
partTwo()
|
||
|
duration2 := time.Since(start)
|
||
|
fmt.Printf("p1: %s, p2: %s\n", duration, duration2-duration)
|
||
|
}
|
||
|
|
||
|
func makeScanner(test bool) *bufio.Scanner {
|
||
|
var f *os.File
|
||
|
if test {
|
||
|
f, _ = os.Open("inputs/testinput")
|
||
|
} else {
|
||
|
f, _ = os.Open("inputs/input")
|
||
|
}
|
||
|
reader := bufio.NewReader(f)
|
||
|
return bufio.NewScanner(reader)
|
||
|
}
|
||
|
|
||
|
type octopus struct {
|
||
|
energy int
|
||
|
flashed bool
|
||
|
}
|
||
|
|
||
|
type octopi []octopus // index is col + (row*10)
|
||
|
|
||
|
func (o *octopi) incrementEnergyLevels() {
|
||
|
for i := range *o {
|
||
|
(*o)[i].energy++
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func (o *octopi) flash() bool {
|
||
|
flash := false
|
||
|
toIncrement := make([]int, 100)
|
||
|
for i := range *o {
|
||
|
if (*o)[i].energy > 9 && !(*o)[i].flashed {
|
||
|
(*o)[i].flashed = true
|
||
|
flash = true
|
||
|
if i > 9 {
|
||
|
toIncrement[i-10]++ // above
|
||
|
}
|
||
|
if i < 90 {
|
||
|
toIncrement[i+10]++ // below
|
||
|
}
|
||
|
if i%10 != 9 {
|
||
|
toIncrement[i+1]++ // right
|
||
|
}
|
||
|
if i%10 != 0 {
|
||
|
toIncrement[i-1]++ // left
|
||
|
}
|
||
|
if i%10 != 0 && i > 9 {
|
||
|
toIncrement[i-11]++ // above-left
|
||
|
}
|
||
|
if i%10 != 9 && i > 9 {
|
||
|
toIncrement[i-9]++ // above-right
|
||
|
}
|
||
|
if i%10 != 0 && i < 90 {
|
||
|
toIncrement[i+9]++ // below-left
|
||
|
}
|
||
|
if i%10 != 9 && i < 90 {
|
||
|
toIncrement[i+11]++ // below-right
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
for i := range toIncrement {
|
||
|
(*o)[i].energy += toIncrement[i]
|
||
|
}
|
||
|
return flash
|
||
|
}
|
||
|
|
||
|
func (o *octopi) reset() int {
|
||
|
count := 0
|
||
|
for i := range *o {
|
||
|
if (*o)[i].energy > 9 {
|
||
|
count++
|
||
|
(*o)[i].energy = 0
|
||
|
(*o)[i].flashed = false
|
||
|
}
|
||
|
}
|
||
|
return count
|
||
|
}
|
||
|
|
||
|
func partOne() {
|
||
|
scanner := makeScanner(false)
|
||
|
|
||
|
cave := octopi{}
|
||
|
for scanner.Scan() {
|
||
|
line := scanner.Text()
|
||
|
for i := range line {
|
||
|
cave = append(cave, octopus{energy: mustAtoi(line[i])})
|
||
|
}
|
||
|
}
|
||
|
total := 0
|
||
|
for step := 0; step < 100; step++ {
|
||
|
cave.incrementEnergyLevels()
|
||
|
for {
|
||
|
if !cave.flash() {
|
||
|
break
|
||
|
}
|
||
|
}
|
||
|
total += cave.reset()
|
||
|
}
|
||
|
fmt.Println(total)
|
||
|
}
|
||
|
|
||
|
func partTwo() {
|
||
|
scanner := makeScanner(false)
|
||
|
|
||
|
cave := octopi{}
|
||
|
for scanner.Scan() {
|
||
|
line := scanner.Text()
|
||
|
for i := range line {
|
||
|
cave = append(cave, octopus{energy: mustAtoi(line[i])})
|
||
|
}
|
||
|
}
|
||
|
step := 0
|
||
|
for {
|
||
|
step++
|
||
|
cave.incrementEnergyLevels()
|
||
|
for {
|
||
|
if !cave.flash() {
|
||
|
break
|
||
|
}
|
||
|
}
|
||
|
if cave.reset() == 100 {
|
||
|
break
|
||
|
}
|
||
|
}
|
||
|
fmt.Println(step)
|
||
|
}
|