2018 Day 20 Done

* Also some cleanup on helpers.go
This commit is contained in:
Brian Buller 2018-12-20 17:17:30 -06:00
parent 184e9d7639
commit 47b656d34a
5 changed files with 177 additions and 14 deletions

157
2018/day20/day20.go Normal file
View File

@ -0,0 +1,157 @@
package main
import (
"bufio"
"fmt"
"os"
)
const (
CLEAR_SCREEN = "\033[H\033[2J"
MAX_INT = int(^uint(0) >> 1)
MIN_INT = -MAX_INT - 1
)
var input []byte
var currRoom *Room
var facility *Facility
var pathStack []Room
func main() {
input = stdinToByteSlice()
input = input[1 : len(input)-1] // Trim ^...$
part1()
part2()
}
func part1() {
facility = NewFacility()
currRoom = &Room{0, 0, 0}
for _, v := range input {
switch v {
case 'N':
facility.move(0, -1)
case 'E':
facility.move(1, 0)
case 'S':
facility.move(0, 1)
case 'W':
facility.move(-1, 0)
case '(':
pathStack = append(pathStack, *currRoom)
case ')':
currRoom, pathStack = &pathStack[len(pathStack)-1], pathStack[:len(pathStack)-1]
case '|':
currRoom = &pathStack[len(pathStack)-1]
}
}
var longest int
for _, v := range facility.rooms {
if v.dist > longest {
longest = v.dist
}
}
fmt.Println("= Part 1 =")
fmt.Println(longest)
}
func part2() {
var kilo int
for _, v := range facility.rooms {
if v.dist >= 1000 {
kilo++
}
}
fmt.Println("= Part 2 =")
fmt.Println(kilo)
}
type Facility struct {
minX, maxX int
minY, maxY int
rooms map[string]*Room
}
func NewFacility() *Facility {
f := Facility{
minX: MAX_INT,
maxX: MIN_INT,
minY: MAX_INT,
maxY: MIN_INT,
rooms: make(map[string]*Room),
}
return &f
}
func (f *Facility) key(x, y int) string {
return fmt.Sprintf("%d,%d", x, y)
}
func (f *Facility) move(xd, yd int) {
n := f.getRoom(currRoom.x+xd, currRoom.y+yd)
n.dist = min(n.dist, currRoom.dist+1)
currRoom = n
f.setRoom(n)
}
func (f *Facility) getRoom(x, y int) *Room {
if v, ok := f.rooms[f.key(x, y)]; ok {
return v
}
return &Room{x, y, MAX_INT}
}
func (f *Facility) setRoom(r *Room) {
f.minX = min(f.minX, r.x)
f.maxX = max(f.maxX, r.x)
f.minY = min(f.minY, r.y)
f.maxY = max(f.maxY, r.y)
f.rooms[r.key()] = r
}
func (f *Facility) string() string {
var ret string
for y := f.minY; y < f.maxY; y++ {
for x := f.minX; x < f.maxX; x++ {
if r, ok := f.rooms[f.key(x, y)]; !ok {
ret += " " + r.key() + " "
}
}
ret += "\n"
}
return ret
}
type Room struct {
x, y int
dist int
}
func (r *Room) key() string {
return fmt.Sprintf("%d,%d", r.x, r.y)
}
func min(i, j int) int {
if j < i {
return j
}
return i
}
func max(i, j int) int {
if j > i {
return j
}
return i
}
func stdinToByteSlice() []byte {
var ret []byte
scanner := bufio.NewScanner(os.Stdin)
for scanner.Scan() {
data := scanner.Bytes()
ret = append(input, data...)
}
return ret
}

1
2018/day20/input Normal file

File diff suppressed because one or more lines are too long

1
2018/day20/testinput Normal file
View File

@ -0,0 +1 @@
^ESSWWN(E|NNENN(EESS(WNSE|)SSS|WWWSSSSE(SW|NNNE)))$

1
2018/day20/testinput2 Normal file
View File

@ -0,0 +1 @@
^WSSEESWWWNW(S|NENNEEEENN(ESSSSW(NWSW|SSEN)|WSWWN(E|WWS(E|SS))))$

View File

@ -10,6 +10,23 @@ import (
"strings" "strings"
) )
// Some handy Constants
const (
BORDER_NS = "\u2502"
BORDER_WE = "\u2500"
BORDER_NW = "\u250C"
BORDER_NE = "\u2510"
BORDER_SW = "\u2514"
BORDER_SE = "\u2518"
FILL_CHAR = "\u2588"
CLEAR_SCREEN = "\033[H\033[2J"
MAX_INT = int(^uint(0) >> 1)
MIN_INT = -MAX_INT - 1
)
func ArgIsSet(a string) bool { func ArgIsSet(a string) bool {
for i := range os.Args { for i := range os.Args {
if os.Args[i] == a || strings.HasPrefix(os.Args[i], a+"=") { if os.Args[i] == a || strings.HasPrefix(os.Args[i], a+"=") {
@ -124,17 +141,3 @@ func stringPermHelper(str string, i int) []string {
} }
return ret return ret
} }
// 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"
)