Skip to content
This repository was archived by the owner on Dec 28, 2024. It is now read-only.

Commit 1043261

Browse files
committed
Add solution for day 6 part 2
1 parent eaaa49e commit 1043261

File tree

2 files changed

+75
-22
lines changed

2 files changed

+75
-22
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ automatically rebuilt and redeployed ever time the `common` module or their own
5050
| 03 | ⭐ ⭐ | 16 | |
5151
| 04 | ⭐ ⭐ | 17 | |
5252
| 05 | ⭐ ⭐ | 18 | |
53-
| 06 | | 19 | |
53+
| 06 | | 19 | |
5454
| 07 | | 20 | |
5555
| 08 | | 21 | |
5656
| 09 | | 22 | |

solutions/day06/main.go

Lines changed: 74 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -25,14 +25,14 @@ var directions = []util.Direction{
2525
}
2626

2727
type parsedInput struct {
28-
Guard Coordinate
29-
Direction direction
30-
ObstacleMap BoolMatrix
31-
VisitedMap tVisitedMap
28+
Guard Coordinate
29+
Direction direction
30+
ObstacleMatrix BoolMatrix
31+
VisitedMap tVisitedMap
3232
}
3333

3434
func main() {
35-
common.Setup(6, part1, nil)
35+
common.Setup(6, part1, part2)
3636
}
3737

3838
func part1(
@@ -55,6 +55,55 @@ func part1(
5555
return fmt.Sprintf("Visited spots in the Matrix: %d", count)
5656
}
5757

58+
func part2(
59+
input string,
60+
) string {
61+
// Solve part 1 first to know where to place obstacles
62+
original, err := parseInput(input)
63+
if err != nil {
64+
return fmt.Sprintf("Failed to parse input: %v", err)
65+
}
66+
67+
originalX := original.Guard.X
68+
originalY := original.Guard.Y
69+
for original.move() {
70+
// Do nothing, move() does all the work
71+
}
72+
73+
// Then loop through all positions the guard will visit and place an obstacle
74+
count := 0
75+
attempts := 0
76+
//for x := 0; x <= original.ObstacleMatrix.MaxX; x++ {
77+
for x, yMap := range original.VisitedMap {
78+
//for y := 0; y <= original.ObstacleMatrix.MaxY; y++ {
79+
for y := range yMap {
80+
if y == originalY && x == originalX {
81+
continue
82+
}
83+
attempts++
84+
85+
// Reset the map with the new obstacle
86+
original.Guard = Coordinate{X: originalX, Y: originalY}
87+
original.Direction = 0
88+
original.VisitedMap = make(tVisitedMap)
89+
_ = original.ObstacleMatrix.Set(x, y, true)
90+
91+
// Run this variant
92+
for original.move() {
93+
// Do nothing, move() does all the work
94+
}
95+
_ = original.ObstacleMatrix.Set(x, y, false)
96+
97+
// If the guard is still in the matrix, he's in a loop
98+
if original.guardIsInMatrix() {
99+
count += 1
100+
}
101+
}
102+
}
103+
104+
return fmt.Sprintf("%d of the available %d positions make him loopy!", count, attempts)
105+
}
106+
58107
func parseInput(
59108
input string,
60109
) (parsedInput, error) {
@@ -92,47 +141,51 @@ func parseInput(
92141
}
93142

94143
out := parsedInput{
95-
Guard: guard,
96-
Direction: 0, // This means north
97-
ObstacleMap: obstacles,
98-
VisitedMap: visitedMap,
144+
Guard: guard,
145+
Direction: 0, // This means north
146+
ObstacleMatrix: obstacles,
147+
VisitedMap: visitedMap,
99148
}
100-
out.markVisited(guard)
149+
out.checkIfVisitedAndMark(guard)
101150

102151
return out, nil
103152
}
104153

105-
// Move and return a boolean indicating whether the guard is inside the matrix or not
106-
func (
107-
p *parsedInput,
108-
) move() bool {
154+
// Move and return a boolean indicating whether the guard is stuck in a loop or inside the matrix
155+
// True means he's stuck or out, false means he's inside on a non-visited spot.
156+
func (p *parsedInput) move() bool {
109157
newPos := getNewPosition(p.Guard, p.Direction)
110-
isBlocked, err := p.ObstacleMap.Get(newPos.X, newPos.Y)
158+
isBlocked, err := p.ObstacleMatrix.Get(newPos.X, newPos.Y)
111159
if err != nil {
160+
p.Guard = newPos
112161
return false
113162
} else if isBlocked {
114163
p.rotate()
115-
newPos = getNewPosition(p.Guard, p.Direction)
164+
return !p.checkIfVisitedAndMark(p.Guard)
116165
}
117166
p.Guard = newPos
118-
if !p.ObstacleMap.IsInMatrix(p.Guard.X, p.Guard.Y) {
167+
168+
if p.checkIfVisitedAndMark(newPos) {
119169
return false
120170
}
121171

122-
p.markVisited(newPos)
123172
return true
124173
}
125174

126-
func (p *parsedInput) markVisited(
127-
c Coordinate,
128-
) {
175+
func (p *parsedInput) guardIsInMatrix() bool {
176+
return p.ObstacleMatrix.IsInMatrix(p.Guard.X, p.Guard.Y)
177+
}
178+
179+
func (p *parsedInput) checkIfVisitedAndMark(c Coordinate) bool {
129180
if p.VisitedMap[c.X] == nil {
130181
p.VisitedMap[c.X] = make(map[int]map[int]bool)
131182
}
132183
if p.VisitedMap[c.X][c.Y] == nil {
133184
p.VisitedMap[c.X][c.Y] = make(map[int]bool)
134185
}
186+
old := p.VisitedMap[c.X][c.Y][p.Direction]
135187
p.VisitedMap[c.X][c.Y][p.Direction] = true
188+
return old
136189
}
137190

138191
func (p *parsedInput) rotate() {

0 commit comments

Comments
 (0)