AoC2020/day17/day17.go

168 lines
4.1 KiB
Go
Raw Normal View History

2020-12-17 21:14:46 +01:00
package main
import (
"AoC2020/helper"
"fmt"
"os"
)
func main() {
args := os.Args[1:]
input, err := helper.GetInput(args[0])
if err != nil {
fmt.Println(err)
}
dimension := readInputLayer(input,0)
fmt.Println(len(getDirectionsPart2()))
for i := 0; i < 6; i++ {
dimension = run(dimension, getDirectionsPart2)
}
}
func run(dimension map[[4]int]rune, getDirections func() [][4]int) map[[4]int]rune {
var changedValues = make(map[[4]int]rune)
directions := getDirections()
visitedNeighbours := make(map[[4]int]int)
for position, status := range dimension {
neighbourPosition := getNeighbourPoints(position,directions)
neighbours := getActiveNeighbours(dimension, neighbourPosition)
if status == '#' && !(neighbours == 2 || neighbours == 3) {
changedValues[position] = '.'
}
for _, position := range neighbourPosition {
visitedNeighbours[position] ++
}
}
for position, val := range visitedNeighbours {
if val == 3 {
changedValues[position] = '#'
}
}
for position, status := range changedValues {
//fmt.Printf("Changed Position: %v Status: %v \n",position,string(status))
if status == '.' {
delete(dimension, position)
}
if status == '#' {
dimension[position] = status
}
}
fmt.Printf("Active Points: %v \n", len(dimension))
return dimension
}
func readInputLayer(input []string, layerLevel int) map[[4]int]rune {
var layer = make(map[[4]int]rune)
for y, row := range input {
for x, val := range row {
if val == '#' {
layer[[4]int{y,x,layerLevel,0}] = val
}
}
}
return layer
}
func printLayer(layer int, width int, height int, dimension map[[3]int]rune) {
for i:= 0; i < height; i++ {
var row []rune
for j:= 0; j < width; j++ {
val := dimension[[3]int{i,j,layer}]
if val == '#' {
row = append(row,val)
}else {
row = append(row, '.')
}
}
fmt.Println(string(row))
}
fmt.Println()
}
func getNeighbourPoints(position [4]int, directions [][4]int) [][4]int{
var neighbourPositions [][4]int
for _, direction := range directions {
neighbourPositions = append(neighbourPositions, add(position, direction))
}
return neighbourPositions
}
func getActiveNeighbours(dimension map[[4]int]rune, neighbourPositions [][4]int) int {
activeNeighbours := 0
for _, neighbourPosition := range neighbourPositions {
if dimension[neighbourPosition] == '#' {
activeNeighbours++
}
}
//fmt.Printf("Active Neighbours: %v \n" ,activeNeighbours)
return activeNeighbours
}
func add(a [4]int, b [4]int) [4]int {
return [4]int{a[0] + b[0], a[1] + b[1], a[2] + b[2], a[3] + b[3]}
}
func getDirections() [][4]int {
possibleValues := [3]int{-1, 0, 1}
var directions [][4]int
for i := 0; i < 3; i++ {
for j := 0; j < 3; j++ {
for k := 0; k < 3; k++ {
if possibleValues[i] != 0 || possibleValues[j] != 0 || possibleValues[k] != 0 {
directions = append(directions, [4]int{possibleValues[i], possibleValues[j], possibleValues[k],0})
}
}
}
}
return directions
}
func getDirectionsPart2() [][4]int {
possibleValues := [3]int{-1, 0, 1}
var directions [][4]int
for i := 0; i < 3; i++ {
for j := 0; j < 3; j++ {
for k := 0; k < 3; k++ {
for l := 0; l < 3; l++ {
if possibleValues[i] != 0 || possibleValues[j] != 0 || possibleValues[k] != 0 || possibleValues[l] != 0 {
directions = append(directions, [4]int{possibleValues[i], possibleValues[j], possibleValues[k],possibleValues[l]})
}
}
}
}
}
return directions
}
func getStatus(position [3]int, dimension [][][]rune) rune {
if len(dimension) < position[0] {
return '.'
}
layer := dimension[position[0]]
if len(layer) < position[1] {
return '.'
}
row := layer[position[1]]
if len(row) < position[2] {
return '.'
}
return rune(row[position[2]])
}
func initiateDimension(z int, x int, y int) [][][]rune {
var emptyRow []rune
for i := 0; i < x; i++ {
emptyRow = append(emptyRow, '.')
}
var emptyLayer [][]rune
for i := 0; i < y; i++ {
emptyLayer = append(emptyLayer, emptyRow)
}
var emptyDimension [][][]rune
for i := 0; i < z; i++ {
emptyDimension = append(emptyDimension, emptyLayer)
}
return emptyDimension
}