catching up, here's day 24

This commit is contained in:
David 2020-12-26 14:50:36 -05:00
parent df30e9abc0
commit 16784775c9
1 changed files with 186 additions and 0 deletions

186
24/main.go Normal file
View File

@ -0,0 +1,186 @@
package main
import (
"bufio"
"fmt"
"os"
"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)
}
// Our grid is a hex, so let's represent that as follows:
// x runs east-west, y runs north-south. Yes, these coordinates here are backward.
// 2,-2 2,0 2,2 2,4
// 1,-2 1,-1 1,1 1,2
// 0,-2 0,0 0,2 0,4
// -1,-2 -1,-1 -1,1 -1,2
// -2,-2 -2,0 -2,2 -2,4
// 0,0 -> e -> 0, 2
// -> w -> 0,-2
// -> se -> -1, 1
// -> sw -> -1,-1
// -> ne -> 1, 1
// -> nw -> 1,-1
// 0 == white, 1 == black
type tiles map[coord]int
type coord struct {
x int
y int
}
func walkGrid(directions []string) (int, int) {
var y, x int
for _, d := range directions {
switch d {
case "e":
x = x + 2
case "se":
y = y - 1
x = x + 1
case "sw":
y = y - 1
x = x - 1
case "w":
x = x - 2
case "ne":
y = y + 1
x = x + 1
case "nw":
y = y + 1
x = x - 1
}
}
return y, x
}
func parseLine(s string) []string {
directions := []string{}
for i := 0; i < len(s); {
switch s[i] {
case 'e':
directions = append(directions, "e")
i = i + 1
case 's':
if s[i+1] == 'e' {
directions = append(directions, "se")
i = i + 2
} else if s[i+1] == 'w' {
directions = append(directions, "sw")
i = i + 2
}
case 'w':
directions = append(directions, "w")
i = i + 1
case 'n':
if s[i+1] == 'e' {
directions = append(directions, "ne")
i = i + 2
} else if s[i+1] == 'w' {
directions = append(directions, "nw")
i = i + 2
}
}
}
return directions
}
func generation(t tiles) tiles {
newTiles := tiles{}
seenWhiteTiles := tiles{}
for coord, tile := range t {
// walk black tile list
if tile == 1 {
neighbors := getNeighbors(coord)
bn := 0
for _, n := range neighbors {
if t[n] == 0 {
seenWhiteTiles[n] = seenWhiteTiles[n] + 1
} else {
bn = bn + 1
}
}
// black tiles only survive if they have one or two black neighbors
if bn == 1 || bn == 2 {
newTiles[coord] = 1
}
}
}
// white tiles turn black if they have two black neighbors
for c, n := range seenWhiteTiles {
if n == 2 {
newTiles[c] = 1
}
}
return newTiles
}
func getNeighbors(c coord) []coord {
return []coord{
{x: c.x + 2, y: c.y}, // e
{x: c.x - 2, y: c.y}, // w
{x: c.x + 1, y: c.y + 1}, // ne
{x: c.x + 1, y: c.y - 1}, // nw
{x: c.x - 1, y: c.y + 1}, // se
{x: c.x - 1, y: c.y - 1}, // sw
}
}
func countBlackTiles(t tiles) int {
sum := 0
for _, tile := range t {
sum = sum + tile
}
return sum
}
func partOne() {
f, _ := os.Open("testinput")
reader := bufio.NewReader(f)
scanner := bufio.NewScanner(reader)
t := tiles{}
for scanner.Scan() {
line := scanner.Text()
x, y := walkGrid(parseLine(line))
if t[coord{x: x, y: y}] == 0 {
t[coord{x: x, y: y}] = 1
} else {
t[coord{x: x, y: y}] = 0
}
}
fmt.Println(countBlackTiles(t))
}
func partTwo() {
f, _ := os.Open("input")
reader := bufio.NewReader(f)
scanner := bufio.NewScanner(reader)
t := tiles{}
for scanner.Scan() {
line := scanner.Text()
y, x := walkGrid(parseLine(line))
if t[coord{x: x, y: y}] == 0 {
t[coord{x: x, y: y}] = 1
} else {
t[coord{x: x, y: y}] = 0
}
}
for day := 1; day <= 100; day = day + 1 {
t = generation(t)
}
fmt.Println(countBlackTiles(t))
}