Browse Source

Works for sample, not for input

Piotr Czajkowski 1 year ago
parent
commit
7d81fb8994
1 changed files with 62 additions and 45 deletions
  1. 62 45
      16/code.go

+ 62 - 45
16/code.go

@@ -44,76 +44,95 @@ const (
 	West
 )
 
-type Beam struct {
+type Point struct {
 	y, x      int
 	direction int
 }
 
-func (b *Beam) canContinue(board [][]byte, height int, width int) []Beam {
+type Beam struct {
+	pos     Point
+	wasHere map[Point]bool
+}
+
+func (b *Beam) canContinue(board [][]byte, height int, width int, pastBeams map[Point]bool) []Beam {
 	var beams []Beam
-	if b.x < 0 || b.x >= width || b.y < 0 || b.y >= height {
+	if b.wasHere[b.pos] || b.pos.x < 0 || b.pos.x >= width || b.pos.y < 0 || b.pos.y >= height {
 		return beams
 	}
 
-	switch board[b.y][b.x] {
+	switch board[b.pos.y][b.pos.x] {
 	case Horizontal:
-		if b.direction != East && b.direction != West {
-			b.direction = East
-			beams = append(beams, *b)
-			b.direction = West
-			beams = append(beams, *b)
+		if b.pos.direction != East && b.pos.direction != West {
+			b.pos.direction = East
+			if !pastBeams[b.pos] {
+				pastBeams[b.pos] = true
+				beams = append(beams, *b)
+			}
+			b.pos.direction = West
+			if !pastBeams[b.pos] {
+				pastBeams[b.pos] = true
+				beams = append(beams, *b)
+			}
 
 			return beams
 		}
 	case Vertical:
-		if b.direction != South && b.direction != North {
-			b.direction = South
-			beams = append(beams, *b)
-			b.direction = North
-			beams = append(beams, *b)
+		if b.pos.direction != South && b.pos.direction != North {
+			b.pos.direction = South
+			if !pastBeams[b.pos] {
+				pastBeams[b.pos] = true
+				beams = append(beams, *b)
+			}
+			b.pos.direction = North
+			if !pastBeams[b.pos] {
+				pastBeams[b.pos] = true
+				beams = append(beams, *b)
+			}
 
 			return beams
 		}
 	case Slash:
-		switch b.direction {
+		switch b.pos.direction {
 		case North:
-			b.direction = East
+			b.pos.direction = East
 		case South:
-			b.direction = West
+			b.pos.direction = West
 		case East:
-			b.direction = North
+			b.pos.direction = North
 		case West:
-			b.direction = South
+			b.pos.direction = South
 		}
 	case Backslash:
-		switch b.direction {
+		switch b.pos.direction {
 		case North:
-			b.direction = West
+			b.pos.direction = West
 		case South:
-			b.direction = East
+			b.pos.direction = East
 		case East:
-			b.direction = South
+			b.pos.direction = South
 		case West:
-			b.direction = North
+			b.pos.direction = North
 		}
 	}
 
 	return append(beams, *b)
 }
 
-func (b *Beam) move(board [][]byte, height int, width int) []Beam {
-	switch b.direction {
+func (b *Beam) move(board [][]byte, height int, width int, pastBeams map[Point]bool) []Beam {
+	b.wasHere[b.pos] = true
+
+	switch b.pos.direction {
 	case North:
-		b.y--
+		b.pos.y--
 	case South:
-		b.y++
+		b.pos.y++
 	case East:
-		b.x++
+		b.pos.x++
 	case West:
-		b.x--
+		b.pos.x--
 	}
 
-	return b.canContinue(board, height, width)
+	return b.canContinue(board, height, width, pastBeams)
 }
 
 func emptyBoard(height int, width int) [][]byte {
@@ -141,31 +160,29 @@ func count(board [][]byte) int {
 func part1(board [][]byte) int {
 	height := len(board)
 	width := len(board[0])
-	var result int
 	trackBoard := emptyBoard(height, width)
-	beams := []Beam{Beam{y: 0, x: 0, direction: East}}
+	beams := []Beam{Beam{pos: Point{y: 0, x: 0, direction: East}, wasHere: make(map[Point]bool)}}
+	pastBeams := make(map[Point]bool)
+	pastBeams[beams[0].pos] = true
 
 	for {
-		change := false
+		if len(beams) == 0 {
+			break
+		}
+
 		var newBeams []Beam
 		for i := range beams {
-			if trackBoard[beams[i].y][beams[i].x] != Mark {
-				trackBoard[beams[i].y][beams[i].x] = Mark
-				change = true
+			if trackBoard[beams[i].pos.y][beams[i].pos.x] != Mark {
+				trackBoard[beams[i].pos.y][beams[i].pos.x] = Mark
 			}
 
-			newBeams = append(newBeams, beams[i].move(board, height, width)...)
-		}
-
-		if !change {
-			break
+			newBeams = append(newBeams, beams[i].move(board, height, width, pastBeams)...)
 		}
 
 		beams = newBeams
 	}
 
-	fmt.Println(count(trackBoard), trackBoard)
-	return result
+	return count(trackBoard)
 }
 
 func main() {
@@ -181,5 +198,5 @@ func main() {
 	}
 
 	board := readInput(file)
-	fmt.Println(part1(board))
+	fmt.Println("Part1:", part1(board))
 }