day18, another example working
This commit is contained in:
		
							parent
							
								
									86c9ad7653
								
							
						
					
					
						commit
						6dabe8bc66
					
				
							
								
								
									
										178
									
								
								day18/lagoon.go
									
									
									
									
									
								
							
							
						
						
									
										178
									
								
								day18/lagoon.go
									
									
									
									
									
								
							@ -12,8 +12,8 @@ import (
 | 
				
			|||||||
func Run() int {
 | 
					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/example2"
 | 
						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,7 +21,7 @@ func Run() int {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	fmt.Println(field.String())
 | 
						fmt.Println(field.String())
 | 
				
			||||||
	borderAmount := field.digByInstructions(instructions)
 | 
						borderAmount := field.digByInstructions(instructions)
 | 
				
			||||||
	// log.Println("created field", field.BorderCellCols)
 | 
						log.Println(">>> created field", field.BordersFromLeft)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	fmt.Println(field.String())
 | 
						fmt.Println(field.String())
 | 
				
			||||||
	// WriteToFile("borders.txt", field.String())
 | 
						// WriteToFile("borders.txt", field.String())
 | 
				
			||||||
@ -208,17 +208,25 @@ type Cell struct {
 | 
				
			|||||||
	ToBeDug bool
 | 
						ToBeDug bool
 | 
				
			||||||
	Coord   Coord
 | 
						Coord   Coord
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type BorderSymbol rune
 | 
				
			||||||
 | 
					// '' always left to right
 | 
				
			||||||
 | 
					const (Vertical BorderSymbol = '|'
 | 
				
			||||||
 | 
						ToDown BorderSymbol = '7'
 | 
				
			||||||
 | 
						ToUp BorderSymbol = 'J'
 | 
				
			||||||
 | 
						FromUp BorderSymbol = 'F'
 | 
				
			||||||
 | 
						FromDown BorderSymbol = 'L'
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type Field struct {
 | 
					type Field struct {
 | 
				
			||||||
	Height, Width int
 | 
						Height, Width int
 | 
				
			||||||
	// Cells         [][]*Cell
 | 
						// Cells         [][]*Cell
 | 
				
			||||||
	Cells map[Coord]*Cell
 | 
						Cells map[Coord]*Cell
 | 
				
			||||||
	MinRow, MaxRow, MinCol, MaxCol int
 | 
						MinRow, MaxRow, MinCol, MaxCol int
 | 
				
			||||||
	// TODO - make this map[int]map[int]any (for the set)
 | 
						BordersFromLeft map[int]map[int]BorderSymbol
 | 
				
			||||||
	BorderCellCols map[int][]int // known row -> col
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
func (f *Field)confirmCoord(c Coord) {
 | 
					func (f *Field)confirmCoord(c Coord) {
 | 
				
			||||||
	// log.Printf("configming coord %+v", c)
 | 
						// log.Printf("configming coord %+v", c)
 | 
				
			||||||
	f.BorderCellCols[c.Row] = append(f.BorderCellCols[c.Row], c.Col)
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if c.Row - 3 < f.MinRow {
 | 
						if c.Row - 3 < f.MinRow {
 | 
				
			||||||
		f.MinRow = c.Row - 3
 | 
							f.MinRow = c.Row - 3
 | 
				
			||||||
@ -238,11 +246,25 @@ func CreateField(height, width int) Field {
 | 
				
			|||||||
	return Field{
 | 
						return Field{
 | 
				
			||||||
		Height: height, Width: width,
 | 
							Height: height, Width: width,
 | 
				
			||||||
		Cells: make(map[Coord]*Cell),
 | 
							Cells: make(map[Coord]*Cell),
 | 
				
			||||||
		BorderCellCols: make(map[int][]int),
 | 
							BordersFromLeft: make(map[int]map[int]BorderSymbol),
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func PutSymbIntoMMMMap(mmmap map[int]map[int]BorderSymbol, row, col int, symb BorderSymbol) {
 | 
				
			||||||
 | 
						rowMap := mmmap[row]
 | 
				
			||||||
 | 
						if rowMap == nil {
 | 
				
			||||||
 | 
							rowMap = make(map[int]BorderSymbol)
 | 
				
			||||||
 | 
							mmmap[row] = rowMap
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						rowMap[col] = symb
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (f *Field) digByInstructions(instructions []Instruction) (borderAmount int) {
 | 
					func (f *Field) digByInstructions(instructions []Instruction) (borderAmount int) {
 | 
				
			||||||
 | 
						// for the last turn
 | 
				
			||||||
 | 
						instructions = append(instructions, instructions[0])
 | 
				
			||||||
 | 
						// but also don't overcount the border
 | 
				
			||||||
 | 
						borderAmount -= instructions[0].Steps
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	runnerCoord := Coord{Col: 0, Row: 0}
 | 
						runnerCoord := Coord{Col: 0, Row: 0}
 | 
				
			||||||
	f.Cells[runnerCoord] = &Cell{
 | 
						f.Cells[runnerCoord] = &Cell{
 | 
				
			||||||
		IsDug: true,
 | 
							IsDug: true,
 | 
				
			||||||
@ -250,8 +272,19 @@ func (f *Field) digByInstructions(instructions []Instruction) (borderAmount int)
 | 
				
			|||||||
	// f.confirmCoord(runnerCoord) // should be confirmed when the cycle is closed on last step
 | 
						// f.confirmCoord(runnerCoord) // should be confirmed when the cycle is closed on last step
 | 
				
			||||||
	// borderAmount += 1
 | 
						// borderAmount += 1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						var prevInstruction Instruction
 | 
				
			||||||
 | 
						firstInstruction := true
 | 
				
			||||||
	for _, instruction := range instructions {
 | 
						for _, instruction := range instructions {
 | 
				
			||||||
		fmt.Printf("starting instruction %+v", instruction)
 | 
							log.Printf("starting new instruction %+v", instruction)
 | 
				
			||||||
 | 
							if !firstInstruction {
 | 
				
			||||||
 | 
								turn := getTurnAsIfGoingFromLeft(prevInstruction.Direction, instruction.Direction)
 | 
				
			||||||
 | 
								for _, theTurn := range turn {
 | 
				
			||||||
 | 
									log.Printf(">> putting turn %s", string(turn))
 | 
				
			||||||
 | 
									PutSymbIntoMMMMap(f.BordersFromLeft, runnerCoord.Row, runnerCoord.Col, theTurn)
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							firstInstruction = false
 | 
				
			||||||
 | 
							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)
 | 
				
			||||||
			f.Cells[runnerCoord] = &Cell{
 | 
								f.Cells[runnerCoord] = &Cell{
 | 
				
			||||||
@ -259,22 +292,77 @@ func (f *Field) digByInstructions(instructions []Instruction) (borderAmount int)
 | 
				
			|||||||
			}
 | 
								}
 | 
				
			||||||
			f.confirmCoord(runnerCoord)
 | 
								f.confirmCoord(runnerCoord)
 | 
				
			||||||
			borderAmount += 1
 | 
								borderAmount += 1
 | 
				
			||||||
 | 
								log.Printf("inside %+v updated border amount to %d", instruction, borderAmount)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								if instruction.Direction == Upward || instruction.Direction == Downward {
 | 
				
			||||||
 | 
									_, alreadyCountedTurn := f.BordersFromLeft[runnerCoord.Row][runnerCoord.Col] 
 | 
				
			||||||
 | 
									if !alreadyCountedTurn {
 | 
				
			||||||
 | 
										PutSymbIntoMMMMap(f.BordersFromLeft, runnerCoord.Row, runnerCoord.Col, Vertical)
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
							prevInstruction = instruction
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return
 | 
						return
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func getTurnAsIfGoingFromLeft(directionFrom, directionTo Direction)  []BorderSymbol {
 | 
				
			||||||
 | 
						log.Printf("getTurnAsIfGoingFromLeft from %s to %s", directionFrom.String(), directionTo.String())
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						var symbol BorderSymbol
 | 
				
			||||||
 | 
						if directionTo == Rightward && directionFrom == Upward {
 | 
				
			||||||
 | 
							symbol = FromUp
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if directionTo == Rightward && directionFrom == Downward {
 | 
				
			||||||
 | 
							symbol = FromDown
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if directionTo == Leftward && directionFrom == Upward {
 | 
				
			||||||
 | 
							symbol = ToDown
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if directionTo == Leftward && directionFrom == Downward {
 | 
				
			||||||
 | 
							symbol = ToUp
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if directionFrom == Rightward && directionTo == Upward {
 | 
				
			||||||
 | 
							symbol = ToUp
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if directionFrom == Rightward && directionTo == Downward {
 | 
				
			||||||
 | 
							symbol = ToDown
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if directionFrom == Leftward && directionTo == Upward {
 | 
				
			||||||
 | 
							symbol = FromDown
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if directionFrom == Leftward && directionTo == Downward {
 | 
				
			||||||
 | 
							symbol = FromUp
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// panic(fmt.Sprint("got strange from %s to %s", directionFrom.String(), directionTo.String()))
 | 
				
			||||||
 | 
						return []BorderSymbol{symbol}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (f *Field) String() string {
 | 
					func (f *Field) String() string {
 | 
				
			||||||
	s := "text 15,15 \""
 | 
						s := "text 15,15 \""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	for row := f.MinRow; row <= f.MaxRow; row++ {
 | 
						for row := f.MinRow; row <= f.MaxRow; row++ {
 | 
				
			||||||
		rowChars := make([]rune, f.MaxCol - f.MinCol + 1)
 | 
							rowChars := make([]rune, f.MaxCol - f.MinCol + 1)
 | 
				
			||||||
		for col := f.MinCol; col <= f.MaxCol; col++ {
 | 
							for col := f.MinCol; col <= f.MaxCol; col++ {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								rowBords := f.BordersFromLeft[row]
 | 
				
			||||||
 | 
								if rowBords != nil {
 | 
				
			||||||
 | 
									bord, exists := rowBords[col]
 | 
				
			||||||
 | 
									if exists {
 | 
				
			||||||
 | 
										rowChars[col - f.MinCol] = rune(bord)
 | 
				
			||||||
 | 
										continue
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
			cell := f.Cells[Coord{col, row}]
 | 
								cell := f.Cells[Coord{col, row}]
 | 
				
			||||||
			if cell != nil && cell.ToBeDug {
 | 
								if cell != nil && cell.ToBeDug {
 | 
				
			||||||
				rowChars[col - f.MinCol] = '@'
 | 
									rowChars[col - f.MinCol] = '@'
 | 
				
			||||||
				continue
 | 
									continue
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			if f.isCellDug(row, col) {
 | 
								if f.isCellDug(row, col) {
 | 
				
			||||||
				rowChars[col - f.MinCol] = '#'
 | 
									rowChars[col - f.MinCol] = '#'
 | 
				
			||||||
			} else {
 | 
								} else {
 | 
				
			||||||
@ -293,34 +381,64 @@ func (f *Field) digInsides() (countInside int) {
 | 
				
			|||||||
		if row % 10000 == 0 {
 | 
							if row % 10000 == 0 {
 | 
				
			||||||
			log.Printf("processed rows %d out of %d", row, f.MaxRow)
 | 
								log.Printf("processed rows %d out of %d", row, f.MaxRow)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		thisRowBorderCols := f.BorderCellCols[row]
 | 
							specialBorders := f.BordersFromLeft[row]
 | 
				
			||||||
		slices.Sort(thisRowBorderCols)
 | 
							if len(specialBorders) == 0 {
 | 
				
			||||||
		// log.Printf("cols for row %d are %+v", row, thisRowBorderCols)
 | 
					 | 
				
			||||||
		if len(thisRowBorderCols) == 0 {
 | 
					 | 
				
			||||||
			continue
 | 
								continue
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		isInside := true
 | 
							type BorderItem struct {
 | 
				
			||||||
		prevCol := thisRowBorderCols[0]
 | 
								border BorderSymbol
 | 
				
			||||||
		for _, col := range thisRowBorderCols[1:] {
 | 
								col int
 | 
				
			||||||
			gap := (col - prevCol - 1)
 | 
							}
 | 
				
			||||||
			if gap == 0 {
 | 
							rowBorders := make([]BorderItem, 0)
 | 
				
			||||||
				prevCol = col
 | 
							for col, borderSymbol := range specialBorders {
 | 
				
			||||||
 | 
								rowBorders = append(rowBorders, BorderItem{borderSymbol, col})
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							slices.SortFunc(rowBorders, func(a BorderItem, b BorderItem) int {
 | 
				
			||||||
 | 
								return a.col - b.col
 | 
				
			||||||
 | 
							})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							// log.Printf(">>>>>>> for row %d sorted %+v", row, rowBorders)
 | 
				
			||||||
 | 
							prevBorder := rowBorders[0]
 | 
				
			||||||
 | 
							bordersCrossed := 0
 | 
				
			||||||
 | 
							if prevBorder.border == Vertical {
 | 
				
			||||||
 | 
								bordersCrossed += 1
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							for _, specialBorder := range rowBorders[1:] {
 | 
				
			||||||
 | 
								diff := specialBorder.col - prevBorder.col - 1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								if specialBorder.border == ToUp && prevBorder.border == FromUp {
 | 
				
			||||||
 | 
									bordersCrossed += 1
 | 
				
			||||||
 | 
									prevBorder = specialBorder
 | 
				
			||||||
				continue
 | 
									continue
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			// log.Printf("found gap in row %d. is inside %t. between col %d and %d of length %d",
 | 
								if specialBorder.border == ToDown && prevBorder.border == FromDown {
 | 
				
			||||||
				// row, isInside, col, prevCol, gap)
 | 
									bordersCrossed += 1
 | 
				
			||||||
			if isInside {
 | 
									prevBorder = specialBorder
 | 
				
			||||||
				for coll := prevCol+1; coll < col; coll++ {
 | 
									continue
 | 
				
			||||||
					f.Cells[Coord{Col: coll, Row: row}] = &Cell{
 | 
								}
 | 
				
			||||||
						ToBeDug: true,
 | 
								if specialBorder.border == ToUp && prevBorder.border == FromDown {
 | 
				
			||||||
					}
 | 
									prevBorder = specialBorder
 | 
				
			||||||
					
 | 
									continue
 | 
				
			||||||
				}
 | 
								}
 | 
				
			||||||
				countInside += gap
 | 
								if specialBorder.border == ToDown && prevBorder.border == FromUp {
 | 
				
			||||||
 | 
									prevBorder = specialBorder
 | 
				
			||||||
 | 
									continue
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			isInside = !isInside
 | 
								if bordersCrossed % 2 == 1 { // is in
 | 
				
			||||||
			prevCol = col
 | 
									for col := prevBorder.col+1; col < specialBorder.col; col++ {
 | 
				
			||||||
 | 
										f.Cells[Coord{Col: col, Row: row}] = &Cell{
 | 
				
			||||||
 | 
											ToBeDug: true,
 | 
				
			||||||
 | 
										}
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
									countInside += diff
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								if specialBorder.border == Vertical {
 | 
				
			||||||
 | 
									bordersCrossed += 1
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								prevBorder = specialBorder
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return
 | 
						return
 | 
				
			||||||
 | 
				
			|||||||
@ -19,9 +19,12 @@ when there's a jump - compare counts, to make decision on whether to switch 'isI
 | 
				
			|||||||
** no. just because they are long doesn't mean they won't ever get one near another
 | 
					** no. just because they are long doesn't mean they won't ever get one near another
 | 
				
			||||||
* another idea is to save | and corners, as if we're going from left to right
 | 
					* another idea is to save | and corners, as if we're going from left to right
 | 
				
			||||||
this seems reasonable.
 | 
					this seems reasonable.
 | 
				
			||||||
** TODO i guess []SpecialSymbol which has Col and Symbol
 | 
					** DONE i guess []SpecialSymbol which has Col and Symbol
 | 
				
			||||||
 | 
					** DONE no, let's make it map. yes will have to init, but yuck anyway
 | 
				
			||||||
** TODO then different logic on border building.
 | 
					** TODO then different logic on border building.
 | 
				
			||||||
if U \ D - on all but last add '|'
 | 
					if U \ D - on all but last add '|'
 | 
				
			||||||
on last - calc with the next turn, what should be saved 'as if traversing from the left'
 | 
					on last - calc with the next turn, what should be saved 'as if traversing from the left'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
for L \ R - on last - calc what the turn was
 | 
					for L \ R - on last - calc what the turn was
 | 
				
			||||||
 | 
					** TODO !! between last and first movement the corner is unknown.
 | 
				
			||||||
 | 
					so, copy the first instruction to the end?
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user