2018 Day 20 Done
* Also some cleanup on helpers.go
This commit is contained in:
parent
184e9d7639
commit
47b656d34a
157
2018/day20/day20.go
Normal file
157
2018/day20/day20.go
Normal 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
1
2018/day20/input
Normal file
File diff suppressed because one or more lines are too long
1
2018/day20/testinput
Normal file
1
2018/day20/testinput
Normal file
@ -0,0 +1 @@
|
||||
^ESSWWN(E|NNENN(EESS(WNSE|)SSS|WWWSSSSE(SW|NNNE)))$
|
1
2018/day20/testinput2
Normal file
1
2018/day20/testinput2
Normal file
@ -0,0 +1 @@
|
||||
^WSSEESWWWNW(S|NENNEEEENN(ESSSSW(NWSW|SSEN)|WSWWN(E|WWS(E|SS))))$
|
31
helpers.go
31
helpers.go
@ -10,6 +10,23 @@ import (
|
||||
"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 {
|
||||
for i := range os.Args {
|
||||
if os.Args[i] == a || strings.HasPrefix(os.Args[i], a+"=") {
|
||||
@ -124,17 +141,3 @@ func stringPermHelper(str string, i int) []string {
|
||||
}
|
||||
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"
|
||||
)
|
||||
|
Loading…
Reference in New Issue
Block a user