Day 17 Complete
This commit is contained in:
111
2016/day17/main.go
Normal file
111
2016/day17/main.go
Normal file
@@ -0,0 +1,111 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"crypto/md5"
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
"../../"
|
||||
)
|
||||
|
||||
var gridWidth, gridHeight int
|
||||
|
||||
func main() {
|
||||
var passcode string
|
||||
gridWidth, gridHeight = 4, 4
|
||||
|
||||
if len(os.Args) < 2 {
|
||||
printUsageAndExit()
|
||||
}
|
||||
passcode = os.Args[1]
|
||||
if len(os.Args) >= 4 {
|
||||
gridWidth = aoc.Atoi(os.Args[2])
|
||||
gridHeight = aoc.Atoi(os.Args[3])
|
||||
}
|
||||
foundPaths := findPaths("", passcode)
|
||||
if len(foundPaths) == 0 {
|
||||
fmt.Println("Couldn't find a valid path!")
|
||||
os.Exit(1)
|
||||
}
|
||||
shortestPath := foundPaths[0]
|
||||
longestPath := foundPaths[0]
|
||||
for i := range foundPaths {
|
||||
if len(foundPaths[i]) < len(shortestPath) {
|
||||
shortestPath = foundPaths[i]
|
||||
}
|
||||
if len(foundPaths[i]) > len(longestPath) {
|
||||
longestPath = foundPaths[i]
|
||||
}
|
||||
}
|
||||
fmt.Println("Shortest Path:", shortestPath)
|
||||
fmt.Println("Longest Path Length:", len(longestPath))
|
||||
}
|
||||
|
||||
func findPaths(path, passcode string) []string {
|
||||
var ret []string
|
||||
cX, cY := currPos(path)
|
||||
if cY == gridHeight-1 && cX == gridWidth-1 {
|
||||
return []string{path}
|
||||
}
|
||||
if cY > 0 && doorIsOpen(path, passcode, 'U') {
|
||||
ret = append(ret, findPaths(path+"U", passcode)...)
|
||||
}
|
||||
if cY < (gridHeight-1) && doorIsOpen(path, passcode, 'D') {
|
||||
ret = append(ret, findPaths(path+"D", passcode)...)
|
||||
}
|
||||
if cX > 0 && doorIsOpen(path, passcode, 'L') {
|
||||
ret = append(ret, findPaths(path+"L", passcode)...)
|
||||
}
|
||||
if cX < (gridWidth-1) && doorIsOpen(path, passcode, 'R') {
|
||||
ret = append(ret, findPaths(path+"R", passcode)...)
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
// We cache the last hash calculated
|
||||
// It should speed things up a little
|
||||
var lastHashInput string
|
||||
var lastHash string
|
||||
|
||||
func doorIsOpen(path, passcode string, dir rune) bool {
|
||||
if lastHashInput != passcode+path {
|
||||
lastHashInput = passcode + path
|
||||
lastHash = fmt.Sprintf("%x", md5.Sum([]byte(lastHashInput)))
|
||||
}
|
||||
switch dir {
|
||||
case 'U':
|
||||
return lastHash[0] >= 'b' && lastHash[0] <= 'f'
|
||||
case 'D':
|
||||
return lastHash[1] >= 'b' && lastHash[1] <= 'f'
|
||||
case 'L':
|
||||
return lastHash[2] >= 'b' && lastHash[2] <= 'f'
|
||||
case 'R':
|
||||
return lastHash[3] >= 'b' && lastHash[3] <= 'f'
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func currPos(path string) (int, int) {
|
||||
var cX, cY int
|
||||
for i := range path {
|
||||
switch path[i] {
|
||||
case 'U':
|
||||
cY--
|
||||
case 'D':
|
||||
cY++
|
||||
case 'L':
|
||||
cX--
|
||||
case 'R':
|
||||
cX++
|
||||
}
|
||||
}
|
||||
return cX, cY
|
||||
}
|
||||
|
||||
func PrintState(path, passcode string) {
|
||||
}
|
||||
|
||||
func printUsageAndExit() {
|
||||
fmt.Println("Usage: ./day17 <passcode> <gridWidth> <gridHeight>")
|
||||
os.Exit(0)
|
||||
}
|
||||
Reference in New Issue
Block a user