Trying to finish up 2019

This commit is contained in:
Brian Buller 2020-11-03 05:02:36 -06:00
parent ac0772f966
commit 4f1712ceb0
13 changed files with 1044 additions and 44 deletions

View File

@ -1,23 +1,127 @@
package main
import (
"errors"
"fmt"
helpers "git.bullercodeworks.com/brian/adventofcode/helpers"
)
var maxX, maxY int
var vault map[helpers.Coordinate]byte
var keys map[helpers.Coordinate]byte
var doors map[helpers.Coordinate]byte
func main() {
file := "input"
if helpers.GetArgNumber(1) != "" {
file = helpers.GetArgNumber(1)
}
v := NewVault(file)
v.Print()
part1(v)
}
var keylist int
var allNodes map[string]*Node
func part1(v *Vault) {
keylist = v.keylist
allNodes = make(map[string]*Node)
for k, v := range v.vault {
if v {
x, y, z := unc(k)
n := Node{
X: x,
Y: y,
Z: z,
steps: helpers.MAX_INT,
}
allNodes[c([]int{x, y})] = &n
}
}
for _, v := range allNodes {
n, ok := allNodes[c([]int{v.X, v.Y + 1})]
if ok {
v.N = n
}
e, ok := allNodes[c([]int{v.X + 1, v.Y})]
if ok {
v.E = e
}
s, ok := allNodes[c([]int{v.X, v.Y - 1})]
if ok {
v.S = s
}
w, ok := allNodes[c([]int{v.X - 1, v.Y})]
if ok {
v.W = w
}
}
start := allNodes[c([]int{v.start.X, v.start.Y})]
start.steps = 0
ProcessNode(start, 0, 0)
}
type Node struct {
X, Y, Z int
N, E, S, W *Node
steps int
visited bool
}
func ProcessNode(n *Node, steps, keys int) {
if n.Z&keylist == keylist {
fmt.Println("Steps to all Keys:", steps)
return
}
for _, neighbor := range []*Node{n.N, n.E, n.S, n.W} {
if neighbor == nil {
continue
}
wrk, ok := allNodes[c([]int{neighbor.X, neighbor.Y})]
if ok {
if n.steps+1 < wrk.steps {
wrk.steps = n.steps + 1
if !wrk.visited {
ProcessNode(wrk, n.steps+1, keys)
}
}
}
}
}
type state struct {
X, Y int
keys int
steps int
}
func FindPath(vault map[string]bool, doors, keys map[string]int, start helpers.Coordinate, keylist, currkeys int) int {
queue := []state{state{X: start.X, Y: start.Y, keys: currkeys}}
visited := make(map[string]bool)
var st state
for {
st, queue = queue[0], queue[1:]
fmt.Println(st.keys&keylist, keylist)
if st.keys&keylist == keylist {
return st.steps
}
visited[c([]int{st.X, st.Y, st.keys})] = true
for _, v := range []*helpers.Coordinate{
start.GetNorthCoord(), start.GetEastCoord(),
start.GetSouthCoord(), start.GetWestCoord(),
} {
wrk := helpers.NewCoordinate3d(v.X, v.Y, st.keys)
if !vault[helpers.NewCoordinate(wrk.X, wrk.Y).String()] || visited[wrk.String()] {
continue // Already been here, or can't be here
}
door, ok := doors[helpers.NewCoordinate(wrk.X, wrk.Y).String()]
if ok && wrk.Z&door != door {
fmt.Println("Hit door")
continue // Space exists, but we can't open the door
}
key, ok := keys[helpers.NewCoordinate(wrk.X, wrk.Y).String()]
if ok {
fmt.Println("Getting Key")
wrk.Z |= key // Pick up the key
}
queue = append(queue, state{X: wrk.X, Y: wrk.Y, keys: wrk.Z, steps: st.steps + 1})
}
}
}
func isDoor(b byte) bool {
@ -34,3 +138,33 @@ func keyToDoor(b byte) byte {
func doorToKey(b byte) byte {
return (b - 'A') + 'a'
}
func keyInt(b byte) int {
return 1 << (b - 'a')
}
func doorInt(b byte) int {
return 1 << (b - 'A')
}
func c(vals []int) string {
if len(vals) == 2 {
return fmt.Sprintf("[%d, %d]", vals[0], vals[1])
} else if len(vals) == 3 {
return fmt.Sprintf("[%d, %d, %d]", vals[0], vals[1], vals[2])
}
return ""
}
func unc(c string) (int, int, int) {
var x, y, z int
_, err := fmt.Sscanf(c, "[%d, %d, %d]", &x, &y, &z)
if err == nil {
return x, y, z
}
_, err = fmt.Sscanf(c, "[%d, %d]", &x, &y)
if err != nil {
panic(err)
}
return x, y, 0
}

View File

@ -2,7 +2,6 @@ package main
import (
"bytes"
"errors"
"fmt"
helpers "git.bullercodeworks.com/brian/adventofcode/helpers"
@ -10,9 +9,11 @@ import (
type Vault struct {
maxX, maxY int
vault map[helpers.Coordinate]byte
keys map[helpers.Coordinate]byte
doors map[helpers.Coordinate]byte
start helpers.Coordinate
vault map[string]bool
keys map[string]int
doors map[string]int
keylist int
}
func NewVault(file string) *Vault {
@ -20,55 +21,41 @@ func NewVault(file string) *Vault {
wrk := bytes.Split(inp, []byte{'\n'})
v := Vault{
vault: make(map[helpers.Coordinate]byte),
keys: make(map[helpers.Coordinate]byte),
doors: make(map[helpers.Coordinate]byte),
vault: make(map[string]bool),
keys: make(map[string]int),
doors: make(map[string]int),
}
v.maxY = len(wrk)
v.maxX = len(wrk[0])
for y, yv := range wrk {
for x, xv := range yv {
v.vault[*helpers.NewCoordinate(x, y)] = xv
if xv == '@' {
v.start = *helpers.NewCoordinate(x, y)
xv = '.'
}
v.vault[helpers.NewCoordinate(x, y).String()] = (xv != '#')
if isKey(xv) {
v.keys[*helpers.NewCoordinate(x, y)] = xv
k := keyInt(xv)
v.keys[helpers.NewCoordinate(x, y).String()] = k
v.keylist |= k
} else if isDoor(xv) {
v.doors[*helpers.NewCoordinate(x, y)] = xv
d := doorInt(xv)
v.doors[helpers.NewCoordinate(x, y).String()] = d
v.keylist |= d
}
}
}
return &v
}
func (v *Vault) findKey(door byte) (helpers.Coordinate, error) {
var r helpers.Coordinate
if !isDoor(door) {
return r, errors.New("Invalid Door")
}
for k := range v.keys {
if v.keys[k] == doorToKey(door) {
return k, nil
}
}
return r, errors.New("No key for that door")
}
func (v *Vault) findDoor(key byte) (helpers.Coordinate, error) {
var r helpers.Coordinate
if !isKey(key) {
return r, errors.New("Invalid Key")
}
for k := range v.doors {
if v.doors[k] == keyToDoor(key) {
return k, nil
}
}
return r, errors.New("No door for that key")
}
func (v *Vault) Print() {
for y := 0; y < v.maxY; y++ {
for x := 0; x < v.maxX; x++ {
fmt.Print(string(v.vault[*helpers.NewCoordinate(x, y)]))
if v.vault[helpers.NewCoordinate(x, y).String()] {
fmt.Print(".")
} else {
fmt.Print("#")
}
}
fmt.Println()
}

125
2019/day20/input Normal file
View File

@ -0,0 +1,125 @@
X H D Z O K W
N O W Z S L F
###################################.#######.###########.###.#.#######.###.#######################################
#.....#.........................#.....#.#...#...........#.#.....#.......#...............................#.....#.#
###.#####.#.#####.#######.###.#####.###.#.#######.#####.#.#####.#######.###.###.###.###.#.#.###.#######.###.###.#
#.#...#...#.#.#.....#...#.#.#.#.......#...#.#.#.....#.#.#.....#...#.....#.#...#...#...#.#.#.#.......#...#.....#.#
#.#.#########.#########.###.#.###.#####.#.#.#.#.###.#.#.###.#.#.#.###.###.#####.###.#####.#####.###########.###.#
#.....#.#.....#.........#...........#.#.#.....#.#.#.#...#...#...#.#.......#.#.....#.#.#.#...#...#.#.#...#...#.#.#
#.#####.#####.###.#####.###.###.#.###.#####.#####.#.###.###.#########.#.###.###.#####.#.#########.#.#.###.###.#.#
#.....#...#.#...#...#.......#.#.#.......#.#.#.#.....#.#.#.........#...#.#.#...#.....#.#...#.#...#.#.#.....#.#...#
###.#####.#.###.#######.###.#.#######.###.#.#.###.###.###.#####.#####.#.#.#.#.#.###.#.#.###.###.#.#.###.###.#.###
#.#.....#.#...#...#.#.#.#.#.#.#.......#.......#.........#.#...#.#.....#.#...#.#.#.........#.#.#...........#...#.#
#.#.#####.###.#.###.#.###.###.###.#.#.#.###.#####.###########.#.###.###.#.###.#.###.#.#.###.#.#.###.###.#####.#.#
#.......#.#.#.#...#.#...#.........#.#.#.#.....#.......#.#.#...#...#.#...#.#.....#.#.#.#...........#...#...#...#.#
###.#.###.#.#.#.#.#.###.#########.###.#####.#####.#####.#.###.#.#######.#.#.#.###.#####.###.#.###############.#.#
#.#.#.#.......#.#.#...#.....#...#...#.#...#...#.....#.#...........#.....#.#.#.....#.#...#.#.#.#.#.....#.#...#...#
#.#.#########.###.#.#####.#####.#.#######.#.#.###.###.#######.#.#######.#.###.#####.###.#.#####.#.#.#.#.###.#.###
#...#...#.....................#.#...#.#.#...#.#...#...#.......#.#...#...#...#.....#...............#.#...#.....#.#
#.#.#.###.#.###.###.#####.#.#.#.#.###.#.#.#######.###.#####.###.###.###.#.###.###########.#.###.#########.###.#.#
#.#.#...#.#.#.#.#.....#...#.#.........#.#.#.#.#...#.....#.....#...#...#.#...#.#.....#...#.#.#.#.....#.#...#...#.#
#.###.#######.#####.#.#.#.###.#######.#.#.#.#.###.###.#.#.#####.###.#.#.###.###.#.#####.#####.#######.#######.#.#
#.....#...#.#...#.#.#.#.#.#...#.#.....#.#.#.#...#.....#.#.#.#.....#.#...#...#.#.#.#.....#...#.........#.......#.#
#.#######.#.###.#.###.#######.#.#.#####.#.#.#.#####.#######.#.#.###.#.#.#.###.#.#####.#.#.#########.#####.###.#.#
#.......#.....#...#...#.......#.........#...#...#.#.....#.....#.#...#.#.#.....#...#...#.#.........#...#.#.#...#.#
#.#########.###.#.#######.#########.#.#####.#.#.#.#####.#.#####.#.###########.#.###.#####.#.#######.#.#.#####.#.#
#.#...#.#.#...#.#.......#...#.#.#...#...#.#...#...#.....#...#.#.#...#.....#.#...#.........#...#.#...#...#.#.#...#
#.#.###.#.#.#######.###.#####.#.#######.#.#####.#####.#.###.#.###.#####.###.#.#.#.#.###.#.#####.###.#####.#.###.#
#...#.#.#...#.#...#.#.#.#.#...#.#.#.#.......#...#.#.#.#.#...#...#.......#.....#...#...#.#.#.....#.....#.#...#...#
#.###.#.#.#.#.###.###.#.#.###.#.#.#.###.###.#.#.#.#.###.#.###.###.#####.#######.###########.#.#####.###.###.###.#
#.#.#...#.#.....#...#.#.#.......#.......#.#.#.#.#.......#...#.#.....#.....#...#.........#.#.#.#.#.#.#.#.#.......#
#.#.###.###.#######.#.#.#####.###.#####.#.###.###.#.#.#####.#.###.#.#.#.#####.#.#########.###.#.#.#.#.#.###.#####
#.#.#.#.........#.........#.#.........#...#.....#.#.#.#.........#.#.#.#.#.......#...#...#.#.....#.#.#...#.......#
#.#.#.#####.###########.#.#.#.#######.#####.#####.###########.#######.###.#########.###.#.###.###.#.#.#.###.#####
#.....#...#.#.....#.#.#.#.#.#.# S K H R I H #.#.......#.#.....#.#.#.....#.#
#####.###.#.#####.#.#.#.###.### U A W P O C #.###.#####.###.#.###.###.###.#
#.#.#...#.....#.#...#...#.#...# #.....#...#...#.#.#.#...#...#.#
#.#.#.#####.###.###.###.#.#.### ###.#####.#.###.###.###.#.###.#
#.#...#...#.#...............#.# NZ..............#.............#.#
#.#.#####.#.###.#######.###.#.# #.###.#####.###.###.#.###.###.#
KA....#.#.......#.#.......#.....# #.#.#.#.........#.#.#...#.....#
#.###.#####.#########.#######.# ###.#####.#.###.#.#.#########.#
#.......#...#.#.#.#.#.....#....DA #...#.#.#.#.#.....#.#.#...#.#..HC
###.###.#.#.#.#.#.#.#####.###.# #.#.#.#.#########.#.#.#.###.###
#...#.....#...............#...# #.#.......#.#.#.#.#.#..........PZ
#.#####################.#.#.#.# #####.#.###.#.#.#####.#.###.#.#
#.#.......#.........#.#.#.#.#.# #.#...#...............#...#.#.#
###.###.#.#.#######.#.######### #.###.#####.###.#.#########.###
RO....#.#.#...#.#.#.....#.#.....# #...#...#.....#.#.#...#.#.#...#
###.#.###.###.#.###.#.#.###.#.# ###.#.###########.#.###.#.#####
#.....#.#.#.#.#.#.#.#.....#.#.# XN......#.#.#...#.......#...#...#
#######.###.#.#.#.###.###.#.#.# #####.#.#.###.#.###.###.#.#.###
#...#.......#...#...#.#.....#..WF TZ....#.#.......#.#...#...#.#.#.#
###.###.#####.#####.########### ###.###.#.#.#####.#######.#.#.#
TZ....#...#.....................# #.......#.#.#.#.....#...#.#.#..YK
###.#.#.#.#######.###.#####.#.# ###.#.###.###.#######.###.#.#.#
#...#.#.#.....#...#.#.#...#.#.# #...#.#...#.......#.#...#.....#
###.#.#.###.#######.###.#####.# #########.#.#.#####.#.###.###.#
#.#...#.......#.....#.#...#....QN #...#.#.....#.............#...#
#.###############.###.#.#####.# ###.#.###.#.###.#.#.#.#.#######
#...#.....#.#.......#...#.....# #.#.....#.#.#.#.#.#.#.#.#...#.#
#.###.#.#.#.#.#####.#.#.#####.# #.###.#######.###########.#.#.#
#.#.#.#.#...#...#...#.#...#.#.# #.#.......#.#.....#.....#.#....IO
#.#.#.#####.#.###.###.###.#.### #.###.###.#.#.#########.#.###.#
#.......#.......#.#.....#.....# JZ......#.........#.#.#.....#...#
#.###.#####.#####.#####.#.##### #########.###.###.#.###.#####.#
DQ....#...#.....#.........#......JO #...#.#.#.#.................#.#
#.###.#####.################### ###.#.#.#######.#######.#######
#...#.#...#.#.....#.#...#.....# #.#...........#.#.....#...#...#
#####.###.#####.###.#.#.#.###.# #.#.#####.###.#####.#########.#
RU....#.#.....#.#...#...#.#...#.# OS....#.#...#...#.....#.#...#.#.#
#.#######.###.#.#.#.###.###.#.# #.#.#.###.#.#.###.#.#.###.#.#.#
#...............#.....#.....#..QT #.#...#...#.#...#.#...#.#.....#
#.#######.#.###.###.########### ###.#.#####.#####.###.#.#.###.#
#.#.#.#...#.#...#.#...#.#.#...# #.#.#.#...#.........#.......#..QN
###.#.###.#.###.#.#####.#.#.#.# #.#.#.###.#####################
#.#...#...#.#...#.#.#.#.....#.# #.#.#.#.............#.#...#.#..HW
#.#.#############.#.#.#####.#.# #.#####.#.#########.#.#.#.#.#.#
#.#.#...#.#...#.#.......#.#.#..DQ #.#.#...#.#...#.........#.....#
#.#.#.###.#.###.###.#.###.#.### #.#.#####.#.###.#####.#.###.###
JZ....................#.........# QO....#.#.......#.#.#...#...#...#
###.#########################.# ###.#.#.#.#######.###.###.#.#.#
PF..#.#.......#.....#.........#.# #.......#...#...#.....#.#.#.#.#
#.###.###.#.#.###.#.#.###.##### #############.#####.#.#.#######
#.......#.#.....#...#.#.......# #...#...#...#...#...#.#.#...#.#
#.#.#.###.#.#####.#.###.#.##### #.#.#.#.#.###.#####.###.###.#.#
#.#.#...#.#.....#.#.#.#.#.#.#.# KL..#.#.#.#.....#...#.#.#.......#
#.#.###.#####.###.###.###.#.#.# ###.#.#.#.#.#####.###.#######.#
#.#...#...#...#...#............RU #...#.#...#...#.#.#.#...#.#.#..RP
#.#.###.###.###.#.#.#.#.#.###.# #.###.#.#.###.#.#.#.#.###.#.#.#
#.#...#.#.....#.#.#.#.#.#...#.# #.....#.#.#...................#
###.###.#.###.###.###.###.###.# D P Y O H R P #.###.#######.#.#########.#.###
#...#...#.#...#.....#.#...#.#.# W Z K A O O F #.#.......#...#.....#.....#...#
#.#.###.###.###.#.#.#####.#.#########.#####.#########.#########.#####.###.###.#####.###.###.#.#.#.#######.#.#.###
#.#.#.....#...#.#.#.#.#.........#.........#.#...#.......#.......#.#...#.....#.....#.#.....#.#.#.#...#.#...#.#...#
###.###.###.#.#.#.###.#.###.#.###.###.###.#.#.#.###.#.#.#####.###.#.#####.#.#.#.#.#########.#####.#.#.###.###.###
#.....#...#.#.#.#...#.....#.#.#.#.#...#.#.#...#...#.#.#.....#.#.........#.#.#.#.#.....#.#...#.#...#...#...#.....#
###.#.#.#########.#######.#####.#######.#.#####.###.#.#######.###.#######.###.#.#######.#####.#####.#####.###.#.#
#...#.#.#.#.#.#.....#.#...#...............#...#...#.#.#...#.....#.....#...#...#...#.#.........#.........#...#.#.#
#.#.#.###.#.#.#.#####.#######.#.#.#.###.###.#.#.###.#####.#####.#.###.###.#.###.###.#.###########.###.#.###.#.#.#
#.#.#...#.......#.#...#...#...#.#.#.#.#...#.#...#.......#.......#.#.#.#.......#.......#.......#...#...#...#.#.#.#
#####.#########.#.#.###.#############.###.#.#######.###.#.#######.#.#####.###.#.#####.#####.#####.#.#.#.###.###.#
#.#.......#.......#.#...#.................#.#.....#...#.#.#.#.#.....#.......#.#.....#...........#.#.#.#...#...#.#
#.#.###.#.#########.#.#############.#######.#.###.###.###.#.#.###.#.###.#######.#####.#.#.#.#.#######.###.#.###.#
#.....#.#.#.....#...#...#.#...............#.#...#...#.#...#.....#.#...#.#.#.........#.#.#.#.#...#.......#.#...#.#
#.#.#####.#####.###.#.###.###############.#.###.#.###.###.#.###.#.#####.#.###.#####.###.###.#.#.###.#.#.#######.#
#.#...#.....#.#.....#.....#.....#.#.......#.....#.#.....#.....#.#...#...#...#...#.#...#...#.#.#.#...#.#.#.......#
#.#.#########.#####.#.#########.#.#.#######.#####.#.#.#.#.#.###.#.#########.#.###.#.###.#####.###.#.#.#########.#
#.#.#...#.....#...#.....#.#.#.........#.......#...#.#.#.#.#.#.#.#...#.....#.......#.#.....#.....#.#.#...#.......#
#.#####.#####.#.###.#.###.#.###.#.#.###.#.#.###.#.#.#####.###.#.#.#####.#######.#.###########.#####.#######.#.###
#.#.......#.........#.#.#.......#.#.#.#.#.#.#...#.#.#.#.....#...#...#.....#...#.#.#...#...#...#.#.#.....#...#...#
###.###.#.#.#.#.#.#.#.#.#.###.#.###.#.###.#####.###.#.#########.#.###.#######.#.#####.###.###.#.#.#########.###.#
#.#...#.#...#.#.#.#.#...#.#.#.#...#.....#.#.......#...#.....#...#.......#.#.#...#.#...#.....#.#...#.....#.#.#...#
#.#.#.#.#.#.#.#######.#####.###.###.#########.###.#.#####.#####.#######.#.#.#.###.#.###.#######.#.#.#.#.#.#####.#
#.#.#.#.#.#.#.#.........#.........#.......#...#...#.....#...#...#.........#...........#.....#...#.#.#.#.#...#.#.#
#.#####.###.#########.#########.###.#######.#####.#####.###.###.###.#.#.#######.#.#####.#.#####.###.#####.###.#.#
#.......#.#.#.............#.....#...#.#.#.....#.#.#.....#...#.....#.#.#.#.....#.#...#.#.#...#...#...#.#.....#...#
#.#.#####.###.###.#.#####.#########.#.#.#.#####.#.#.#.#.###.###.###.#######.#.#.#####.#.#####.#####.#.###.#######
#.#...#.....#.#.#.#.#.#.........#.......#.#.#.#...#.#.#.#.......#...#...#.#.#.....................#...#.........#
#########.#.###.#####.###.#####.###.#######.#.###.#.#######.###.#.#####.#.#.###############.#.#####.###.#########
#.........#.........#.....#.........#...#.#...#...#...#...#.#...#.#.#.....................#.#...................#
###.#.#####.#####.###.#.#####.#####.###.#.#.###.#.#.#.###.#.#####.#.###########.#######.#####.###.###########.###
#...#.#.......#.......#.#.......#.....#.........#.#.#.#.......#.......#...............#.....#.#...........#.....#
###################################.#######.#.#####.#####.###########.###.###.###################################
J A O Q N Q S D
O A A T Z O U A

94
2019/day20/main.go Normal file
View File

@ -0,0 +1,94 @@
package main
import (
"bufio"
"fmt"
"os"
"time"
helpers "git.bullercodeworks.com/brian/adventofcode/helpers"
)
var maze *Maze
func main() {
file := "input"
var manual bool
if helpers.GetArgNumber(1) != "" {
file = helpers.GetArgNumber(1)
}
if helpers.GetArgNumber(2) == "manual" {
manual = true
}
maze = NewMaze(file)
if manual {
runmanual(maze)
}
part1()
//part2(inp)
}
func part1() {
maze.GetStart().steps = 0
ProcessNode(maze.GetStart(), 0)
fmt.Println("Distance:", maze.GetEnd().steps)
}
func ProcessNode(m *MazeCoord, steps int) {
fmt.Println("Processing Node", m)
if maze.IsEnd(m.X, m.Y) {
fmt.Println(" End")
return
}
for _, neighbor := range []*MazeCoord{m.N, m.E, m.S, m.W} {
if neighbor == nil {
continue
}
if m.steps+1 < neighbor.steps {
neighbor.steps = m.steps + 1
if !neighbor.visited {
ProcessNode(neighbor, m.steps+1)
}
}
}
m.visited = true
}
func runmanual(m *Maze) {
var err error
var inp string
m.Print()
for {
reader := bufio.NewReader(os.Stdin)
inp, err = reader.ReadString('\n')
if err != nil {
fmt.Println("Input Error:", err.Error())
continue
}
var valid bool
switch inp[0] {
case 'N', 'n':
valid = m.MoveNorth()
case 'E', 'e':
valid = m.MoveEast()
case 'S', 's':
valid = m.MoveSouth()
case 'W', 'w':
valid = m.MoveWest()
case 'Q', 'q':
fmt.Println("Quitting")
break
}
fmt.Println(helpers.CLEAR_SCREEN)
m.Print()
if m.IsDone() {
fmt.Println("DONE!")
break
}
if !valid {
fmt.Println("Invalid Move")
}
time.Sleep(time.Second / 2)
}
}

228
2019/day20/maze.go Normal file
View File

@ -0,0 +1,228 @@
package main
import (
"bytes"
"fmt"
helpers "git.bullercodeworks.com/brian/adventofcode/helpers"
)
type Maze struct {
start *MazeCoord
end *MazeCoord
maze map[string]*MazeCoord
portals map[string]*Portal
current *MazeCoord
BotX, BotY int
TopX, TopY int
}
func NewMaze(file string) *Maze {
inp := helpers.FileToBytes(file)
lines := bytes.Split(inp, []byte{'\n'})
m := Maze{
maze: make(map[string]*MazeCoord),
portals: make(map[string]*Portal),
}
for yk, yv := range lines {
for xk, xv := range yv {
if xv == '.' || xv == '#' {
m.maze[c(xk, yk)] = &MazeCoord{
X: xk,
Y: yk,
Value: xv,
steps: helpers.MAX_INT,
}
}
}
}
// Now hook up neighbor coords
for _, v := range m.maze {
if v.X < m.BotX {
m.BotX = v.X
}
if v.X > m.TopX {
m.TopX = v.X
}
if v.Y < m.BotY {
m.BotY = v.Y
}
if v.Y > m.TopY {
m.TopY = v.Y
}
var d *MazeCoord
var ok bool
// Hook up north
if d, ok = m.maze[c(v.X, v.Y-1)]; ok {
v.N = d
} else if v.Value == '.' {
// North Portal
name := string([]byte{lines[v.Y-2][v.X], lines[v.Y-1][v.X]})
var p *Portal
if p, ok = m.portals[name]; ok {
v.N = m.maze[c(p.X1, p.Y1)]
m.maze[c(p.X1, p.Y1)].S = v
p.X2 = v.X
p.Y2 = v.Y
} else {
m.portals[name] = &Portal{
Name: name,
X1: v.X,
Y1: v.Y,
}
}
}
// Hook up east
if d, ok = m.maze[c(v.X+1, v.Y)]; ok {
v.E = d
} else if v.Value == '.' {
// East Portal
name := string([]byte{lines[v.Y][v.X+1], lines[v.Y][v.X+2]})
var p *Portal
if p, ok = m.portals[name]; ok {
v.E = m.maze[c(p.X1, p.Y1)]
m.maze[c(p.X1, p.Y1)].W = v
p.X2 = v.X
p.Y2 = v.Y
} else {
m.portals[name] = &Portal{
Name: name,
X1: v.X,
Y1: v.Y,
}
}
}
// Hook up south
if d, ok = m.maze[c(v.X, v.Y+1)]; ok {
v.S = d
} else if v.Value == '.' {
// South Portal
name := string([]byte{lines[v.Y+1][v.X], lines[v.Y+2][v.X]})
var p *Portal
if p, ok = m.portals[name]; ok {
v.S = m.maze[c(p.X1, p.Y1)]
m.maze[c(p.X1, p.Y1)].N = v
fmt.Println(v.S, "<=>", m.maze[c(p.X1, p.Y1)].N)
p.X2 = v.X
p.Y2 = v.Y
} else {
m.portals[name] = &Portal{
Name: name,
X1: v.X,
Y1: v.Y,
}
}
}
// Hook up west
if d, ok = m.maze[c(v.X-1, v.Y)]; ok {
v.W = d
} else if v.Value == '.' {
// West Portal
name := string([]byte{lines[v.Y][v.X-2], lines[v.Y][v.X-1]})
var p *Portal
if p, ok = m.portals[name]; ok {
v.W = m.maze[c(p.X1, p.Y1)]
m.maze[c(p.X1, p.Y1)].E = v
p.X2 = v.X
p.Y2 = v.Y
} else {
m.portals[name] = &Portal{
Name: name,
X1: v.X,
Y1: v.Y,
}
}
}
}
st := m.portals["AA"]
m.current = m.maze[c(st.X1, st.Y1)]
return &m
}
func (m *Maze) MoveNorth() bool {
if m.current.N != nil && m.current.N.Value == '.' {
m.current = m.current.N
return true
}
return false
}
func (m *Maze) MoveEast() bool {
if m.current.E != nil && m.current.E.Value == '.' {
m.current = m.current.E
return true
}
return false
}
func (m *Maze) MoveSouth() bool {
if m.current.S != nil && m.current.S.Value == '.' {
m.current = m.current.S
return true
}
return false
}
func (m *Maze) MoveWest() bool {
if m.current.W != nil && m.current.W.Value == '.' {
m.current = m.current.W
return true
}
return false
}
func (m *Maze) Print() {
for y := m.BotY; y <= m.TopY; y++ {
for x := m.BotX; x <= m.TopX; x++ {
if m.current.X == x && m.current.Y == y {
fmt.Print("%")
} else {
if v, ok := m.maze[c(x, y)]; ok {
fmt.Print(string(v.Value))
} else {
fmt.Print(" ")
}
}
}
fmt.Println()
}
}
func (m *Maze) GetStart() *MazeCoord {
start := m.portals["AA"]
return m.maze[c(start.X1, start.Y1)]
}
func (m *Maze) IsDone() bool {
return m.IsEnd(m.current.X, m.current.Y)
}
func (m *Maze) GetEnd() *MazeCoord {
end := m.portals["ZZ"]
return m.maze[c(end.X1, end.Y1)]
}
func (m *Maze) IsEnd(x, y int) bool {
return x == m.GetEnd().X && y == m.GetEnd().Y
}
type Portal struct {
Name string
X1, Y1, X2, Y2 int
}
type MazeCoord struct {
X, Y int
N, E, S, W *MazeCoord
Value byte
visited bool
steps int
}
func c(x, y int) string {
return fmt.Sprintf("[%d, %d]", x, y)
}

19
2019/day20/testinput1 Normal file
View File

@ -0,0 +1,19 @@
A
A
#######.#########
#######.........#
#######.#######.#
#######.#######.#
#######.#######.#
##### B ###.#
BC...## C ###.#
##.## ###.#
##...DE F ###.#
##### G ###.#
#########.#####.#
DE..#######...###.#
#.#########.###.#
FG..#########.....#
###########.#####
Z
Z

1
2019/day21/input Normal file

File diff suppressed because one or more lines are too long

83
2019/day21/main.go Normal file
View File

@ -0,0 +1,83 @@
package main
import (
"fmt"
"time"
intcode "git.bullercodeworks.com/brian/adventofcode/2019/intcode-processor"
helpers "git.bullercodeworks.com/brian/adventofcode/helpers"
)
func main() {
pt := helpers.GetArgNumber(1)
prog := intcode.ReadIntCodeFile("input")
if pt == "1" {
part1(prog)
} else {
part2(prog)
}
}
func part1(prog []int) {
p := intcode.NewProgram(prog)
//p.EnableDebug()
var lastOut int
go func() {
for {
if !p.NeedsOutput() && !p.NeedsInput() {
time.Sleep(1)
} else if p.NeedsOutput() {
lastOut = getOutput(p)
fmt.Print(string(byte(lastOut)))
} else if p.NeedsInput() {
instructions := "NOT A J\nNOT C T\nOR T J\nAND D J\nWALK\n"
//instructions := "NOT A J\nWALK\n"
for _, v := range []byte(instructions) {
fmt.Print(string(v))
p.Input(int(v))
}
}
}
/*
fmt.Println(getOutput(p))
return
*/
}()
p.Run()
fmt.Println("Damage:", lastOut)
}
func part2(prog []int) {
p := intcode.NewProgram(prog)
//p.EnableDebug()
var lastOut int
go func() {
for {
if !p.NeedsOutput() && !p.NeedsInput() {
time.Sleep(1)
} else if p.NeedsOutput() {
lastOut = getOutput(p)
fmt.Print(string(byte(lastOut)))
} else if p.NeedsInput() {
instructions := "NOT A J\nNOT B T\nOR T J\nNOT C T\nOR T J\nAND D J\nAND E T\nOR H T\nAND T J\nRUN\n"
for _, v := range []byte(instructions) {
fmt.Print(string(v))
p.Input(int(v))
}
}
}
/*
fmt.Println(getOutput(p))
return
*/
}()
p.Run()
fmt.Println("Damage:", lastOut)
}
func getOutput(p *intcode.Program) int {
for !p.NeedsOutput() {
time.Sleep(1)
}
return p.Output()
}

100
2019/day22/input Normal file
View File

@ -0,0 +1,100 @@
deal into new stack
deal with increment 32
cut 5214
deal with increment 50
cut -7078
deal with increment 3
cut 5720
deal with increment 18
cut -6750
deal with increment 74
cut -6007
deal with increment 16
cut -3885
deal with increment 40
deal into new stack
cut -2142
deal with increment 25
deal into new stack
cut -1348
deal with increment 40
cut 3943
deal with increment 14
cut 7093
deal with increment 67
cut 1217
deal with increment 75
cut 597
deal with increment 60
cut -1078
deal with increment 68
cut -8345
deal with increment 25
cut 6856
deal into new stack
cut -4152
deal with increment 59
deal into new stack
cut -80
deal with increment 3
deal into new stack
deal with increment 44
cut 1498
deal with increment 18
cut -7149
deal with increment 58
deal into new stack
deal with increment 71
cut -323
deal into new stack
deal with increment 58
cut 1793
deal with increment 45
deal into new stack
cut 7187
deal with increment 48
cut 2664
deal into new stack
cut 8943
deal with increment 32
deal into new stack
deal with increment 62
cut -9436
deal with increment 67
deal into new stack
cut -1898
deal with increment 61
deal into new stack
deal with increment 14
cut 1287
deal with increment 8
cut 560
deal with increment 6
cut -2110
deal with increment 8
cut 9501
deal with increment 25
cut 4791
deal with increment 70
deal into new stack
deal with increment 5
cut 2320
deal with increment 47
cut -467
deal into new stack
deal with increment 19
cut -1920
deal with increment 16
cut -8920
deal with increment 65
cut -3986
deal with increment 3
cut -2690
deal with increment 35
cut -757
deal with increment 37
cut -1280
deal with increment 71
cut 3765
deal with increment 26
deal into new stack

101
2019/day22/main.go Normal file
View File

@ -0,0 +1,101 @@
package main
import (
"fmt"
"math/big"
"strconv"
helpers "git.bullercodeworks.com/brian/adventofcode/helpers"
)
func main() {
pt := helpers.GetArgNumber(1)
inp := helpers.StdinToStringSlice()
if pt == "1" {
part1(inp)
} else {
part2(inp)
}
}
func NewDeck(n int) []int {
s := make([]int, n)
for i := 0; i < n; i++ {
s[i] = i
}
return s
}
func deal(s []int) []int {
s2 := make([]int, len(s))
for i := range s {
s2[len(s)-1-i] = s[i]
}
return s2
}
func cut(s []int, n int) []int {
if n >= 0 {
return append(s[n:], s[:n]...)
}
n = -n
return append(s[len(s)-n:], s[:len(s)-n]...)
}
func dealn(s []int, n int) []int {
s2 := make([]int, len(s))
for i := range s {
s2[(i*n)%len(s)] = s[i]
}
return s2
}
func part1(inp []string) {
s := NewDeck(10007)
for _, line := range inp {
if line == "deal into new stack" {
s = deal(s)
} else if line[:3] == "cut" {
i, _ := strconv.Atoi(line[4:])
s = cut(s, i)
} else if line[:19] == "deal with increment" {
i, _ := strconv.Atoi(line[20:])
s = dealn(s, i)
}
}
for i, v := range s {
if v == 2019 {
fmt.Println(i)
return
}
}
}
func part2(inp []string) {
deckSize := big.NewInt(119315717514047)
shuffles := big.NewInt(101741582076661)
off, inc := big.NewInt(0), big.NewInt(1)
for _, line := range inp {
if line == "deal into new stack" {
inc.Mul(inc, big.NewInt(-1))
off.Add(off, inc)
} else if line[:3] == "cut" {
i, _ := strconv.Atoi(line[4:])
off.Add(off, big.NewInt(0).Mul(big.NewInt(int64(i)), inc))
} else if line[:19] == "deal with increment" {
i, _ := strconv.Atoi(line[20:])
inc.Mul(inc, big.NewInt(0).Exp(big.NewInt(int64(i)), big.NewInt(0).Sub(deckSize, big.NewInt(2)), deckSize))
}
}
lastInc := big.NewInt(0).Exp(inc, shuffles, deckSize)
lastOff := big.NewInt(0).Exp(inc, shuffles, deckSize)
lastOff.Sub(big.NewInt(1), lastOff)
mod := big.NewInt(0).Exp(big.NewInt(0).Sub(big.NewInt(1), inc), big.NewInt(0).Sub(deckSize, big.NewInt(2)), deckSize)
lastOff.Mul(lastOff, mod)
lastOff.Mul(lastOff, off)
res := big.NewInt(0).Mul(big.NewInt(2020), lastInc)
res.Add(res, lastOff)
res.Mod(res, deckSize)
fmt.Println("Result:", res)
}

1
2019/day23/input Normal file

File diff suppressed because one or more lines are too long

70
2019/day23/main.go Normal file
View File

@ -0,0 +1,70 @@
package main
import (
"fmt"
"time"
intcode "git.bullercodeworks.com/brian/adventofcode/2019/intcode-processor"
//helpers "git.bullercodeworks.com/brian/adventofcode/helpers"
)
func main() {
//pt := helpers.GetArgNumber(1)
prog := intcode.ReadIntCodeFile("input")
//if pt == "1" {
part1(prog)
//} else {
// part2(prog)
//}
}
func part1(prog []int) {
var network []*intcode.Program
msgQueue := make([][]int, 255)
for k := 0; k < 50; k++ {
p := intcode.NewProgram(prog)
//p.EnableDebug()
network = append(network, p)
msgQueue = append(msgQueue, []int{})
go func(addr int) {
for !network[addr].NeedsInput() {
time.Sleep(1)
}
network[addr].Input(0)
for {
if !network[addr].NeedsOutput() && !network[addr].NeedsInput() {
time.Sleep(1)
} else if network[addr].NeedsOutput() {
msgD := network[addr].Output()
msgQueue[msgD] = append(msgQueue[msgD], network[addr].Output())
msgQueue[msgD] = append(msgQueue[msgD], network[addr].Output())
fmt.Println(addr, "->", msgD, msgQueue[msgD])
} else if network[addr].NeedsInput() {
if len(msgQueue[addr]) > 0 {
var v int
v, msgQueue[addr] = msgQueue[addr][0], msgQueue[addr][1:]
fmt.Println(addr, "<-", v)
network[addr].Input(v)
} else {
network[addr].Input(-1)
}
}
}
}(k)
go network[k].Run()
}
for len(msgQueue[255]) < 2 {
time.Sleep(1)
}
fmt.Println(msgQueue[255])
}
func part2(prog []int) {
}
func getOutput(p *intcode.Program) int {
for !p.NeedsOutput() {
time.Sleep(1)
}
return p.Output()
}

57
helpers/coordinate3d.go Normal file
View File

@ -0,0 +1,57 @@
package aoc
import "fmt"
type Coordinate3d struct {
X, Y, Z int
}
func NewCoordinate3d(x, y, z int) *Coordinate3d {
return &Coordinate3d{x, y, z}
}
func (c *Coordinate3d) GetNorthCoord() *Coordinate3d {
return &Coordinate3d{
X: c.X,
Y: c.Y - 1,
Z: c.Z,
}
}
func (c *Coordinate3d) GetEastCoord() *Coordinate3d {
return &Coordinate3d{
X: c.X + 1,
Y: c.Y,
Z: c.Z,
}
}
func (c *Coordinate3d) GetSouthCoord() *Coordinate3d {
return &Coordinate3d{
X: c.X,
Y: c.Y + 1,
Z: c.Z,
}
}
func (c *Coordinate3d) GetWestCoord() *Coordinate3d {
return &Coordinate3d{
X: c.X - 1,
Y: c.Y,
Z: c.Z,
}
}
func (c *Coordinate3d) GetUpCoord() *Coordinate3d {
return &Coordinate3d{
X: c.X,
Y: c.Y,
Z: c.Z + 1,
}
}
func (c *Coordinate3d) GetDownCoord() *Coordinate3d {
return &Coordinate3d{
X: c.X,
Y: c.Y,
Z: c.Z - 1,
}
}
func (c Coordinate3d) String() string {
return fmt.Sprintf("[%d, %d, %d]", c.X, c.Y, c.Z)
}