166 lines
3.1 KiB
Go
166 lines
3.1 KiB
Go
package main
|
|
|
|
import (
|
|
"bufio"
|
|
"fmt"
|
|
"os"
|
|
"strings"
|
|
"time"
|
|
)
|
|
|
|
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 coord struct {
|
|
x int
|
|
y int
|
|
}
|
|
|
|
// grid SHOULD be like this:
|
|
// x ->
|
|
// y
|
|
// |
|
|
// V
|
|
|
|
type image struct {
|
|
background rune // what all uninitialized cells are set to; defaults to '.'
|
|
grid map[coord]rune
|
|
topleft coord
|
|
size int
|
|
}
|
|
|
|
func GetNeighbors(c coord) []coord {
|
|
return []coord{
|
|
{x: c.x - 1, y: c.y - 1},
|
|
{x: c.x, y: c.y - 1},
|
|
{x: c.x + 1, y: c.y - 1},
|
|
|
|
{x: c.x - 1, y: c.y},
|
|
{x: c.x, y: c.y},
|
|
{x: c.x + 1, y: c.y},
|
|
|
|
{x: c.x - 1, y: c.y + 1},
|
|
{x: c.x, y: c.y + 1},
|
|
{x: c.x + 1, y: c.y + 1},
|
|
}
|
|
}
|
|
|
|
func (img *image) GetNewRune(coord coord, enhancementMap string) rune {
|
|
index := 0
|
|
coords := GetNeighbors(coord)
|
|
for i := 0; i < len(coords); i++ {
|
|
value := img.grid[coords[i]]
|
|
if value == 0 {
|
|
value = img.background
|
|
}
|
|
if value == '#' {
|
|
index += (1 << (8 - i))
|
|
}
|
|
}
|
|
return rune(enhancementMap[index])
|
|
}
|
|
|
|
func (img *image) CountBrightPixels() int {
|
|
count := 0
|
|
for _, v := range img.grid {
|
|
if v == '#' {
|
|
count++
|
|
}
|
|
}
|
|
return count
|
|
}
|
|
|
|
func (img *image) Print() {
|
|
fmt.Println(strings.Repeat(string(img.background), img.size+2))
|
|
for y := img.topleft.y; y < img.size+img.topleft.y; y++ {
|
|
fmt.Print(string(img.background))
|
|
for x := img.topleft.x; x < img.size+img.topleft.x; x++ {
|
|
fmt.Printf("%s", string(img.grid[coord{x, y}]))
|
|
}
|
|
fmt.Printf("%s\n", string(img.background))
|
|
}
|
|
fmt.Println(strings.Repeat(string(img.background), img.size+2))
|
|
}
|
|
|
|
func Enhance(img *image, m string) *image {
|
|
next := &image{
|
|
topleft: coord{
|
|
x: img.topleft.x - 1,
|
|
y: img.topleft.y - 1,
|
|
},
|
|
size: img.size + 2,
|
|
grid: map[coord]rune{},
|
|
}
|
|
if img.background == '.' { // permute new "background" value
|
|
next.background = rune(m[0])
|
|
} else if img.background == '#' {
|
|
next.background = rune(m[511])
|
|
}
|
|
for y := img.topleft.y - 1; y < img.size+1; y++ {
|
|
for x := img.topleft.x - 1; x < img.size+1; x++ {
|
|
next.grid[coord{x, y}] = img.GetNewRune(coord{x, y}, m)
|
|
}
|
|
}
|
|
return next
|
|
}
|
|
|
|
func partOne() {
|
|
scanner := makeScanner(false)
|
|
|
|
scanner.Scan()
|
|
enhancementString := scanner.Text()
|
|
scanner.Scan() // eat empty line
|
|
|
|
img := &image{
|
|
background: '.',
|
|
grid: map[coord]rune{},
|
|
topleft: coord{0, 0},
|
|
}
|
|
|
|
y := 0
|
|
for scanner.Scan() {
|
|
line := scanner.Text()
|
|
img.size = len(line)
|
|
for x, c := range line {
|
|
img.grid[coord{x, y}] = c
|
|
}
|
|
y++
|
|
}
|
|
|
|
img.Print()
|
|
fmt.Println(img.CountBrightPixels())
|
|
fmt.Println("")
|
|
|
|
for i := 0; i < 2; i++ {
|
|
img = Enhance(img, enhancementString)
|
|
img.Print()
|
|
fmt.Println(img.CountBrightPixels())
|
|
fmt.Println("")
|
|
}
|
|
}
|
|
|
|
func partTwo() {
|
|
scanner := makeScanner(false)
|
|
|
|
for scanner.Scan() {
|
|
// line := scanner.Text()
|
|
}
|
|
}
|