2020 Day 17 Complete
This commit is contained in:
		@@ -14,7 +14,7 @@ var FieldMap map[int]string
 | 
				
			|||||||
var UnknownFields map[int]bool
 | 
					var UnknownFields map[int]bool
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func main() {
 | 
					func main() {
 | 
				
			||||||
	fmt.Println("# Day 15")
 | 
						fmt.Println("# Day 16")
 | 
				
			||||||
	inp := h.StdinToStringSlice()
 | 
						inp := h.StdinToStringSlice()
 | 
				
			||||||
	FieldMap = make(map[int]string)
 | 
						FieldMap = make(map[int]string)
 | 
				
			||||||
	UnknownFields = make(map[int]bool)
 | 
						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 {
 | 
					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 {
 | 
					func (m *CoordByteMap) Get(pos Coordinate) byte {
 | 
				
			||||||
	if pos.X <= m.Width && pos.Y <= m.Height {
 | 
						if v, ok := m.Field[pos]; ok {
 | 
				
			||||||
		return m.Field[pos]
 | 
							return v
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return 0
 | 
						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) {
 | 
					func (m *CoordByteMap) Put(pos Coordinate, val byte) {
 | 
				
			||||||
	m.Field[pos] = val
 | 
						m.Field[pos] = val
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -44,3 +51,118 @@ func (m CoordByteMap) String() string {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
	return ret
 | 
						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