day22, part1, struggle
This commit is contained in:
		
							parent
							
								
									2b3c7f4ca6
								
							
						
					
					
						commit
						45d03e5ab3
					
				@ -26,8 +26,26 @@ store z, and have 'settledZ', maybe with default -1?
 | 
			
		||||
** DONE now i guess what? do i want a sorted map? or just map from height to blocks on that hight?
 | 
			
		||||
let's read file, and calc max height present?
 | 
			
		||||
i suppose funciton to read file could also be initially entered via test, right?
 | 
			
		||||
** TODO now go through the z levels, block by block, doing setting.
 | 
			
		||||
** DONE now go through the z levels, block by block, doing setting.
 | 
			
		||||
i suppose i could organize setting methods around Space?
 | 
			
		||||
it will store (settledOnZ) and (maxSettledOnXY)
 | 
			
		||||
** TODO [#A] when i settle single block. the maxSettledOnXY - should use (z + height)
 | 
			
		||||
** DONE [#A] when i settle single block. the maxSettledOnXY - should use (z + height)
 | 
			
		||||
** i can already imagine secon part? what is the most volume that can be disintegrated? or what? most volume is just all
 | 
			
		||||
* part 1, wrong answer.
 | 
			
		||||
i guess try to go, setting the input? block after block and try to check the calculations?
 | 
			
		||||
 | 
			
		||||
what i want to check:
 | 
			
		||||
how maxSettledOnXY works, how linking works. maybe i'll find a problem in few steps =C
 | 
			
		||||
** can't see anything just glancing around.
 | 
			
		||||
maybe then trying to pick a block and track what's under it?
 | 
			
		||||
* ok. let's try to brute force?
 | 
			
		||||
for each block, remove it?
 | 
			
		||||
create new space and try to settle it
 | 
			
		||||
** this is shit. why blocks move up?
 | 
			
		||||
2023/12/22 12:12:24 >>> starting for block [Block 1 - x:0-2, y:0-0, z:1, h:0, isSettled true] (supports [[Block 3 - x:0-0, y:0-2, z:3, h:0, isSettled true] [Block 4 - x:2-2, y:0-2, z:3, h:0, isSettled true] [Block 3 - x:0-0, y:0-2, z:2, h:0, isSettled true] [Block 4 - x:2-2, y:0-2, z:2, h:0, isSettled true]])
 | 
			
		||||
2023/12/22 12:12:24 block [Block 2 - x:0-2, y:2-2, z:2, h:0, isSettled true] moved from 1 to 2
 | 
			
		||||
2023/12/22 12:12:24 block [Block 3 - x:0-0, y:0-2, z:3, h:0, isSettled true] moved from 2 to 3
 | 
			
		||||
2023/12/22 12:12:24 block [Block 4 - x:2-2, y:0-2, z:3, h:0, isSettled true] moved from 2 to 3
 | 
			
		||||
2023/12/22 12:12:24 block [Block 5 - x:0-2, y:1-1, z:4, h:0, isSettled true] moved from 3 to 4
 | 
			
		||||
2023/12/22 12:12:24 block [Block 6 - x:1-1, y:1-1, z:5, h:1, isSettled true] moved from 4 to 5
 | 
			
		||||
2023/12/22 12:12:24 for block [Block 1 - x:0-2, y:0-0, z:1, h:0, isSettled true] new space has 5 moved
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										38
									
								
								day22/printingSpace.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										38
									
								
								day22/printingSpace.go
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,38 @@
 | 
			
		||||
package day22
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"math"
 | 
			
		||||
 | 
			
		||||
	"github.com/tidwall/pinhole"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func TestPinhole() {
 | 
			
		||||
	p := pinhole.New()
 | 
			
		||||
	p.DrawCube(-0.3, -0.3, -0.3, 0.3, 0.3, 0.3)
 | 
			
		||||
	p.Rotate(math.Pi/3, math.Pi/2, 0)
 | 
			
		||||
	p.SavePNG("cube.png", 500, 500, nil)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func PrintSpace(s Space, filename string) {
 | 
			
		||||
	// pinhole is from -1 to 1. let's use from 0 to 1.
 | 
			
		||||
	// so coord should be divided by max height, and let's hope that they are not too wide
 | 
			
		||||
 | 
			
		||||
	rotation := []float64{math.Pi/3, math.Pi/6, 0}
 | 
			
		||||
 | 
			
		||||
	p := pinhole.New()
 | 
			
		||||
 | 
			
		||||
	p.DrawRect(-1, -1, 1, 1, 0)
 | 
			
		||||
 | 
			
		||||
	for _, zLevel := range s.SettledOnZ {
 | 
			
		||||
		for _, block := range zLevel {
 | 
			
		||||
			p.DrawCube(float64(block.XMin) / float64(s.MaxZ),
 | 
			
		||||
				float64(block.YMin) / float64(s.MaxZ),
 | 
			
		||||
				float64(block.Z) / float64(s.MaxZ),
 | 
			
		||||
				float64(block.XMax + 1) / float64(s.MaxZ),
 | 
			
		||||
				float64(block.YMax + 1) / float64(s.MaxZ),
 | 
			
		||||
				float64(block.Z + block.ZHeight + 1) / float64(s.MaxZ))
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	p.Rotate(rotation[0], rotation[1], rotation[2])
 | 
			
		||||
	p.SavePNG(filename, 1920, 1080, nil)
 | 
			
		||||
}
 | 
			
		||||
@ -6,13 +6,13 @@ import (
 | 
			
		||||
 | 
			
		||||
func Run() int {
 | 
			
		||||
	fmt.Print("oi, hello day 22")
 | 
			
		||||
	filename := "day22/example"
 | 
			
		||||
	filename := "day22/input"
 | 
			
		||||
	blocks := ReadBlockFile(filename)
 | 
			
		||||
	byZ := BlocksByZ(blocks)
 | 
			
		||||
 | 
			
		||||
	space := NewSpace(byZ)
 | 
			
		||||
	space.SettleAll()
 | 
			
		||||
 | 
			
		||||
	result := space.CountFreeBlocks()
 | 
			
		||||
	result := space.ThirdTimeCountFreeBlocks()
 | 
			
		||||
	return result
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										105
									
								
								day22/space.go
									
									
									
									
									
								
							
							
						
						
									
										105
									
								
								day22/space.go
									
									
									
									
									
								
							@ -1,6 +1,11 @@
 | 
			
		||||
package day22
 | 
			
		||||
 | 
			
		||||
import "log"
 | 
			
		||||
import (
 | 
			
		||||
	// "fmt"
 | 
			
		||||
	"log"
 | 
			
		||||
	"slices"
 | 
			
		||||
	// "time"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
type Space struct {
 | 
			
		||||
	MaxZ           uint
 | 
			
		||||
@ -18,16 +23,37 @@ func NewSpace(blocksByZ [][]*Block) Space {
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (s *Space)CountFreeBlocks() (result int) {
 | 
			
		||||
func (s *Space) AgainCountFreeBlocks() (result int) {
 | 
			
		||||
	for _, row := range s.SettledOnZ {
 | 
			
		||||
		for _, block := range row {
 | 
			
		||||
			thisSupports := block.Supports
 | 
			
		||||
			canDisintegrate := true
 | 
			
		||||
			for _, blockThisSupports := range thisSupports {
 | 
			
		||||
				if len(blockThisSupports.SupportedBy) == 1 {
 | 
			
		||||
					// we cannot disintigrate this block
 | 
			
		||||
					canDisintegrate = false
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
			if canDisintegrate {
 | 
			
		||||
				result += 1
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
func (s *Space) CountFreeBlocks() (result int) {
 | 
			
		||||
	allBlocks := make(map[*Block]any)
 | 
			
		||||
 | 
			
		||||
	for _, row := range s.SettledOnZ {
 | 
			
		||||
		for _, block := range row {
 | 
			
		||||
			allBlocks[block] = struct{}{}
 | 
			
		||||
			if len(block.SupportedBy) == 1 {
 | 
			
		||||
				log.Printf("in block %+v. only support is %+v", block, block.SupportedBy)
 | 
			
		||||
				log.Printf("should be NOT OK to remove %+v", block.SupportedBy)
 | 
			
		||||
				delete(allBlocks, block.SupportedBy[0])
 | 
			
		||||
				onlySupport := block.SupportedBy[0]
 | 
			
		||||
				log.Printf("in block %+v. only support is %+v", block, onlySupport)
 | 
			
		||||
				log.Printf("should be NOT OK to remove %+v", onlySupport)
 | 
			
		||||
				delete(allBlocks, onlySupport)
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
@ -35,21 +61,61 @@ func (s *Space)CountFreeBlocks() (result int) {
 | 
			
		||||
	return
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (s *Space)SettleAll() {
 | 
			
		||||
	for i := uint(1); i <= s.MaxZ; i++ {
 | 
			
		||||
		s.SettleZ(i)
 | 
			
		||||
func (s *Space) ThirdTimeCountFreeBlocks() (result int) {
 | 
			
		||||
	// for each block create a new space without it. try to settle and check if 0 moved
 | 
			
		||||
	log.Println(">>>>> starting hardcode count <<<<<")
 | 
			
		||||
	for rowNum, row := range s.SettledOnZ {
 | 
			
		||||
		for blockNum, block  := range row {
 | 
			
		||||
			log.Printf(">>> starting for block %+v (supports %+v)\n", block, block.Supports)
 | 
			
		||||
			newUnsettled := slices.Clone(s.SettledOnZ)
 | 
			
		||||
			for rowNum, row := range newUnsettled {
 | 
			
		||||
				newUnsettled[rowNum] = slices.Clone(row)
 | 
			
		||||
			}
 | 
			
		||||
			newUnsettled[rowNum] = slices.Delete(newUnsettled[rowNum], blockNum, blockNum+1)
 | 
			
		||||
			// and now copy the blocks 
 | 
			
		||||
			for rowNum, row := range newUnsettled {
 | 
			
		||||
				for blockNum, block := range row {
 | 
			
		||||
					newBlock := *block
 | 
			
		||||
					newUnsettled[rowNum][blockNum] = &newBlock
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
			
 | 
			
		||||
			newSpace := NewSpace(newUnsettled)
 | 
			
		||||
			moved := newSpace.SettleAll()
 | 
			
		||||
			if moved > 0 {
 | 
			
		||||
				log.Printf("for block %+v new space has %d moved\n\n", block, moved)
 | 
			
		||||
			} else {
 | 
			
		||||
				log.Printf("for block %+v new space has %d moved\n\n", block, moved)
 | 
			
		||||
				result += 1
 | 
			
		||||
			}
 | 
			
		||||
			
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (s *Space) SettleAll() (totalMoved int) {
 | 
			
		||||
	for i := uint(1); i <= s.MaxZ; i++ {
 | 
			
		||||
		movedAfterLayer := s.SettleZ(i)
 | 
			
		||||
		totalMoved += movedAfterLayer
 | 
			
		||||
	}
 | 
			
		||||
	return
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// settle all blocks in Z, remove Z from UnsettledByZ
 | 
			
		||||
func (s *Space)SettleZ(z uint) {
 | 
			
		||||
func (s *Space) SettleZ(z uint) (totalMoved int) {
 | 
			
		||||
	blocksToSettle := s.UnsettledByZ[int(z)]
 | 
			
		||||
 | 
			
		||||
	for _, block := range blocksToSettle {
 | 
			
		||||
		s.SettleBlock(block)
 | 
			
		||||
		hasMoved := s.SettleBlock(block)
 | 
			
		||||
		if hasMoved {
 | 
			
		||||
			totalMoved += 1
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	s.UnsettledByZ[int(z)] = nil
 | 
			
		||||
	return
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// for the block:
 | 
			
		||||
@ -59,20 +125,29 @@ func (s *Space)SettleZ(z uint) {
 | 
			
		||||
// set Z for block to Z+1, settled to true
 | 
			
		||||
// add block as highest settled for all the XY
 | 
			
		||||
// add block to MaxSettledOnXY
 | 
			
		||||
func (s *Space)SettleBlock(block *Block) {
 | 
			
		||||
func (s *Space) SettleBlock(block *Block) (hasMoved bool) {
 | 
			
		||||
	initialZ := block.Z
 | 
			
		||||
	underZMax := uint(0)
 | 
			
		||||
	underZBlocks := make([]*Block, 0)
 | 
			
		||||
	// fmt.Printf("\n>> for block %s\n", block)
 | 
			
		||||
	for _, xy := range block.getXY() {
 | 
			
		||||
		underBlock, found := s.MaxSettledOnXY[xy]
 | 
			
		||||
		// if block.NameNum
 | 
			
		||||
		if found {
 | 
			
		||||
			underBlockMaxZ := underBlock.Z + underBlock.ZHeight
 | 
			
		||||
			// action := " 'skipping' "
 | 
			
		||||
			if underBlockMaxZ > underZMax {
 | 
			
		||||
				underZBlocks = []*Block{underBlock}
 | 
			
		||||
				underZMax = underBlockMaxZ
 | 
			
		||||
				// action = " 'overriding' "
 | 
			
		||||
			} else if underBlockMaxZ == underZMax {
 | 
			
		||||
				underZBlocks = append(underZBlocks, underBlock)
 | 
			
		||||
				// action = " 'adding' "
 | 
			
		||||
			}
 | 
			
		||||
			// fmt.Printf("checking under coord %+v. found under %+v. (%s) with %d ; maxZ %d\n directly supporting blocks are %+v\n",
 | 
			
		||||
			// 	xy, underBlock, action, underBlockMaxZ, underZMax, underZBlocks)
 | 
			
		||||
		} else {
 | 
			
		||||
			// fmt.Printf("checking under coord %+v. nothing under\n", xy)
 | 
			
		||||
		}
 | 
			
		||||
		s.MaxSettledOnXY[xy] = block
 | 
			
		||||
	}
 | 
			
		||||
@ -86,4 +161,12 @@ func (s *Space)SettleBlock(block *Block) {
 | 
			
		||||
	block.IsSettled = true
 | 
			
		||||
 | 
			
		||||
	s.SettledOnZ[block.Z] = append(s.SettledOnZ[block.Z], block)
 | 
			
		||||
	// fmt.Printf(">> after settring block %s. supported by %+v\n\n", block, block.SupportedBy)
 | 
			
		||||
 | 
			
		||||
	// time.Sleep(500 * time.Millisecond)
 | 
			
		||||
	hasMoved = initialZ != block.Z
 | 
			
		||||
	if hasMoved {
 | 
			
		||||
		log.Printf("block %+v moved from %d to %d", block, initialZ, block.Z)
 | 
			
		||||
	}
 | 
			
		||||
	return 
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -85,3 +85,22 @@ func TestSpaceExampleSettleAll(t *testing.T) {
 | 
			
		||||
	// i guess we can start with set of all blocks, then?
 | 
			
		||||
	// run over all, if some block is only supported by some underBlock - remove that underblock
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func TestPinholeStart(t *testing.T) {
 | 
			
		||||
	TestPinhole()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func TestExampleSpacePrint(t *testing.T) {
 | 
			
		||||
	filename := "example"
 | 
			
		||||
	blocks := ReadBlockFile(filename)
 | 
			
		||||
	byZ := BlocksByZ(blocks)
 | 
			
		||||
 | 
			
		||||
	space := NewSpace(byZ)
 | 
			
		||||
 | 
			
		||||
	// PrintSpace(space, "before-settping.png")
 | 
			
		||||
 | 
			
		||||
	space.SettleAll()
 | 
			
		||||
 | 
			
		||||
	PrintSpace(space, "after-settping.png")
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										9
									
								
								go.mod
									
									
									
									
									
								
							
							
						
						
									
										9
									
								
								go.mod
									
									
									
									
									
								
							@ -1,3 +1,12 @@
 | 
			
		||||
module sunshine.industries/aoc2023
 | 
			
		||||
 | 
			
		||||
go 1.21.4
 | 
			
		||||
 | 
			
		||||
require github.com/tidwall/pinhole v0.0.0-20210130162507-d8644a7c3d19
 | 
			
		||||
 | 
			
		||||
require (
 | 
			
		||||
	github.com/fogleman/gg v1.3.0 // indirect
 | 
			
		||||
	github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 // indirect
 | 
			
		||||
	github.com/google/btree v1.1.2 // indirect
 | 
			
		||||
	golang.org/x/image v0.14.0 // indirect
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										10
									
								
								go.sum
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								go.sum
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,10 @@
 | 
			
		||||
github.com/fogleman/gg v1.3.0 h1:/7zJX8F6AaYQc57WQCyN9cAIz+4bCJGO9B+dyW29am8=
 | 
			
		||||
github.com/fogleman/gg v1.3.0/go.mod h1:R/bRT+9gY/C5z7JzPU0zXsXHKM4/ayA+zqcVNZzPa1k=
 | 
			
		||||
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 h1:DACJavvAHhabrF08vX0COfcOBJRhZ8lUbR+ZWIs0Y5g=
 | 
			
		||||
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGwJL78qG/PmXZO1EjYhfJinVAhrmmHX6Z8B9k=
 | 
			
		||||
github.com/google/btree v1.1.2 h1:xf4v41cLI2Z6FxbKm+8Bu+m8ifhj15JuZ9sa0jZCMUU=
 | 
			
		||||
github.com/google/btree v1.1.2/go.mod h1:qOPhT0dTNdNzV6Z/lhRX0YXUafgPLFUh+gZMl761Gm4=
 | 
			
		||||
github.com/tidwall/pinhole v0.0.0-20210130162507-d8644a7c3d19 h1:PH18rfaiwA/34DAtuREBTrrByvZeLHqhfYh4SG7jYg4=
 | 
			
		||||
github.com/tidwall/pinhole v0.0.0-20210130162507-d8644a7c3d19/go.mod h1:5VfbOBfzaI6Y0XiGSkz7hiXgKtwYaDBI3plwKGsLonM=
 | 
			
		||||
golang.org/x/image v0.14.0 h1:tNgSxAFe3jC4uYqvZdTr84SZoM1KfwdC9SKIFrLjFn4=
 | 
			
		||||
golang.org/x/image v0.14.0/go.mod h1:HUYqC05R2ZcZ3ejNQsIHQDQiwWM4JBqmm6MKANTp4LE=
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user