2020 Day 17 Complete
This commit is contained in:
		@@ -14,7 +14,7 @@ var FieldMap map[int]string
 | 
			
		||||
var UnknownFields map[int]bool
 | 
			
		||||
 | 
			
		||||
func main() {
 | 
			
		||||
	fmt.Println("# Day 15")
 | 
			
		||||
	fmt.Println("# Day 16")
 | 
			
		||||
	inp := h.StdinToStringSlice()
 | 
			
		||||
	FieldMap = make(map[int]string)
 | 
			
		||||
	UnknownFields = make(map[int]bool)
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										8
									
								
								2020/day17/input
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								2020/day17/input
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,8 @@
 | 
			
		||||
....###.
 | 
			
		||||
#...####
 | 
			
		||||
##.#.###
 | 
			
		||||
..#.#...
 | 
			
		||||
##.#.#.#
 | 
			
		||||
#.######
 | 
			
		||||
..#..#.#
 | 
			
		||||
######.#
 | 
			
		||||
							
								
								
									
										115
									
								
								2020/day17/main.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										115
									
								
								2020/day17/main.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,115 @@
 | 
			
		||||
package main
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"fmt"
 | 
			
		||||
 | 
			
		||||
	h "git.bullercodeworks.com/brian/adventofcode/helpers"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func main() {
 | 
			
		||||
	fmt.Println("# Day 17")
 | 
			
		||||
	fmt.Println()
 | 
			
		||||
	inp := h.StdinToStringSlice()
 | 
			
		||||
	//field := h.StringSliceToCoord3dByteMap(inp)
 | 
			
		||||
	//part1old(field)
 | 
			
		||||
	fmt.Println("## Part 1:\nAnswer:", run(inp, 3))
 | 
			
		||||
	fmt.Println("## Part 2:\nAnswer:", run(inp, 4))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func run(inp []string, dim int) int {
 | 
			
		||||
	cs := NewCubeMapFromLines(inp)
 | 
			
		||||
	for i := 0; i < 6; i++ {
 | 
			
		||||
		next := NewCubeMap()
 | 
			
		||||
		wrk := cs.Copy()
 | 
			
		||||
		for _, c := range cs.ToSlice() {
 | 
			
		||||
			wrk.AddMany(c.Neighbors(dim))
 | 
			
		||||
		}
 | 
			
		||||
		for _, c := range wrk.ToSlice() {
 | 
			
		||||
			active := cs.Contains(c)
 | 
			
		||||
			cnt := 0
 | 
			
		||||
			for _, n := range c.Neighbors(dim) {
 | 
			
		||||
				if cs.Contains(n) {
 | 
			
		||||
					cnt++
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
			if cnt == 3 || (active && cnt == 2) {
 | 
			
		||||
				next.Add(c)
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		cs = next
 | 
			
		||||
	}
 | 
			
		||||
	return cs.Size()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type Cube struct {
 | 
			
		||||
	X, Y, Z, W int
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (c Cube) Neighbors(d int) []Cube {
 | 
			
		||||
	ret := []Cube{}
 | 
			
		||||
	for dx := -1; dx <= 1; dx++ {
 | 
			
		||||
		for dy := -1; dy <= 1; dy++ {
 | 
			
		||||
			for dz := -1; dz <= 1; dz++ {
 | 
			
		||||
				for dw := -(d - 3); dw <= d-3; dw++ {
 | 
			
		||||
					if dx == 0 && dy == 0 && dz == 0 && dw == 0 {
 | 
			
		||||
						continue
 | 
			
		||||
					}
 | 
			
		||||
					ret = append(ret, Cube{c.X + dx, c.Y + dy, c.Z + dz, c.W + dw})
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return ret
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type CubeMap struct {
 | 
			
		||||
	field map[Cube]bool
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func NewCubeMap() *CubeMap {
 | 
			
		||||
	return &CubeMap{map[Cube]bool{}}
 | 
			
		||||
}
 | 
			
		||||
func NewCubeMapFromLines(inp []string) *CubeMap {
 | 
			
		||||
	cs := NewCubeMap()
 | 
			
		||||
	for y, line := range inp {
 | 
			
		||||
		for x, b := range line {
 | 
			
		||||
			if b == '#' {
 | 
			
		||||
				cs.Add(Cube{x, y, 0, 0})
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return cs
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (cs *CubeMap) Add(c Cube) {
 | 
			
		||||
	cs.field[c] = true
 | 
			
		||||
}
 | 
			
		||||
func (cs *CubeMap) AddMany(cubes []Cube) {
 | 
			
		||||
	for _, c := range cubes {
 | 
			
		||||
		cs.Add(c)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
func (cs *CubeMap) Remove(c Cube) {
 | 
			
		||||
	delete(cs.field, c)
 | 
			
		||||
}
 | 
			
		||||
func (cs *CubeMap) Contains(c Cube) bool {
 | 
			
		||||
	_, ok := cs.field[c]
 | 
			
		||||
	return ok
 | 
			
		||||
}
 | 
			
		||||
func (cs *CubeMap) Copy() *CubeMap {
 | 
			
		||||
	field := map[Cube]bool{}
 | 
			
		||||
	for c := range cs.field {
 | 
			
		||||
		field[c] = true
 | 
			
		||||
	}
 | 
			
		||||
	return &CubeMap{field}
 | 
			
		||||
}
 | 
			
		||||
func (cs *CubeMap) Size() int {
 | 
			
		||||
	return len(cs.field)
 | 
			
		||||
}
 | 
			
		||||
func (cs *CubeMap) ToSlice() []Cube {
 | 
			
		||||
	ret := []Cube{}
 | 
			
		||||
	for c := range cs.field {
 | 
			
		||||
		ret = append(ret, Cube{c.X, c.Y, c.Z, c.W})
 | 
			
		||||
	}
 | 
			
		||||
	return ret
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										3
									
								
								2020/day17/testinput
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								2020/day17/testinput
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,3 @@
 | 
			
		||||
.#.
 | 
			
		||||
..#
 | 
			
		||||
###
 | 
			
		||||
@@ -72,5 +72,5 @@ func (c *Coordinate3d) GetDownCoord() *Coordinate3d {
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
func (c Coordinate3d) String() string {
 | 
			
		||||
	return fmt.Sprintf("[%d, %d, %d]", c.X, c.Y, c.Z)
 | 
			
		||||
	return fmt.Sprintf("[X:%d, Y:%d, Z:%d]", c.X, c.Y, c.Z)
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -24,12 +24,19 @@ func StringSliceToCoordByteMap(input []string) CoordByteMap {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (m *CoordByteMap) Get(pos Coordinate) byte {
 | 
			
		||||
	if pos.X <= m.Width && pos.Y <= m.Height {
 | 
			
		||||
		return m.Field[pos]
 | 
			
		||||
	if v, ok := m.Field[pos]; ok {
 | 
			
		||||
		return v
 | 
			
		||||
	}
 | 
			
		||||
	return 0
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (m *CoordByteMap) Opt(pos Coordinate, def byte) byte {
 | 
			
		||||
	if v, ok := m.Field[pos]; ok {
 | 
			
		||||
		return v
 | 
			
		||||
	}
 | 
			
		||||
	return def
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (m *CoordByteMap) Put(pos Coordinate, val byte) {
 | 
			
		||||
	m.Field[pos] = val
 | 
			
		||||
}
 | 
			
		||||
@@ -44,3 +51,118 @@ func (m CoordByteMap) String() string {
 | 
			
		||||
	}
 | 
			
		||||
	return ret
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// And the 3d Version
 | 
			
		||||
type Coord3dByteMap struct {
 | 
			
		||||
	Field      map[Coordinate3d]byte
 | 
			
		||||
	MinX, MaxX int
 | 
			
		||||
	MinY, MaxY int
 | 
			
		||||
	MinZ, MaxZ int
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func StringSliceToCoord3dByteMap(input []string) Coord3dByteMap {
 | 
			
		||||
	ret := Coord3dByteMap{
 | 
			
		||||
		Field: make(map[Coordinate3d]byte),
 | 
			
		||||
	}
 | 
			
		||||
	for y := range input {
 | 
			
		||||
		for x := range input[y] {
 | 
			
		||||
			ret.Put(Coordinate3d{X: x, Y: y, Z: 0}, input[y][x])
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return ret
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (m *Coord3dByteMap) Copy() Coord3dByteMap {
 | 
			
		||||
	ret := Coord3dByteMap{
 | 
			
		||||
		Field: make(map[Coordinate3d]byte),
 | 
			
		||||
		MinX:  m.MinX, MaxX: m.MaxX,
 | 
			
		||||
		MinY: m.MinY, MaxY: m.MaxY,
 | 
			
		||||
		MinZ: m.MinZ, MaxZ: m.MaxZ,
 | 
			
		||||
	}
 | 
			
		||||
	for z := m.MinZ; z <= m.MaxZ; z++ {
 | 
			
		||||
		for y := m.MinY; y <= m.MaxY; y++ {
 | 
			
		||||
			for x := m.MinX; x <= m.MaxX; x++ {
 | 
			
		||||
				c := Coordinate3d{X: x, Y: y, Z: z}
 | 
			
		||||
				ret.Field[c] = m.Get(c)
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return ret
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (m *Coord3dByteMap) Get(pos Coordinate3d) byte {
 | 
			
		||||
	if _, ok := m.Field[pos]; !ok {
 | 
			
		||||
		return 0
 | 
			
		||||
	}
 | 
			
		||||
	return m.Field[pos]
 | 
			
		||||
}
 | 
			
		||||
func (m *Coord3dByteMap) Opt(pos Coordinate3d, def byte) byte {
 | 
			
		||||
	if v, ok := m.Field[pos]; ok {
 | 
			
		||||
		return v
 | 
			
		||||
	}
 | 
			
		||||
	return def
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (m *Coord3dByteMap) Put(pos Coordinate3d, val byte) {
 | 
			
		||||
	m.Field[pos] = val
 | 
			
		||||
	if pos.X < m.MinX {
 | 
			
		||||
		m.MinX = pos.X
 | 
			
		||||
	}
 | 
			
		||||
	if pos.X > m.MaxX {
 | 
			
		||||
		m.MaxX = pos.X
 | 
			
		||||
	}
 | 
			
		||||
	if pos.Y < m.MinY {
 | 
			
		||||
		m.MinY = pos.X
 | 
			
		||||
	}
 | 
			
		||||
	if pos.Y > m.MaxY {
 | 
			
		||||
		m.MaxY = pos.Y
 | 
			
		||||
	}
 | 
			
		||||
	if pos.Z < m.MinZ {
 | 
			
		||||
		m.MinZ = pos.Z
 | 
			
		||||
	}
 | 
			
		||||
	if pos.Z > m.MaxZ {
 | 
			
		||||
		m.MaxZ = pos.Z
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (m *Coord3dByteMap) CountNeighbors(pos Coordinate3d, val byte) int {
 | 
			
		||||
	var res int
 | 
			
		||||
	for z := pos.Z - 1; z <= pos.Z+1; z++ {
 | 
			
		||||
		for y := pos.Y - 1; y <= pos.Y+1; y++ {
 | 
			
		||||
			for x := pos.X - 1; x <= pos.X+1; x++ {
 | 
			
		||||
				if m.Get(Coordinate3d{X: x, Y: y, Z: z}) == val {
 | 
			
		||||
					res++
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return res
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (m Coord3dByteMap) Count(val byte) int {
 | 
			
		||||
	var ret int
 | 
			
		||||
	for z := m.MinZ; z <= m.MaxZ; z++ {
 | 
			
		||||
		for y := m.MinY; y <= m.MaxY; y++ {
 | 
			
		||||
			for x := m.MinX; x <= m.MaxX; x++ {
 | 
			
		||||
				if m.Get(Coordinate3d{X: x, Y: y, Z: z}) == val {
 | 
			
		||||
					ret++
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return ret
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (m Coord3dByteMap) String() string {
 | 
			
		||||
	var ret string
 | 
			
		||||
	for z := m.MinZ; z <= m.MaxZ; z++ {
 | 
			
		||||
		for y := m.MinY; y <= m.MaxY; y++ {
 | 
			
		||||
			for x := m.MinX; x <= m.MaxX; x++ {
 | 
			
		||||
				ret = ret + string(m.Field[Coordinate3d{X: x, Y: y, Z: z}])
 | 
			
		||||
			}
 | 
			
		||||
			ret = ret + "\n"
 | 
			
		||||
		}
 | 
			
		||||
		ret = ret + "\n\n"
 | 
			
		||||
	}
 | 
			
		||||
	return ret
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user