2024 Day 6 Complete!
This commit is contained in:
148
2024/day06/main.go
Normal file
148
2024/day06/main.go
Normal file
@@ -0,0 +1,148 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
h "git.bullercodeworks.com/brian/adventofcode/helpers"
|
||||
)
|
||||
|
||||
func main() {
|
||||
inp := h.StdinToCoordMap()
|
||||
cp := inp.Copy()
|
||||
m := part1(inp)
|
||||
part2(*cp, m.FindAll('X'))
|
||||
}
|
||||
|
||||
var debug = false
|
||||
|
||||
func part1(m h.CoordByteMap) h.CoordByteMap {
|
||||
init, err := m.FindFirst('^')
|
||||
h.CheckErr(err)
|
||||
for moveGuard(m) {
|
||||
if debug {
|
||||
fmt.Println(h.CLEAR_SCREEN)
|
||||
fmt.Println(m)
|
||||
guard := m.FindAll('^', '>', 'v', '<')[0]
|
||||
fmt.Println(guard)
|
||||
time.Sleep(time.Second / 10)
|
||||
}
|
||||
}
|
||||
fmt.Println()
|
||||
fmt.Println("# Part 1")
|
||||
fmt.Printf("Guard moved into %d positions.\n", m.Count('X'))
|
||||
fmt.Println()
|
||||
m.Put(init, '^')
|
||||
return m
|
||||
}
|
||||
|
||||
func part2(clean h.CoordByteMap, p []h.Coordinate) {
|
||||
// m should have all of the 'X' spots where the guard moved in part 1
|
||||
init, err := clean.FindFirst('^')
|
||||
h.CheckErr(err)
|
||||
var obstacles []h.Coordinate
|
||||
for i := range p {
|
||||
fmt.Println(h.CLEAR_SCREEN)
|
||||
fmt.Print("Progress: ")
|
||||
h.PrintProgress(i, len(p))
|
||||
fmt.Printf(" %d/%d\n", i, len(p))
|
||||
m := *clean.Copy()
|
||||
// Try putting an obstacle at p[i]
|
||||
m.Put(p[i], 'O')
|
||||
history := make(map[h.Coordinate][]string)
|
||||
guard := m.FindAll('^', '>', 'v', '<')[0]
|
||||
tst := m.Get(guard)
|
||||
history[guard] = append(history[guard], string(tst))
|
||||
var foundLoop bool
|
||||
for moveGuard(m) && !foundLoop {
|
||||
// fmt.Print(".")
|
||||
if debug {
|
||||
fmt.Println(h.CLEAR_SCREEN)
|
||||
fmt.Println(m)
|
||||
guard := m.FindAll('^', '>', 'v', '<')[0]
|
||||
fmt.Printf("Guard: %s - Testing Obstacle: %s\n", guard, p[i])
|
||||
fmt.Println(obstacles)
|
||||
fmt.Println(history)
|
||||
time.Sleep(time.Second / 10)
|
||||
}
|
||||
guard := m.FindAll('^', '>', 'v', '<')[0]
|
||||
bt := m.Get(guard)
|
||||
// Check if we already have this position/orientation in our history
|
||||
for j := range history[guard] {
|
||||
if history[guard][j] == string(bt) {
|
||||
if !contains(obstacles, p[i]) {
|
||||
obstacles = append(obstacles, p[i])
|
||||
foundLoop = true
|
||||
if debug {
|
||||
fmt.Println("Found Loop:", string(history[guard][j]), "==", string(bt))
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
history[guard] = append(history[guard], string(bt))
|
||||
}
|
||||
m.Put(p[i], '.')
|
||||
m.Put(init, '^')
|
||||
}
|
||||
fmt.Println()
|
||||
fmt.Println("# Part 2")
|
||||
fmt.Printf("Obstacle positions to create a loop: %d\n", len(obstacles))
|
||||
// 583 is too low
|
||||
}
|
||||
|
||||
func checkForLoop(m h.CoordByteMap) {
|
||||
}
|
||||
|
||||
func contains(sl []h.Coordinate, c h.Coordinate) bool {
|
||||
for i := range sl {
|
||||
if sl[i].Equals(c) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func turn(g byte) byte {
|
||||
switch g {
|
||||
case '^':
|
||||
return '>'
|
||||
case '>':
|
||||
return 'v'
|
||||
case 'v':
|
||||
return '<'
|
||||
default:
|
||||
return '^'
|
||||
}
|
||||
}
|
||||
|
||||
func nextPos(guard h.Coordinate, m h.CoordByteMap) h.Coordinate {
|
||||
switch m.Get(guard) {
|
||||
case '>':
|
||||
return guard.East()
|
||||
case 'v':
|
||||
return guard.South()
|
||||
case '<':
|
||||
return guard.West()
|
||||
}
|
||||
return guard.North()
|
||||
}
|
||||
|
||||
func moveGuard(m h.CoordByteMap) bool {
|
||||
guard := m.FindAll('^', '>', 'v', '<')[0]
|
||||
currBt := m.Get(guard)
|
||||
turn := turn(currBt)
|
||||
next := nextPos(guard, m)
|
||||
if !m.ContainsCoord(next) {
|
||||
m.Put(guard, 'X')
|
||||
return false
|
||||
}
|
||||
tst := m.Get(next)
|
||||
if tst == '#' || tst == 'O' {
|
||||
m.Put(guard, turn)
|
||||
return moveGuard(m)
|
||||
}
|
||||
m.Put(guard, 'X')
|
||||
m.Put(next, currBt)
|
||||
return true
|
||||
}
|
||||
Reference in New Issue
Block a user