From b831e92e1fbd61e1946c5625aa554d43d1881cd5 Mon Sep 17 00:00:00 2001 From: efim Date: Mon, 18 Dec 2023 11:41:55 +0000 Subject: [PATCH] day18: example optimized --- day18/lagoon.go | 196 +++++++++++++++++++++++++++--------------------- 1 file changed, 109 insertions(+), 87 deletions(-) diff --git a/day18/lagoon.go b/day18/lagoon.go index 347af1f..12046f3 100644 --- a/day18/lagoon.go +++ b/day18/lagoon.go @@ -13,7 +13,7 @@ func Run() int { log.Println("hello day 18") log.Println("problem of lagoon bgins") filename := "day18/example" - instructions := ReadInstructionas2(filename) + instructions := ReadInstructionas(filename) h, w := calcHeightWidth(instructions) log.Printf("read %+v instructions", instructions) @@ -21,19 +21,22 @@ func Run() int { log.Println("created field") // fmt.Println(field.String()) - field.digByInstructions(instructions) + borderAmount := field.digByInstructions(instructions) - // fmt.Println(field.String()) + fmt.Println(field.String()) // WriteToFile("borders.txt", field.String()) // 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) // WriteToFile("fulldug.txt", field.String()) // 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, @@ -50,20 +53,23 @@ func Run() int { // last part is filling in isides, should be ok with horizontal scans from left by even crossings type Direction int -const (Upward Direction = iota -Downward -Leftward -Rightward) -func (d Direction)opposite() Direction { +const ( + Upward Direction = iota + Downward + Leftward + Rightward +) + +func (d Direction) opposite() Direction { switch d { - case Upward: + case Upward: return Downward - case Downward: + case Downward: return Upward - case Leftward: + case Leftward: return Rightward - case Rightward: + case Rightward: return Leftward } panic("unaccounted direction") @@ -71,7 +77,7 @@ func (d Direction)opposite() Direction { var DirectionNames []string = []string{"U", "D", "L", "R"} -func (d Direction)String() string { +func (d Direction) String() string { return DirectionNames[d] } func DirectionFromString(s string) Direction { @@ -84,8 +90,8 @@ func DirectionFromString(s string) Direction { type Instruction struct { Direction Direction - Steps int - Color string + Steps int + Color string } func ReadInstructionas(filename string) (result []Instruction) { @@ -130,13 +136,17 @@ func ReadInstruction2(line string) Instruction { fields := strings.Fields(line) hexDist := fields[2][2 : len(fields[2])-2] - 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 switch hexDirection { - case "0": direction = Rightward - case "1": direction = Downward - case "2": direction = Leftward - case "3": direction = Upward + case "0": + direction = Rightward + case "1": + direction = Downward + case "2": + direction = Leftward + case "3": + direction = Upward } dist, err := strconv.ParseUint(hexDist, 16, 64) @@ -145,7 +155,7 @@ func ReadInstruction2(line string) Instruction { } return Instruction{ - Steps: int(dist), + Steps: int(dist), Direction: direction, } } @@ -176,15 +186,16 @@ func calcHeightWidth(instructions []Instruction) (height, width int) { type Coord struct { X, Y int } -func (c Coord)applyDirection(d Direction) Coord { + +func (c Coord) applyDirection(d Direction) Coord { switch d { - case Upward: + case Upward: c.Y -= 1 - case Downward: + case Downward: c.Y += 1 - case Leftward: + case Leftward: c.X -= 1 - case Rightward: + case Rightward: c.X += 1 } @@ -192,14 +203,13 @@ func (c Coord)applyDirection(d Direction) Coord { } type Cell struct { - IsDug bool + IsDug bool ToBeDug bool - Walls map[Direction]string - Coord Coord + Coord Coord } type Field struct { Height, Width int - Cells [][]*Cell + Cells [][]*Cell } func CreateField(height, width int) Field { @@ -207,11 +217,9 @@ func CreateField(height, width int) Field { for i := 0; i < height; i++ { row := make([]*Cell, width) rows[i] = row - for j := 0; j < width; j++ { - row[j] = &Cell{ - Walls: make(map[Direction]string), - } - } + // for j := 0; j < width; j++ { + // row[j] = &Cell{} + // } } return Field{ Height: height, Width: width, @@ -219,44 +227,49 @@ func CreateField(height, width int) Field { } } -func (f *Field)coordToIndices(c Coord) (row, col int) { - row = c.Y + (f.Height/2) - col = c.X + (f.Width/2) +func (f *Field) coordToIndices(c Coord) (row, col int) { + row = c.Y + (f.Height / 2) + col = c.X + (f.Width / 2) return } -func (f *Field)digByInstructions(instructions []Instruction) { +func (f *Field) digByInstructions(instructions []Instruction) (borderAmount int) { runnerCoord := Coord{X: 0, Y: 0} row, col := f.coordToIndices(runnerCoord) - f.Cells[row][col].IsDug = true + f.Cells[row][col] = &Cell{ + IsDug: true, + } + // borderAmount += 1 for _, instruction := range instructions { log.Printf("starting instruction %+v", instruction) for i := 0; i < instruction.Steps; i++ { runnerCoord = runnerCoord.applyDirection(instruction.Direction) row, col := f.coordToIndices(runnerCoord) - f.Cells[row][col].IsDug = true + f.Cells[row][col] = &Cell{ + IsDug: true, + } + borderAmount += 1 } } return } -func (f *Field)String() string { +func (f *Field) String() string { s := "text 15,15 \"" - firstNonemptyRow, lastNonemptyRow := 0,0 + firstNonemptyRow, lastNonemptyRow := 0, 0 + log.Print("just use", firstNonemptyRow, lastNonemptyRow) seenInRows := false - firstNonemptyCol, lastNonemptyCol := 0,0 + firstNonemptyCol, lastNonemptyCol := 0, 0 seenInCols := false for i, row := range f.Cells { seenInRow := false - for _, cell := range row { - if cell.IsDug { + for j := 0; j < len(row); j++ { + if f.isCellDug(i, j) { seenInRow = true - } else { } } - seenInRows = seenInRows || seenInRow if seenInRow { lastNonemptyRow = i @@ -269,8 +282,7 @@ func (f *Field)String() string { for col := 0; col < f.Width; col++ { seenInCol := false for row := 0; row < f.Height; row++ { - cell := f.Cells[row][col] - if cell.IsDug { + if f.isCellDug(row, col) { seenInCol = true } } @@ -284,16 +296,17 @@ func (f *Field)String() string { } rowLen := lastNonemptyCol - firstNonemptyCol + 1 - for i := firstNonemptyRow; i <= lastNonemptyRow; i++ { - rowChars := make([]rune, rowLen) - for col := firstNonemptyCol; col <= lastNonemptyCol; col++ { + log.Print(rowLen) + for i := 0; i <= f.Height-1; i++ { + rowChars := make([]rune, f.Width) + for col := 0; col <= f.Width-1; col++ { cell := f.Cells[i][col] - if cell.IsDug { - rowChars[col-firstNonemptyCol] = '#' - } else if cell.ToBeDug { - rowChars[col-firstNonemptyCol] = '@' + if cell != nil && cell.ToBeDug { + rowChars[col] = '@' + } else if f.isCellDug(i, col) { + rowChars[col] = '#' } else { - rowChars[col-firstNonemptyCol] = '.' + rowChars[col] = '.' } } @@ -304,18 +317,17 @@ func (f *Field)String() string { return s } -func (f *Field)digInsides() { - for row := 0; row < f.Height; row++ { +func (f *Field) digInsides() (countInside int) { + for row := 1; row < f.Height-1; row++ { isInside := false seenUp, seenDown := false, false // for detecting L---7 walls - for col := 0; col < f.Width - 1; col++ { - cellPtr := f.Cells[row][col] - rightCell := f.Cells[row][col+1] - if cellPtr.IsDug { - upCell := f.Cells[row-1][col] - downCell := f.Cells[row+1][col] - if !rightCell.IsDug { - if (upCell.IsDug && seenDown) || (downCell.IsDug && seenUp) { + for col := 0; col < f.Width-1; col++ { + rightCellIsDug := f.isCellDug(row, col+1) + if f.isCellDug(row, col) { + upCellIsDug := f.isCellDug(row-1, col) + downCellIsDug := f.isCellDug(row+1, col) + if !rightCellIsDug { + if (upCellIsDug && seenDown) || (downCellIsDug && seenUp) { isInside = !isInside } seenUp, seenDown = false, false @@ -323,37 +335,47 @@ func (f *Field)digInsides() { } else { // not a dug out cell, maybe inside and needs to be dug out if isInside { - cellPtr.ToBeDug = true + f.Cells[row][col] = &Cell{ + ToBeDug: true, + } + + countInside += 1 + log.Printf("tick count inside for %d %d", row, col) + // cellPtr.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 + 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 } +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) { fileBorder, err := os.Create(filename) if err != nil { panic(err) } - defer func(){ + defer func() { if err := fileBorder.Close(); err != nil { panic(err) }