Day 18 Complete

This commit is contained in:
Brian Buller 2016-12-18 09:32:37 -06:00
parent 5ccafb37c4
commit 708d883e94
7 changed files with 228 additions and 7 deletions

BIN
2016/day17-add/day17-add Executable file

Binary file not shown.

1
2016/day17-add/input Normal file
View File

@ -0,0 +1 @@
pvhmgsws

165
2016/day17-add/main.go Normal file
View File

@ -0,0 +1,165 @@
package main
import (
"crypto/md5"
"fmt"
"os"
termbox "github.com/nsf/termbox-go"
"../../"
)
var gridWidth, gridHeight int
var path string
func main() {
// TODO: Random seed
passcode := "pvhmgsws"
gridWidth, gridHeight = 4, 4
if len(os.Args) >= 3 {
gridWidth = aoc.Atoi(os.Args[1])
gridHeight = aoc.Atoi(os.Args[2])
}
run := true
err := termbox.Init()
if err != nil {
panic(err)
}
defer termbox.Close()
var e termbox.Event
for run {
PrintState("", passcode)
e = termbox.PollEvent()
if e.Type == termbox.EventKey {
if e.Key == termbox.KeyCtrlC {
run = false
}
}
}
}
// 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 'N':
return lastHash[0] >= 'b' && lastHash[0] <= 'f'
case 'E':
return lastHash[3] >= 'b' && lastHash[3] <= 'f'
case 'S':
return lastHash[1] >= 'b' && lastHash[1] <= 'f'
case 'W':
return lastHash[2] >= 'b' && lastHash[2] <= '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) {
posX, posY := currPos(path)
for y := 0; y < gridHeight; y++ {
for x := 0; x < gridWidth; x++ {
fmt.Print(aoc.BorderNW)
if posX == x && posY == y && doorIsOpen(path, passcode, 'N') {
// Current Pos w/ open door
fmt.Print(aoc.BorderSE)
fmt.Print(aoc.BorderSW)
} else if y == posY+1 && x == posX && doorIsOpen(path, passcode, 'S') {
// Room below, w/ open door
fmt.Print(aoc.BorderNE)
fmt.Print(aoc.BorderNW)
} else {
// All other cases
fmt.Print(aoc.BorderWE)
fmt.Print(aoc.BorderWE)
}
fmt.Print(aoc.BorderNE)
}
fmt.Println()
for x := 0; x < gridWidth; x++ {
if posX == x && posY == y && doorIsOpen(path, passcode, 'W') {
fmt.Print(aoc.BorderSE)
} else {
fmt.Print(aoc.BorderNS)
}
if posX == x && posY == y {
fmt.Print(aoc.BorderNW)
fmt.Print(aoc.BorderNE)
} else {
fmt.Print(" ")
fmt.Print(" ")
}
if posX == x && posY == y && doorIsOpen(path, passcode, 'E') {
fmt.Print(aoc.BorderSW)
} else {
fmt.Print(aoc.BorderNS)
}
}
fmt.Println()
for x := 0; x < gridWidth; x++ {
if posX == x && posY == y && doorIsOpen(path, passcode, 'W') {
fmt.Print(aoc.BorderNE)
} else {
fmt.Print(aoc.BorderNS)
}
if posX == x && posY == y {
fmt.Print(aoc.BorderSW)
fmt.Print(aoc.BorderSE)
} else {
fmt.Print(" ")
fmt.Print(" ")
}
if posX == x && posY == y && doorIsOpen(path, passcode, 'E') {
fmt.Print(aoc.BorderNW)
} else {
fmt.Print(aoc.BorderNS)
}
}
fmt.Println()
for x := 0; x < gridWidth; x++ {
fmt.Print(aoc.BorderSW)
if posX == x && posY == y && doorIsOpen(path, passcode, 'S') {
fmt.Print(aoc.BorderNE)
fmt.Print(aoc.BorderNW)
} else {
fmt.Print(aoc.BorderWE)
fmt.Print(aoc.BorderWE)
}
fmt.Print(aoc.BorderSE)
}
fmt.Println()
}
}
func ClearScreen() {
fmt.Print(aoc.ClearScreen)
}
func printUsageAndExit() {
fmt.Println("Usage: ./day17 <passcode> <gridWidth> <gridHeight>")
os.Exit(0)
}

View File

@ -102,9 +102,6 @@ func currPos(path string) (int, int) {
return cX, cY
}
func PrintState(path, passcode string) {
}
func printUsageAndExit() {
fmt.Println("Usage: ./day17 <passcode> <gridWidth> <gridHeight>")
os.Exit(0)

1
2016/day18/input Normal file
View File

@ -0,0 +1 @@
^.^^^..^^...^.^..^^^^^.....^...^^^..^^^^.^^.^^^^^^^^.^^.^^^^...^^...^^^^.^.^..^^..^..^.^^.^.^.......

43
2016/day18/main.go Normal file
View File

@ -0,0 +1,43 @@
package main
import (
"bytes"
"fmt"
"os"
"../../"
)
func main() {
if len(os.Args) < 3 {
fmt.Println("Usage: ./day18 <filename> <numrows>")
}
input := aoc.FileToBytes(os.Args[1])
numRows := aoc.Atoi(os.Args[2])
room := [][]byte{input}
for row := 1; row < numRows; row++ {
room = append(room, []byte{})
for tile := 0; tile < len(room[0])-1; tile++ {
var l, r byte
switch tile {
case 0:
l, r = '.', room[row-1][tile+1]
case len(input) - 2:
l, r = room[row-1][tile-1], '.'
default:
l, r = room[row-1][tile-1], room[row-1][tile+1]
}
if l != r && (l == '^' || r == '^') {
room[row] = append(room[row], '^')
} else {
room[row] = append(room[row], '.')
}
}
}
var safeCount int
for i := range room {
safeCount += bytes.Count(room[i], []byte{'.'})
}
fmt.Println(safeCount, "safe tiles")
}

View File

@ -41,6 +41,10 @@ func StdinToString() string {
}
func FileToString(fn string) string {
return string(FileToBytes(fn))
}
func FileToBytes(fn string) []byte {
var c []byte
var err error
c, err = ioutil.ReadFile(fn)
@ -48,9 +52,19 @@ func FileToString(fn string) string {
fmt.Println("Unable to read file: " + fn)
os.Exit(1)
}
return string(c)
return c
}
func ClearScreen() {
fmt.Print("\033[H\033[2J")
}
// Some character code stuff for prettier output
const (
BorderNS = "\u2502"
BorderWE = "\u2500"
BorderNW = "\u250C"
BorderNE = "\u2510"
BorderSW = "\u2514"
BorderSE = "\u2518"
FillChar = "\u2588"
ClearScreen = "\033[H\033[2J"
)