parent
698ddc4dfd
commit
6194da02c9
4 changed files with 205 additions and 16 deletions
@ -0,0 +1,167 @@ |
||||
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 |
||||
} |
@ -0,0 +1,8 @@ |
||||
##....#. |
||||
#.#..#.. |
||||
...#.... |
||||
...#.#.. |
||||
###....# |
||||
#.#....# |
||||
.#....## |
||||
.#.###.# |
@ -0,0 +1,3 @@ |
||||
.#. |
||||
..# |
||||
### |
Loading…
Reference in new issue