day18: example optimized

This commit is contained in:
efim 2023-12-18 11:41:55 +00:00
parent d799b122ce
commit b831e92e1f
1 changed files with 109 additions and 87 deletions

View File

@ -13,7 +13,7 @@ func Run() int {
log.Println("hello day 18") log.Println("hello day 18")
log.Println("problem of lagoon bgins") log.Println("problem of lagoon bgins")
filename := "day18/example" filename := "day18/example"
instructions := ReadInstructionas2(filename) instructions := ReadInstructionas(filename)
h, w := calcHeightWidth(instructions) h, w := calcHeightWidth(instructions)
log.Printf("read %+v instructions", instructions) log.Printf("read %+v instructions", instructions)
@ -21,19 +21,22 @@ func Run() int {
log.Println("created field") log.Println("created field")
// fmt.Println(field.String()) // fmt.Println(field.String())
field.digByInstructions(instructions) borderAmount := field.digByInstructions(instructions)
// fmt.Println(field.String()) fmt.Println(field.String())
// WriteToFile("borders.txt", field.String()) // WriteToFile("borders.txt", field.String())
// convert -size 3000x6000 xc:white -font "FreeMono" -pointsize 13 -fill black -draw @borders.txt borders.png // convert -size 3000x6000 xc:white -font "FreeMono" -pointsize 13 -fill black -draw @borders.txt borders.png
field.digInsides() insideAmount := field.digInsides()
log.Printf("border is %d; inside is %d", borderAmount, insideAmount)
fmt.Println(field.String())
// fmt.Println(field.Height, field.Width) // fmt.Println(field.Height, field.Width)
// WriteToFile("fulldug.txt", field.String()) // WriteToFile("fulldug.txt", field.String())
// convert -size 3000x6000 xc:white -font "FreeMono" -pointsize 13 -fill black -draw @fulldug.txt fulldug.png // convert -size 3000x6000 xc:white -font "FreeMono" -pointsize 13 -fill black -draw @fulldug.txt fulldug.png
return field.countDugOut() // field.countDugOut()
return borderAmount + insideAmount
} }
// determine size of field. max(sum(up), sum(down)) for height, // determine size of field. max(sum(up), sum(down)) for height,
@ -50,10 +53,13 @@ func Run() int {
// last part is filling in isides, should be ok with horizontal scans from left by even crossings // last part is filling in isides, should be ok with horizontal scans from left by even crossings
type Direction int type Direction int
const (Upward Direction = iota
const (
Upward Direction = iota
Downward Downward
Leftward Leftward
Rightward) Rightward
)
func (d Direction) opposite() Direction { func (d Direction) opposite() Direction {
switch d { switch d {
@ -133,10 +139,14 @@ func ReadInstruction2(line string) Instruction {
hexDirection := fields[2][len(fields[2])-2 : len(fields[2])-1] hexDirection := fields[2][len(fields[2])-2 : len(fields[2])-1]
var direction Direction var direction Direction
switch hexDirection { switch hexDirection {
case "0": direction = Rightward case "0":
case "1": direction = Downward direction = Rightward
case "2": direction = Leftward case "1":
case "3": direction = Upward direction = Downward
case "2":
direction = Leftward
case "3":
direction = Upward
} }
dist, err := strconv.ParseUint(hexDist, 16, 64) dist, err := strconv.ParseUint(hexDist, 16, 64)
@ -176,6 +186,7 @@ func calcHeightWidth(instructions []Instruction) (height, width int) {
type Coord struct { type Coord struct {
X, Y int X, Y int
} }
func (c Coord) applyDirection(d Direction) Coord { func (c Coord) applyDirection(d Direction) Coord {
switch d { switch d {
case Upward: case Upward:
@ -194,7 +205,6 @@ func (c Coord)applyDirection(d Direction) Coord {
type Cell struct { type Cell struct {
IsDug bool IsDug bool
ToBeDug bool ToBeDug bool
Walls map[Direction]string
Coord Coord Coord Coord
} }
type Field struct { type Field struct {
@ -207,11 +217,9 @@ func CreateField(height, width int) Field {
for i := 0; i < height; i++ { for i := 0; i < height; i++ {
row := make([]*Cell, width) row := make([]*Cell, width)
rows[i] = row rows[i] = row
for j := 0; j < width; j++ { // for j := 0; j < width; j++ {
row[j] = &Cell{ // row[j] = &Cell{}
Walls: make(map[Direction]string), // }
}
}
} }
return Field{ return Field{
Height: height, Width: width, Height: height, Width: width,
@ -225,17 +233,23 @@ func (f *Field)coordToIndices(c Coord) (row, col int) {
return return
} }
func (f *Field)digByInstructions(instructions []Instruction) { func (f *Field) digByInstructions(instructions []Instruction) (borderAmount int) {
runnerCoord := Coord{X: 0, Y: 0} runnerCoord := Coord{X: 0, Y: 0}
row, col := f.coordToIndices(runnerCoord) row, col := f.coordToIndices(runnerCoord)
f.Cells[row][col].IsDug = true f.Cells[row][col] = &Cell{
IsDug: true,
}
// borderAmount += 1
for _, instruction := range instructions { for _, instruction := range instructions {
log.Printf("starting instruction %+v", instruction) log.Printf("starting instruction %+v", instruction)
for i := 0; i < instruction.Steps; i++ { for i := 0; i < instruction.Steps; i++ {
runnerCoord = runnerCoord.applyDirection(instruction.Direction) runnerCoord = runnerCoord.applyDirection(instruction.Direction)
row, col := f.coordToIndices(runnerCoord) row, col := f.coordToIndices(runnerCoord)
f.Cells[row][col].IsDug = true f.Cells[row][col] = &Cell{
IsDug: true,
}
borderAmount += 1
} }
} }
return return
@ -244,19 +258,18 @@ func (f *Field)digByInstructions(instructions []Instruction) {
func (f *Field) String() string { func (f *Field) String() string {
s := "text 15,15 \"" s := "text 15,15 \""
firstNonemptyRow, lastNonemptyRow := 0, 0 firstNonemptyRow, lastNonemptyRow := 0, 0
log.Print("just use", firstNonemptyRow, lastNonemptyRow)
seenInRows := false seenInRows := false
firstNonemptyCol, lastNonemptyCol := 0, 0 firstNonemptyCol, lastNonemptyCol := 0, 0
seenInCols := false seenInCols := false
for i, row := range f.Cells { for i, row := range f.Cells {
seenInRow := false seenInRow := false
for _, cell := range row { for j := 0; j < len(row); j++ {
if cell.IsDug { if f.isCellDug(i, j) {
seenInRow = true seenInRow = true
} else {
} }
} }
seenInRows = seenInRows || seenInRow seenInRows = seenInRows || seenInRow
if seenInRow { if seenInRow {
lastNonemptyRow = i lastNonemptyRow = i
@ -269,8 +282,7 @@ func (f *Field)String() string {
for col := 0; col < f.Width; col++ { for col := 0; col < f.Width; col++ {
seenInCol := false seenInCol := false
for row := 0; row < f.Height; row++ { for row := 0; row < f.Height; row++ {
cell := f.Cells[row][col] if f.isCellDug(row, col) {
if cell.IsDug {
seenInCol = true seenInCol = true
} }
} }
@ -284,16 +296,17 @@ func (f *Field)String() string {
} }
rowLen := lastNonemptyCol - firstNonemptyCol + 1 rowLen := lastNonemptyCol - firstNonemptyCol + 1
for i := firstNonemptyRow; i <= lastNonemptyRow; i++ { log.Print(rowLen)
rowChars := make([]rune, rowLen) for i := 0; i <= f.Height-1; i++ {
for col := firstNonemptyCol; col <= lastNonemptyCol; col++ { rowChars := make([]rune, f.Width)
for col := 0; col <= f.Width-1; col++ {
cell := f.Cells[i][col] cell := f.Cells[i][col]
if cell.IsDug { if cell != nil && cell.ToBeDug {
rowChars[col-firstNonemptyCol] = '#' rowChars[col] = '@'
} else if cell.ToBeDug { } else if f.isCellDug(i, col) {
rowChars[col-firstNonemptyCol] = '@' rowChars[col] = '#'
} else { } else {
rowChars[col-firstNonemptyCol] = '.' rowChars[col] = '.'
} }
} }
@ -304,18 +317,17 @@ func (f *Field)String() string {
return s return s
} }
func (f *Field)digInsides() { func (f *Field) digInsides() (countInside int) {
for row := 0; row < f.Height; row++ { for row := 1; row < f.Height-1; row++ {
isInside := false isInside := false
seenUp, seenDown := false, false // for detecting L---7 walls seenUp, seenDown := false, false // for detecting L---7 walls
for col := 0; col < f.Width-1; col++ { for col := 0; col < f.Width-1; col++ {
cellPtr := f.Cells[row][col] rightCellIsDug := f.isCellDug(row, col+1)
rightCell := f.Cells[row][col+1] if f.isCellDug(row, col) {
if cellPtr.IsDug { upCellIsDug := f.isCellDug(row-1, col)
upCell := f.Cells[row-1][col] downCellIsDug := f.isCellDug(row+1, col)
downCell := f.Cells[row+1][col] if !rightCellIsDug {
if !rightCell.IsDug { if (upCellIsDug && seenDown) || (downCellIsDug && seenUp) {
if (upCell.IsDug && seenDown) || (downCell.IsDug && seenUp) {
isInside = !isInside isInside = !isInside
} }
seenUp, seenDown = false, false seenUp, seenDown = false, false
@ -323,31 +335,41 @@ func (f *Field)digInsides() {
} else { } else {
// not a dug out cell, maybe inside and needs to be dug out // not a dug out cell, maybe inside and needs to be dug out
if isInside { if isInside {
cellPtr.ToBeDug = true f.Cells[row][col] = &Cell{
} ToBeDug: true,
if rightCell.IsDug {
nextUpCell := f.Cells[row-1][col+1]
nextDownCell := f.Cells[row+1][col+1]
seenUp = nextUpCell.IsDug
seenDown = nextDownCell.IsDug
} }
countInside += 1
log.Printf("tick count inside for %d %d", row, col)
// cellPtr.ToBeDug = true
} }
} if rightCellIsDug {
} seenUp = f.isCellDug(row-1, col+1)
seenDown = f.isCellDug(row+1, col+1)
} }
func (f *Field)countDugOut() (result int) {
for _, row := range f.Cells {
for _, cell := range row {
if cell.IsDug || cell.ToBeDug {
result += 1
} }
} }
} }
return return
} }
func (f *Field) isCellDug(row, col int) bool {
cell := f.Cells[row][col]
return cell != nil && cell.IsDug
}
// func (f *Field)countDugOut() (result int) {
// for _, row := range f.Cells {
// for _, cell := range row {
// if cell.IsDug || cell.ToBeDug {
// result += 1
// }
// }
// }
// return
// }
func WriteToFile(filename string, content string) { func WriteToFile(filename string, content string) {
fileBorder, err := os.Create(filename) fileBorder, err := os.Create(filename)
if err != nil { if err != nil {