Compare commits
17 Commits
Author | SHA1 | Date | |
---|---|---|---|
9e8078484a
|
|||
3ff5e90e81
|
|||
ada450ef97
|
|||
c788813cd2
|
|||
788239e531
|
|||
37928d7138
|
|||
da5823aa17
|
|||
8282e09a42
|
|||
343007481a
|
|||
44eeb5a8a6
|
|||
f8d2758c90
|
|||
d9e0d9b649
|
|||
94d83695bf
|
|||
365edf82b1
|
|||
a099a86511
|
|||
acef5fdc12
|
|||
bdd007bb4d
|
@ -169,7 +169,7 @@ func (d *Day05) Part1() string {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
return fmt.Sprintf("Diagnostic code: %d", diagCode)
|
return fmt.Sprintf("Diagnostic code: %s%d%s", utilities.TextBold, diagCode, utilities.TextReset)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *Day05) Part2() string {
|
func (d *Day05) Part2() string {
|
||||||
@ -184,5 +184,5 @@ func (d *Day05) Part2() string {
|
|||||||
diagCode = val
|
diagCode = val
|
||||||
})
|
})
|
||||||
|
|
||||||
return fmt.Sprintf("Diagnostic code: %d", diagCode)
|
return fmt.Sprintf("Diagnostic code: %s%d%s", utilities.TextBold, diagCode, utilities.TextReset)
|
||||||
}
|
}
|
||||||
|
@ -28,7 +28,7 @@ func (d *Day07) Part1() string {
|
|||||||
var highestVal int64
|
var highestVal int64
|
||||||
var highestSequence []int64
|
var highestSequence []int64
|
||||||
|
|
||||||
allSequences := utilities.GetPermutations([]int64{0, 1, 2, 3, 4})
|
allSequences := utilities.GetPermutations([]int64{0, 1, 2, 3, 4}...)
|
||||||
for _, sequence := range allSequences {
|
for _, sequence := range allSequences {
|
||||||
if len(sequence) != len(d.amps) {
|
if len(sequence) != len(d.amps) {
|
||||||
panic("input sequence does not match up to number of amplifiers")
|
panic("input sequence does not match up to number of amplifiers")
|
||||||
@ -68,7 +68,7 @@ func (d *Day07) Part2() string {
|
|||||||
var highestVal int64
|
var highestVal int64
|
||||||
var highestSequence []int64
|
var highestSequence []int64
|
||||||
|
|
||||||
allSequences := utilities.GetPermutations([]int64{5, 6, 7, 8, 9})
|
allSequences := utilities.GetPermutations([]int64{5, 6, 7, 8, 9}...)
|
||||||
for _, sequence := range allSequences {
|
for _, sequence := range allSequences {
|
||||||
if len(sequence) != len(d.amps) {
|
if len(sequence) != len(d.amps) {
|
||||||
panic("input sequence does not match up to number of amplifiers")
|
panic("input sequence does not match up to number of amplifiers")
|
||||||
|
@ -84,7 +84,8 @@ func (d *Day08) Part2() string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
outStr := strings.Builder{}
|
outStr := strings.Builder{}
|
||||||
outStr.WriteRune('\n')
|
outStr.WriteString("Message received:\n")
|
||||||
|
outStr.WriteString(utilities.TextBold)
|
||||||
for y := 0; y < imgHeight; y++ {
|
for y := 0; y < imgHeight; y++ {
|
||||||
for x := 0; x < imgWidth; x++ {
|
for x := 0; x < imgWidth; x++ {
|
||||||
if finalImg[(y*imgWidth)+x] == 0 {
|
if finalImg[(y*imgWidth)+x] == 0 {
|
||||||
@ -95,6 +96,7 @@ func (d *Day08) Part2() string {
|
|||||||
}
|
}
|
||||||
outStr.WriteRune('\n')
|
outStr.WriteRune('\n')
|
||||||
}
|
}
|
||||||
|
outStr.WriteString(utilities.TextReset)
|
||||||
|
|
||||||
return outStr.String()
|
return outStr.String()
|
||||||
}
|
}
|
||||||
|
@ -99,7 +99,8 @@ func (d *Day11) Part2() string {
|
|||||||
_, min, max := d.paintHull()
|
_, min, max := d.paintHull()
|
||||||
|
|
||||||
outStr := strings.Builder{}
|
outStr := strings.Builder{}
|
||||||
outStr.WriteRune('\n')
|
outStr.WriteString("Registration identifier:\n")
|
||||||
|
outStr.WriteString(u.TextBold)
|
||||||
for x := min.First; x <= max.First; x++ {
|
for x := min.First; x <= max.First; x++ {
|
||||||
for y := min.Second; y <= max.Second; y++ {
|
for y := min.Second; y <= max.Second; y++ {
|
||||||
val, exists := d.painted[u.Pair[int, int]{First: x, Second: y}]
|
val, exists := d.painted[u.Pair[int, int]{First: x, Second: y}]
|
||||||
@ -111,6 +112,7 @@ func (d *Day11) Part2() string {
|
|||||||
}
|
}
|
||||||
outStr.WriteRune('\n')
|
outStr.WriteRune('\n')
|
||||||
}
|
}
|
||||||
|
outStr.WriteString(u.TextReset)
|
||||||
|
|
||||||
return outStr.String()
|
return outStr.String()
|
||||||
}
|
}
|
||||||
|
66
days/14.go
66
days/14.go
@ -10,18 +10,15 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type reaction struct {
|
type reaction struct {
|
||||||
inputs map[string]int
|
inputs map[string]int64
|
||||||
output u.Pair[string, int]
|
output u.Pair[string, int]
|
||||||
}
|
}
|
||||||
|
|
||||||
type Day14 struct {
|
type Day14 struct {
|
||||||
reactions []reaction
|
reactions []reaction
|
||||||
leftovers map[string]int
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *Day14) Parse() {
|
func (d *Day14) Parse() {
|
||||||
d.leftovers = make(map[string]int)
|
|
||||||
|
|
||||||
lines := u.GetStringLines("14p")
|
lines := u.GetStringLines("14p")
|
||||||
d.reactions = make([]reaction, len(lines))
|
d.reactions = make([]reaction, len(lines))
|
||||||
for i, line := range lines {
|
for i, line := range lines {
|
||||||
@ -32,10 +29,10 @@ func (d *Day14) Parse() {
|
|||||||
outPair := strings.Split(output, " ")
|
outPair := strings.Split(output, " ")
|
||||||
outAmt, _ := strconv.Atoi(outPair[0])
|
outAmt, _ := strconv.Atoi(outPair[0])
|
||||||
d.reactions[i].output = u.Pair[string, int]{First: outPair[1], Second: outAmt}
|
d.reactions[i].output = u.Pair[string, int]{First: outPair[1], Second: outAmt}
|
||||||
d.reactions[i].inputs = make(map[string]int)
|
d.reactions[i].inputs = make(map[string]int64)
|
||||||
for _, input := range inputs {
|
for _, input := range inputs {
|
||||||
pair := strings.Split(input, " ")
|
pair := strings.Split(input, " ")
|
||||||
d.reactions[i].inputs[pair[1]], _ = strconv.Atoi(pair[0])
|
d.reactions[i].inputs[pair[1]], _ = strconv.ParseInt(pair[0], 10, 64)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -54,7 +51,7 @@ func (d Day14) Num() int {
|
|||||||
return 14
|
return 14
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *Day14) oreRequiredStock(qty int64) int64 {
|
func (d *Day14) getOreRequiredForFuel(qty int64) int64 {
|
||||||
oreRequired := int64(0)
|
oreRequired := int64(0)
|
||||||
needs := map[string]int64{
|
needs := map[string]int64{
|
||||||
"FUEL": qty,
|
"FUEL": qty,
|
||||||
@ -62,33 +59,36 @@ func (d *Day14) oreRequiredStock(qty int64) int64 {
|
|||||||
excess := make(map[string]int64)
|
excess := make(map[string]int64)
|
||||||
|
|
||||||
getFromExcess := func(qty int64, chemical string) int64 {
|
getFromExcess := func(qty int64, chemical string) int64 {
|
||||||
inStock := excess[chemical]
|
available := u.Min(excess[chemical], qty)
|
||||||
qty -= inStock
|
excess[chemical] -= available
|
||||||
excess[chemical] = int64(math.Min(math.Abs(float64(qty)), 0))
|
return available
|
||||||
return inStock - excess[chemical]
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for len(needs) > 0 {
|
for len(needs) > 0 {
|
||||||
keys := u.MapKeys(needs)
|
keys := u.MapKeys(needs)
|
||||||
chemical := keys[len(keys)-1]
|
producing := keys[0]
|
||||||
qtyRequired := needs[chemical]
|
qtyRequired := needs[producing]
|
||||||
delete(needs, chemical)
|
delete(needs, producing)
|
||||||
|
|
||||||
fromExcess := getFromExcess(qtyRequired, chemical)
|
fromExcess := getFromExcess(qtyRequired, producing)
|
||||||
|
if fromExcess == qtyRequired {
|
||||||
|
continue
|
||||||
|
}
|
||||||
qtyRequired -= fromExcess
|
qtyRequired -= fromExcess
|
||||||
|
|
||||||
reaction := d.getReactionProducing(chemical)
|
reaction := d.getReactionProducing(producing)
|
||||||
|
|
||||||
qtyProduced := int64(reaction.output.Second)
|
qtyProduced := int64(reaction.output.Second)
|
||||||
ingredients := reaction.inputs
|
reactionsNeeded := int64(math.Ceil(float64(qtyRequired) / float64(qtyProduced)))
|
||||||
|
|
||||||
n := int64(math.Ceil(float64(qtyRequired) / float64(qtyProduced)))
|
excess[producing] = (qtyProduced * reactionsNeeded) - qtyRequired
|
||||||
|
|
||||||
excess[chemical] = (qtyProduced * n) - qtyRequired
|
for reagent, inputQty := range reaction.inputs {
|
||||||
for ingredient, qtyIngredient := range ingredients {
|
qtyNeeded := inputQty * reactionsNeeded
|
||||||
if ingredient == "ORE" {
|
if reagent == "ORE" {
|
||||||
oreRequired += int64(int64(qtyIngredient) * n)
|
oreRequired += qtyNeeded
|
||||||
} else {
|
} else {
|
||||||
needs[ingredient] += int64(qtyIngredient) * n
|
needs[reagent] += qtyNeeded
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -97,13 +97,13 @@ func (d *Day14) oreRequiredStock(qty int64) int64 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (d *Day14) Part1() string {
|
func (d *Day14) Part1() string {
|
||||||
neededOre := d.oreRequiredStock(1)
|
neededOre := d.getOreRequiredForFuel(1)
|
||||||
return fmt.Sprintf("%s%d%s", u.TextBold, neededOre, u.TextReset)
|
return fmt.Sprintf("Minimum ore to produce 1 FUEL: %s%d%s", u.TextBold, neededOre, u.TextReset)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *Day14) Part2() string {
|
func (d *Day14) Part2() string {
|
||||||
oreAvailable := int64(1000000000000)
|
oreAvailable := int64(1000000000000)
|
||||||
estimate := oreAvailable / d.oreRequiredStock(1)
|
estimate := oreAvailable / d.getOreRequiredForFuel(1)
|
||||||
|
|
||||||
high := estimate * 2
|
high := estimate * 2
|
||||||
low := estimate
|
low := estimate
|
||||||
@ -112,16 +112,18 @@ func (d *Day14) Part2() string {
|
|||||||
lastFailure := high
|
lastFailure := high
|
||||||
fuelProduced := low
|
fuelProduced := low
|
||||||
|
|
||||||
for math.Abs(float64(lastFailure)-float64(lastSuccess)) > 1 {
|
for math.Abs(float64(lastFailure-lastSuccess)) > 1 {
|
||||||
oreConsumed := d.oreRequiredStock(fuelProduced)
|
oreConsumed := d.getOreRequiredForFuel(fuelProduced)
|
||||||
|
adjustment := (lastFailure - lastSuccess) / 2
|
||||||
if oreConsumed < oreAvailable {
|
if oreConsumed < oreAvailable {
|
||||||
lastSuccess = fuelProduced
|
lastSuccess = fuelProduced
|
||||||
fuelProduced += (lastFailure - lastSuccess) / 2
|
|
||||||
} else {
|
} else {
|
||||||
lastFailure = fuelProduced
|
lastFailure = fuelProduced
|
||||||
fuelProduced -= (lastFailure - lastSuccess) / 2
|
adjustment = -adjustment
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return fmt.Sprintf("%s%d%s", u.TextBold, lastSuccess, u.TextReset)
|
fuelProduced += adjustment
|
||||||
|
}
|
||||||
|
|
||||||
|
return fmt.Sprintf("Maximum fuel we can make from 1 trillion ore: %s%d%s", u.TextBold, lastSuccess, u.TextReset)
|
||||||
}
|
}
|
||||||
|
332
days/15.go
Normal file
332
days/15.go
Normal file
@ -0,0 +1,332 @@
|
|||||||
|
package days
|
||||||
|
|
||||||
|
//go:generate stringer -type=cellStatus,responseType,dirType -output=15_types_string.go
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"math"
|
||||||
|
"sort"
|
||||||
|
|
||||||
|
u "parnic.com/aoc2019/utilities"
|
||||||
|
)
|
||||||
|
|
||||||
|
type point u.Pair[int, int]
|
||||||
|
type cellStatus int
|
||||||
|
type responseType int
|
||||||
|
type dirType int
|
||||||
|
|
||||||
|
const (
|
||||||
|
cellStatusUnknown cellStatus = iota
|
||||||
|
cellStatusWall
|
||||||
|
cellStatusOpen
|
||||||
|
cellStatusGoal
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
responseWall responseType = iota
|
||||||
|
responseSuccess
|
||||||
|
responseFoundGoal
|
||||||
|
)
|
||||||
|
|
||||||
|
const maxVisited = 3
|
||||||
|
|
||||||
|
const (
|
||||||
|
dirNorth dirType = iota + 1
|
||||||
|
dirSouth
|
||||||
|
dirWest
|
||||||
|
dirEast
|
||||||
|
|
||||||
|
dirFirst = dirNorth
|
||||||
|
dirLast = dirEast
|
||||||
|
)
|
||||||
|
|
||||||
|
var dirOrders = [][]dirType{
|
||||||
|
{dirNorth, dirSouth, dirWest, dirEast},
|
||||||
|
{dirSouth, dirWest, dirEast, dirNorth},
|
||||||
|
{dirWest, dirEast, dirNorth, dirSouth},
|
||||||
|
{dirEast, dirNorth, dirSouth, dirWest},
|
||||||
|
}
|
||||||
|
|
||||||
|
// turned out to be unnecessary on multiple datasets i tried. increases the iterations 6x
|
||||||
|
// var dirOrders = u.GetPermutations(dirNorth, dirSouth, dirWest, dirEast)
|
||||||
|
|
||||||
|
type visitedStatus struct {
|
||||||
|
timesVisited int
|
||||||
|
distanceFromStart int
|
||||||
|
}
|
||||||
|
|
||||||
|
type Day15 struct {
|
||||||
|
program u.IntcodeProgram
|
||||||
|
grid map[point]cellStatus
|
||||||
|
visited map[point]*visitedStatus
|
||||||
|
shortestPath []point
|
||||||
|
pos point
|
||||||
|
goalPos point
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *Day15) Parse() {
|
||||||
|
d.program = u.LoadIntcodeProgram("15p")
|
||||||
|
d.grid = map[point]cellStatus{
|
||||||
|
{First: 0, Second: 0}: cellStatusOpen,
|
||||||
|
}
|
||||||
|
d.visited = map[point]*visitedStatus{
|
||||||
|
{First: 0, Second: 0}: {timesVisited: 1},
|
||||||
|
}
|
||||||
|
d.shortestPath = []point{{}}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d Day15) Num() int {
|
||||||
|
return 15
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d Day15) getPointInDirection(pos point, dir dirType) point {
|
||||||
|
target := pos
|
||||||
|
switch dir {
|
||||||
|
case dirNorth:
|
||||||
|
target.First--
|
||||||
|
case dirSouth:
|
||||||
|
target.First++
|
||||||
|
case dirWest:
|
||||||
|
target.Second--
|
||||||
|
case dirEast:
|
||||||
|
target.Second++
|
||||||
|
}
|
||||||
|
|
||||||
|
return target
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d Day15) getCellTypeInDirection(pos point, dir dirType) (cellStatus, point) {
|
||||||
|
target := d.getPointInDirection(pos, dir)
|
||||||
|
return d.grid[target], target
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d Day15) getAdjacentCellsOfType(pos point, cellType cellStatus) []point {
|
||||||
|
points := make([]point, 0, 4)
|
||||||
|
for i := dirFirst; i <= dirLast; i++ {
|
||||||
|
adjacentCell := d.getPointInDirection(pos, i)
|
||||||
|
if d.grid[adjacentCell] == cellType {
|
||||||
|
points = append(points, adjacentCell)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return points
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d Day15) getDirToNextCellType(pos point, t cellStatus, maxNumVisited int, dirs []dirType) (dirType, point, error) {
|
||||||
|
for _, dir := range dirs {
|
||||||
|
cellInDirection, targetCell := d.getCellTypeInDirection(pos, dir)
|
||||||
|
if cellInDirection == t {
|
||||||
|
_, visitedTargetExists := d.visited[targetCell]
|
||||||
|
foundUnknown := t == cellStatusUnknown && !visitedTargetExists
|
||||||
|
foundOther := t != cellStatusUnknown && visitedTargetExists && d.visited[targetCell].timesVisited <= maxNumVisited
|
||||||
|
if foundUnknown || foundOther {
|
||||||
|
return dir, targetCell, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return dirFirst, point{}, fmt.Errorf("no %v tiles around %v", t, pos)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *Day15) Draw() {
|
||||||
|
min := point{First: math.MaxInt, Second: math.MaxInt}
|
||||||
|
max := point{First: math.MinInt, Second: math.MinInt}
|
||||||
|
for p := range d.grid {
|
||||||
|
if p.First < min.First {
|
||||||
|
min.First = p.First
|
||||||
|
}
|
||||||
|
if p.First > max.First {
|
||||||
|
max.First = p.First
|
||||||
|
}
|
||||||
|
if p.Second < min.Second {
|
||||||
|
min.Second = p.Second
|
||||||
|
}
|
||||||
|
if p.Second > max.Second {
|
||||||
|
max.Second = p.Second
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for x := min.First; x <= max.First; x++ {
|
||||||
|
for y := min.Second; y <= max.Second; y++ {
|
||||||
|
p := point{First: x, Second: y}
|
||||||
|
switch d.grid[p] {
|
||||||
|
case cellStatusGoal:
|
||||||
|
fmt.Printf("%s@%s", u.ColorBrightGreen, u.TextReset)
|
||||||
|
case cellStatusOpen:
|
||||||
|
if p == d.pos {
|
||||||
|
fmt.Print(u.BackgroundBrightRed)
|
||||||
|
} else if x == 0 && y == 0 {
|
||||||
|
fmt.Print(u.BackgroundYellow)
|
||||||
|
} else if u.ArrayContains(d.shortestPath, p) {
|
||||||
|
fmt.Print(u.BackgroundGreen)
|
||||||
|
} else if d.visited[p] != nil && d.visited[p].timesVisited > maxVisited {
|
||||||
|
fmt.Print(u.ColorYellow)
|
||||||
|
fmt.Print(u.BackgroundBlack)
|
||||||
|
} else if d.visited[p] != nil && d.visited[p].timesVisited > 1 {
|
||||||
|
fmt.Print(u.BackgroundMagenta)
|
||||||
|
} else {
|
||||||
|
fmt.Print(u.BackgroundBlue)
|
||||||
|
}
|
||||||
|
fmt.Printf(".%s", u.TextReset)
|
||||||
|
case cellStatusWall:
|
||||||
|
fmt.Print("█")
|
||||||
|
case cellStatusUnknown:
|
||||||
|
fmt.Print(" ")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fmt.Println()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *Day15) markShortestPath() {
|
||||||
|
pos := d.goalPos
|
||||||
|
checkOffsets := []point{
|
||||||
|
{First: -1, Second: 0},
|
||||||
|
{First: 1, Second: 0},
|
||||||
|
{First: 0, Second: -1},
|
||||||
|
{First: 0, Second: 1},
|
||||||
|
}
|
||||||
|
|
||||||
|
checkPt := func(pt point) (bool, int) {
|
||||||
|
if v, exists := d.visited[pt]; exists && d.grid[pt] == cellStatusOpen {
|
||||||
|
return true, v.distanceFromStart
|
||||||
|
}
|
||||||
|
return false, math.MaxInt
|
||||||
|
}
|
||||||
|
|
||||||
|
d.shortestPath = []point{d.goalPos}
|
||||||
|
|
||||||
|
for pos.First != 0 || pos.Second != 0 {
|
||||||
|
lowestDist := math.MaxInt
|
||||||
|
lowestPoint := point{}
|
||||||
|
for _, pt := range checkOffsets {
|
||||||
|
newPt := point{First: pos.First + pt.First, Second: pos.Second + pt.Second}
|
||||||
|
if found, dist := checkPt(newPt); found && dist < lowestDist {
|
||||||
|
lowestDist = dist
|
||||||
|
lowestPoint = newPt
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
d.shortestPath = append(d.shortestPath, lowestPoint)
|
||||||
|
pos = lowestPoint
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *Day15) exploreFullMap() map[point]*visitedStatus {
|
||||||
|
grids := make([]map[point]cellStatus, 0, len(dirOrders))
|
||||||
|
goalVisited := d.visited
|
||||||
|
|
||||||
|
for _, dirOrder := range dirOrders {
|
||||||
|
d.program.Reset()
|
||||||
|
|
||||||
|
targetPos := point{}
|
||||||
|
nextDir := dirFirst
|
||||||
|
distFromStart := 0
|
||||||
|
|
||||||
|
d.pos = point{}
|
||||||
|
d.visited = map[point]*visitedStatus{
|
||||||
|
{First: 0, Second: 0}: {timesVisited: 1},
|
||||||
|
}
|
||||||
|
d.grid = map[point]cellStatus{
|
||||||
|
{First: 0, Second: 0}: cellStatusOpen,
|
||||||
|
}
|
||||||
|
d.program.RunIn(func(inputStep int) int64 {
|
||||||
|
var err error
|
||||||
|
nextDir, targetPos, err = d.getDirToNextCellType(d.pos, cellStatusUnknown, 0, dirOrder)
|
||||||
|
if err != nil {
|
||||||
|
// ensure we never try to go back into the trapped spot
|
||||||
|
d.visited[d.pos].timesVisited = maxVisited + 1
|
||||||
|
for x := 1; x <= maxVisited && err != nil; x++ {
|
||||||
|
nextDir, targetPos, err = d.getDirToNextCellType(d.pos, cellStatusOpen, x, dirOrder)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
// d.Draw()
|
||||||
|
// panic(err)
|
||||||
|
d.program.Stop()
|
||||||
|
}
|
||||||
|
|
||||||
|
return int64(nextDir)
|
||||||
|
}, func(val int64, state u.IntcodeProgramState) {
|
||||||
|
rVal := responseType(val)
|
||||||
|
|
||||||
|
p := d.getPointInDirection(d.pos, nextDir)
|
||||||
|
shouldMove := true
|
||||||
|
switch rVal {
|
||||||
|
case responseWall:
|
||||||
|
d.grid[p] = cellStatusWall
|
||||||
|
shouldMove = false
|
||||||
|
case responseSuccess:
|
||||||
|
d.grid[p] = cellStatusOpen
|
||||||
|
case responseFoundGoal:
|
||||||
|
d.grid[p] = cellStatusGoal
|
||||||
|
}
|
||||||
|
|
||||||
|
if shouldMove {
|
||||||
|
d.pos = targetPos
|
||||||
|
if d.visited[d.pos] == nil {
|
||||||
|
d.visited[d.pos] = &visitedStatus{}
|
||||||
|
distFromStart++
|
||||||
|
} else {
|
||||||
|
distFromStart--
|
||||||
|
}
|
||||||
|
d.visited[d.pos].timesVisited++
|
||||||
|
d.visited[d.pos].distanceFromStart = distFromStart
|
||||||
|
}
|
||||||
|
|
||||||
|
if rVal == responseFoundGoal {
|
||||||
|
// d.Draw()
|
||||||
|
d.goalPos = targetPos
|
||||||
|
goalVisited = d.visited
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
grids = append(grids, d.grid)
|
||||||
|
}
|
||||||
|
|
||||||
|
d.grid = map[point]cellStatus{
|
||||||
|
{First: 0, Second: 0}: cellStatusOpen,
|
||||||
|
}
|
||||||
|
for _, grid := range grids {
|
||||||
|
keys := u.MapKeys(grid)
|
||||||
|
for _, key := range keys {
|
||||||
|
d.grid[key] = grid[key]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return goalVisited
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *Day15) tagDistanceRecursive(pos, last point, dist int, distances map[point]int) {
|
||||||
|
distances[pos] = dist
|
||||||
|
for _, cell := range d.getAdjacentCellsOfType(pos, cellStatusOpen) {
|
||||||
|
if cell == last {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
d.tagDistanceRecursive(cell, pos, dist+1, distances)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *Day15) Part1() string {
|
||||||
|
d.visited = d.exploreFullMap()
|
||||||
|
d.markShortestPath()
|
||||||
|
|
||||||
|
for _, visited := range d.visited {
|
||||||
|
visited.timesVisited = 1
|
||||||
|
}
|
||||||
|
d.pos = point{}
|
||||||
|
d.Draw()
|
||||||
|
|
||||||
|
return fmt.Sprintf("Moves required to reach target: %s%d%s", u.TextBold, d.visited[d.goalPos].distanceFromStart, u.TextReset)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *Day15) Part2() string {
|
||||||
|
startLoc := d.goalPos
|
||||||
|
distanceMap := map[point]int{startLoc: 0}
|
||||||
|
|
||||||
|
d.tagDistanceRecursive(startLoc, point{}, 0, distanceMap)
|
||||||
|
|
||||||
|
cellDistances := u.MapValues(distanceMap)
|
||||||
|
sort.Slice(cellDistances, func(i, j int) bool { return cellDistances[i] > cellDistances[j] })
|
||||||
|
|
||||||
|
return fmt.Sprintf("Time to fill the area with oxygen: %s%d%s minutes", u.TextBold, cellDistances[0], u.TextReset)
|
||||||
|
}
|
66
days/15_types_string.go
Normal file
66
days/15_types_string.go
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
// Code generated by "stringer -type=cellStatus,responseType,dirType -output=15_types_string.go"; DO NOT EDIT.
|
||||||
|
|
||||||
|
package days
|
||||||
|
|
||||||
|
import "strconv"
|
||||||
|
|
||||||
|
func _() {
|
||||||
|
// An "invalid array index" compiler error signifies that the constant values have changed.
|
||||||
|
// Re-run the stringer command to generate them again.
|
||||||
|
var x [1]struct{}
|
||||||
|
_ = x[cellStatusUnknown-0]
|
||||||
|
_ = x[cellStatusWall-1]
|
||||||
|
_ = x[cellStatusOpen-2]
|
||||||
|
_ = x[cellStatusGoal-3]
|
||||||
|
}
|
||||||
|
|
||||||
|
const _cellStatus_name = "cellStatusUnknowncellStatusWallcellStatusOpencellStatusGoal"
|
||||||
|
|
||||||
|
var _cellStatus_index = [...]uint8{0, 17, 31, 45, 59}
|
||||||
|
|
||||||
|
func (i cellStatus) String() string {
|
||||||
|
if i < 0 || i >= cellStatus(len(_cellStatus_index)-1) {
|
||||||
|
return "cellStatus(" + strconv.FormatInt(int64(i), 10) + ")"
|
||||||
|
}
|
||||||
|
return _cellStatus_name[_cellStatus_index[i]:_cellStatus_index[i+1]]
|
||||||
|
}
|
||||||
|
func _() {
|
||||||
|
// An "invalid array index" compiler error signifies that the constant values have changed.
|
||||||
|
// Re-run the stringer command to generate them again.
|
||||||
|
var x [1]struct{}
|
||||||
|
_ = x[responseWall-0]
|
||||||
|
_ = x[responseSuccess-1]
|
||||||
|
_ = x[responseFoundGoal-2]
|
||||||
|
}
|
||||||
|
|
||||||
|
const _responseType_name = "responseWallresponseSuccessresponseFoundGoal"
|
||||||
|
|
||||||
|
var _responseType_index = [...]uint8{0, 12, 27, 44}
|
||||||
|
|
||||||
|
func (i responseType) String() string {
|
||||||
|
if i < 0 || i >= responseType(len(_responseType_index)-1) {
|
||||||
|
return "responseType(" + strconv.FormatInt(int64(i), 10) + ")"
|
||||||
|
}
|
||||||
|
return _responseType_name[_responseType_index[i]:_responseType_index[i+1]]
|
||||||
|
}
|
||||||
|
func _() {
|
||||||
|
// An "invalid array index" compiler error signifies that the constant values have changed.
|
||||||
|
// Re-run the stringer command to generate them again.
|
||||||
|
var x [1]struct{}
|
||||||
|
_ = x[dirNorth-1]
|
||||||
|
_ = x[dirSouth-2]
|
||||||
|
_ = x[dirWest-3]
|
||||||
|
_ = x[dirEast-4]
|
||||||
|
}
|
||||||
|
|
||||||
|
const _dirType_name = "dirNorthdirSouthdirWestdirEast"
|
||||||
|
|
||||||
|
var _dirType_index = [...]uint8{0, 8, 16, 23, 30}
|
||||||
|
|
||||||
|
func (i dirType) String() string {
|
||||||
|
i -= 1
|
||||||
|
if i < 0 || i >= dirType(len(_dirType_index)-1) {
|
||||||
|
return "dirType(" + strconv.FormatInt(int64(i+1), 10) + ")"
|
||||||
|
}
|
||||||
|
return _dirType_name[_dirType_index[i]:_dirType_index[i+1]]
|
||||||
|
}
|
104
days/16.go
Normal file
104
days/16.go
Normal file
@ -0,0 +1,104 @@
|
|||||||
|
package days
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"math"
|
||||||
|
|
||||||
|
u "parnic.com/aoc2019/utilities"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Day16 struct {
|
||||||
|
numberSet []int8
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *Day16) Parse() {
|
||||||
|
numberSequence := u.GetStringContents("16p")
|
||||||
|
d.numberSet = make([]int8, len(numberSequence))
|
||||||
|
for i, numRune := range numberSequence {
|
||||||
|
d.numberSet[i] = int8(numRune - '0')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d Day16) Num() int {
|
||||||
|
return 16
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *Day16) Part1() string {
|
||||||
|
transformed := make([]int8, len(d.numberSet))
|
||||||
|
copy(transformed, d.numberSet)
|
||||||
|
|
||||||
|
transformPattern := []int8{0, 1, 0, -1}
|
||||||
|
|
||||||
|
phases := 100
|
||||||
|
workingSet := make([]int8, len(transformed))
|
||||||
|
for i := 0; i < phases; i++ {
|
||||||
|
copy(workingSet, transformed)
|
||||||
|
|
||||||
|
// fmt.Printf("Phase %d. Input signal: %v\n", (i + 1), transformed)
|
||||||
|
for destIdx := range transformed {
|
||||||
|
repeated := 0
|
||||||
|
patternIdx := 0
|
||||||
|
workingVal := int64(0)
|
||||||
|
for idx := range transformed {
|
||||||
|
if repeated >= destIdx {
|
||||||
|
repeated = 0
|
||||||
|
patternIdx++
|
||||||
|
if patternIdx == len(transformPattern) {
|
||||||
|
patternIdx = 0
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
repeated++
|
||||||
|
}
|
||||||
|
|
||||||
|
// fmt.Printf("%d*%d", transformed[idx], transformPattern[patternIdx])
|
||||||
|
// if idx < len(transformed)-1 {
|
||||||
|
// fmt.Print(" + ")
|
||||||
|
// }
|
||||||
|
workingVal += int64(transformed[idx] * transformPattern[patternIdx])
|
||||||
|
}
|
||||||
|
|
||||||
|
workingSet[destIdx] = int8(int64(math.Abs(float64(workingVal))) % 10)
|
||||||
|
// fmt.Printf(" = %d\n", workingSet[destIdx])
|
||||||
|
}
|
||||||
|
|
||||||
|
copy(transformed, workingSet)
|
||||||
|
}
|
||||||
|
|
||||||
|
finalVal := 0
|
||||||
|
for i := range transformed[0:8] {
|
||||||
|
finalVal += int(transformed[i]) * int(math.Pow10(8-1-i))
|
||||||
|
}
|
||||||
|
return fmt.Sprintf("First 8 digits of the final output list: %s%d%s", u.TextBold, finalVal, u.TextReset)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *Day16) Part2() string {
|
||||||
|
transformed := make([]int8, len(d.numberSet)*10000)
|
||||||
|
for i := 0; i < 10000; i++ {
|
||||||
|
copy(transformed[i*len(d.numberSet):(i*len(d.numberSet))+len(d.numberSet)], d.numberSet)
|
||||||
|
}
|
||||||
|
|
||||||
|
finalMsgOffset := 0
|
||||||
|
for i := 0; i < 7; i++ {
|
||||||
|
finalMsgOffset += int(d.numberSet[i]) * int(math.Pow10(7-1-i))
|
||||||
|
}
|
||||||
|
|
||||||
|
if finalMsgOffset < len(transformed)/2 {
|
||||||
|
panic("offset must be in the back half of the message for this solution to work")
|
||||||
|
}
|
||||||
|
|
||||||
|
phases := 100
|
||||||
|
for p := 0; p < phases; p++ {
|
||||||
|
rollingTotal := int8(0)
|
||||||
|
for i := len(transformed) - 1; i >= finalMsgOffset; i-- {
|
||||||
|
rollingTotal += transformed[i]
|
||||||
|
rollingTotal = rollingTotal % 10
|
||||||
|
transformed[i] = rollingTotal
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
finalVal := 0
|
||||||
|
for i := range transformed[finalMsgOffset : finalMsgOffset+8] {
|
||||||
|
finalVal += int(transformed[finalMsgOffset+i]) * int(math.Pow10(8-1-i))
|
||||||
|
}
|
||||||
|
return fmt.Sprintf("Embedded message in the final output list: %s%d%s", u.TextBold, finalVal, u.TextReset)
|
||||||
|
}
|
340
days/17.go
Normal file
340
days/17.go
Normal file
@ -0,0 +1,340 @@
|
|||||||
|
package days
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
u "parnic.com/aoc2019/utilities"
|
||||||
|
)
|
||||||
|
|
||||||
|
type camViewCellType int
|
||||||
|
type botFacing int
|
||||||
|
|
||||||
|
const (
|
||||||
|
cellTypeScaffold camViewCellType = iota
|
||||||
|
cellTypeOpen
|
||||||
|
cellTypeInvalid
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
botFacingUp botFacing = iota
|
||||||
|
botFacingLeft
|
||||||
|
botFacingDown
|
||||||
|
botFacingRight
|
||||||
|
|
||||||
|
botFacingFirst = botFacingUp
|
||||||
|
botFacingLast = botFacingRight
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
dirLeft dirType = 1
|
||||||
|
dirRight dirType = -1
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
day17AdjacentOffsets = []u.Vec2i{
|
||||||
|
{X: -1, Y: 0},
|
||||||
|
{X: 1, Y: 0},
|
||||||
|
{X: 0, Y: -1},
|
||||||
|
{X: 0, Y: 1},
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
type Day17 struct {
|
||||||
|
program u.IntcodeProgram
|
||||||
|
grid [][]camViewCellType
|
||||||
|
botLocation u.Vec2i
|
||||||
|
botFacingDir botFacing
|
||||||
|
endLocation u.Vec2i
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *Day17) Parse() {
|
||||||
|
d.program = u.LoadIntcodeProgram("17p")
|
||||||
|
d.grid = [][]camViewCellType{{}}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d Day17) Num() int {
|
||||||
|
return 17
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d Day17) Draw() {
|
||||||
|
for y := range d.grid {
|
||||||
|
for x := range d.grid[y] {
|
||||||
|
switch d.grid[y][x] {
|
||||||
|
case cellTypeOpen:
|
||||||
|
fmt.Print(" ")
|
||||||
|
case cellTypeScaffold:
|
||||||
|
char := "█"
|
||||||
|
color := u.ColorBlack
|
||||||
|
if d.botLocation.X == x && d.botLocation.Y == y {
|
||||||
|
switch d.botFacingDir {
|
||||||
|
case botFacingUp:
|
||||||
|
char = "^"
|
||||||
|
case botFacingLeft:
|
||||||
|
char = "<"
|
||||||
|
case botFacingDown:
|
||||||
|
char = "v"
|
||||||
|
case botFacingRight:
|
||||||
|
char = ">"
|
||||||
|
}
|
||||||
|
} else if d.endLocation.X == x && d.endLocation.Y == y {
|
||||||
|
char = "@"
|
||||||
|
} else {
|
||||||
|
color = u.ColorWhite
|
||||||
|
}
|
||||||
|
fmt.Printf("%s%s%s%s", u.BackgroundWhite, color, char, u.TextReset)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fmt.Println()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d Day17) getAdjacentScaffolds(y, x int) []u.Vec2i {
|
||||||
|
retval := make([]u.Vec2i, 0)
|
||||||
|
for _, offset := range day17AdjacentOffsets {
|
||||||
|
offY := y + offset.Y
|
||||||
|
offX := x + offset.X
|
||||||
|
if offY < 0 || offY >= len(d.grid) ||
|
||||||
|
offX < 0 || offX >= len(d.grid[0]) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if d.grid[offY][offX] == cellTypeScaffold {
|
||||||
|
retval = append(retval, u.Vec2i{X: offX, Y: offY})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return retval
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d Day17) getNumSurroundingScaffolds(y, x int) int {
|
||||||
|
return len(d.getAdjacentScaffolds(y, x))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d Day17) forEachCellOfType(t camViewCellType, f func(y, x int)) {
|
||||||
|
for y := range d.grid {
|
||||||
|
for x := range d.grid[y] {
|
||||||
|
if d.grid[y][x] == t {
|
||||||
|
f(y, x)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d Day17) getNewFacingDir(currentDir botFacing, turnDir dirType) botFacing {
|
||||||
|
currentDir += botFacing(turnDir)
|
||||||
|
if currentDir < botFacingFirst {
|
||||||
|
currentDir = botFacingLast
|
||||||
|
} else if currentDir > botFacingLast {
|
||||||
|
currentDir = botFacingFirst
|
||||||
|
}
|
||||||
|
|
||||||
|
return currentDir
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d Day17) getCellTypeInDirection(y, x int, facingDir botFacing) (camViewCellType, int, int) {
|
||||||
|
newX := x
|
||||||
|
newY := y
|
||||||
|
switch facingDir {
|
||||||
|
case botFacingUp:
|
||||||
|
newY--
|
||||||
|
case botFacingLeft:
|
||||||
|
newX--
|
||||||
|
case botFacingDown:
|
||||||
|
newY++
|
||||||
|
case botFacingRight:
|
||||||
|
newX++
|
||||||
|
}
|
||||||
|
|
||||||
|
if newY < 0 || newY >= len(d.grid) || newX < 0 || newX >= len(d.grid[0]) {
|
||||||
|
return cellTypeInvalid, newY, newX
|
||||||
|
}
|
||||||
|
|
||||||
|
return d.grid[newY][newX], newY, newX
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *Day17) Part1() string {
|
||||||
|
y := 0
|
||||||
|
d.program.RunIn(func(inputStep int) int64 {
|
||||||
|
return 0
|
||||||
|
}, func(val int64, state u.IntcodeProgramState) {
|
||||||
|
rVal := rune(val)
|
||||||
|
switch rVal {
|
||||||
|
case '\n':
|
||||||
|
y++
|
||||||
|
d.grid = append(d.grid, make([]camViewCellType, 0))
|
||||||
|
case '#':
|
||||||
|
d.grid[y] = append(d.grid[y], cellTypeScaffold)
|
||||||
|
case '.':
|
||||||
|
d.grid[y] = append(d.grid[y], cellTypeOpen)
|
||||||
|
case '^', '<', 'v', '>':
|
||||||
|
d.botLocation = u.Vec2i{X: len(d.grid[y]), Y: y}
|
||||||
|
d.grid[y] = append(d.grid[y], cellTypeScaffold)
|
||||||
|
switch rVal {
|
||||||
|
case '^':
|
||||||
|
d.botFacingDir = botFacingUp
|
||||||
|
case '<':
|
||||||
|
d.botFacingDir = botFacingLeft
|
||||||
|
case 'v':
|
||||||
|
d.botFacingDir = botFacingDown
|
||||||
|
case '>':
|
||||||
|
d.botFacingDir = botFacingRight
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
for y := len(d.grid) - 1; y >= 0; y-- {
|
||||||
|
if len(d.grid[y]) == 0 {
|
||||||
|
d.grid = d.grid[0 : len(d.grid)-1]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
alignmentParameterTotal := 0
|
||||||
|
d.forEachCellOfType(cellTypeScaffold, func(y, x int) {
|
||||||
|
if numSurrounding := d.getNumSurroundingScaffolds(y, x); numSurrounding == 4 {
|
||||||
|
alignmentParameterTotal += y * x
|
||||||
|
} else if numSurrounding == 1 {
|
||||||
|
if d.botLocation.X != x || d.botLocation.Y != y {
|
||||||
|
d.endLocation = u.Vec2i{X: x, Y: y}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
// d.Draw()
|
||||||
|
|
||||||
|
return fmt.Sprintf("Alignment parameter sum: %s%d%s", u.TextBold, alignmentParameterTotal, u.TextReset)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *Day17) Part2() string {
|
||||||
|
instructions := make([]string, 0)
|
||||||
|
|
||||||
|
pos := d.botLocation
|
||||||
|
botFacingDir := d.botFacingDir
|
||||||
|
for {
|
||||||
|
if pos == d.endLocation {
|
||||||
|
fmt.Println()
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
adj := d.getAdjacentScaffolds(pos.Y, pos.X)
|
||||||
|
turnDirection := dirType(0)
|
||||||
|
if botFacingDir == botFacingUp || botFacingDir == botFacingDown {
|
||||||
|
if u.ArrayContains(adj, u.Vec2i{X: pos.X - 1, Y: pos.Y}) {
|
||||||
|
if botFacingDir == botFacingUp {
|
||||||
|
turnDirection = dirLeft
|
||||||
|
} else if botFacingDir == botFacingDown {
|
||||||
|
turnDirection = dirRight
|
||||||
|
}
|
||||||
|
} else if u.ArrayContains(adj, u.Vec2i{X: pos.X + 1, Y: pos.Y}) {
|
||||||
|
if botFacingDir == botFacingUp {
|
||||||
|
turnDirection = dirRight
|
||||||
|
} else if botFacingDir == botFacingDown {
|
||||||
|
turnDirection = dirLeft
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if u.ArrayContains(adj, u.Vec2i{X: pos.X, Y: pos.Y - 1}) {
|
||||||
|
if botFacingDir == botFacingLeft {
|
||||||
|
turnDirection = dirRight
|
||||||
|
} else if botFacingDir == botFacingRight {
|
||||||
|
turnDirection = dirLeft
|
||||||
|
}
|
||||||
|
} else if u.ArrayContains(adj, u.Vec2i{X: pos.X, Y: pos.Y + 1}) {
|
||||||
|
if botFacingDir == botFacingLeft {
|
||||||
|
turnDirection = dirLeft
|
||||||
|
} else if botFacingDir == botFacingRight {
|
||||||
|
turnDirection = dirRight
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if turnDirection == 0 {
|
||||||
|
panic("at an invalid location somehow")
|
||||||
|
}
|
||||||
|
|
||||||
|
dirAscii := "L"
|
||||||
|
if turnDirection == dirRight {
|
||||||
|
dirAscii = "R"
|
||||||
|
}
|
||||||
|
instructions = append(instructions, dirAscii)
|
||||||
|
|
||||||
|
botFacingDir = d.getNewFacingDir(botFacingDir, turnDirection)
|
||||||
|
numMoved := 0
|
||||||
|
for {
|
||||||
|
cell, newY, newX := d.getCellTypeInDirection(pos.Y, pos.X, botFacingDir)
|
||||||
|
if cell != cellTypeScaffold {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
pos.X = newX
|
||||||
|
pos.Y = newY
|
||||||
|
numMoved++
|
||||||
|
}
|
||||||
|
instructions = append(instructions, fmt.Sprintf("%d", numMoved))
|
||||||
|
}
|
||||||
|
|
||||||
|
workingInstructions := make([]string, len(instructions))
|
||||||
|
copy(workingInstructions, instructions)
|
||||||
|
|
||||||
|
instructionStr := strings.Join(workingInstructions, ",")
|
||||||
|
progs := make([][]string, 3)
|
||||||
|
for i := 0; i < 3; i++ {
|
||||||
|
numFound := 3
|
||||||
|
subLen := 4
|
||||||
|
for numFound >= 3 {
|
||||||
|
numFound = 1
|
||||||
|
instructionSubset := strings.Join(workingInstructions[0:subLen], ",")
|
||||||
|
if len(instructionSubset) > 20 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
for x := len(instructionSubset); x <= len(instructionStr)-len(instructionSubset); x++ {
|
||||||
|
if instructionStr[x:x+len(instructionSubset)] == instructionSubset {
|
||||||
|
numFound++
|
||||||
|
x += len(instructionSubset)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if numFound >= 3 {
|
||||||
|
subLen += 2
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if numFound < 3 {
|
||||||
|
subLen -= 2
|
||||||
|
}
|
||||||
|
progs[i] = make([]string, subLen)
|
||||||
|
copy(progs[i], workingInstructions[0:subLen])
|
||||||
|
|
||||||
|
instructionStr = strings.ReplaceAll(instructionStr, strings.Join(progs[i], ","), "")
|
||||||
|
instructionStr = strings.TrimPrefix(strings.ReplaceAll(instructionStr, ",,", ","), ",")
|
||||||
|
|
||||||
|
if len(instructionStr) == 0 {
|
||||||
|
workingInstructions = nil
|
||||||
|
} else {
|
||||||
|
workingInstructions = strings.Split(instructionStr, ",")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if workingInstructions != nil {
|
||||||
|
panic("didn't empty instructions")
|
||||||
|
}
|
||||||
|
instructionStr = strings.Join(instructions, ",")
|
||||||
|
instructionStr = strings.ReplaceAll(instructionStr, strings.Join(progs[0], ","), "A")
|
||||||
|
instructionStr = strings.ReplaceAll(instructionStr, strings.Join(progs[1], ","), "B")
|
||||||
|
instructionStr = strings.ReplaceAll(instructionStr, strings.Join(progs[2], ","), "C")
|
||||||
|
|
||||||
|
instructionStr = fmt.Sprintf("%s\n%s\n%s\n%s\nn\n",
|
||||||
|
instructionStr,
|
||||||
|
strings.Join(progs[0], ","),
|
||||||
|
strings.Join(progs[1], ","),
|
||||||
|
strings.Join(progs[2], ","),
|
||||||
|
)
|
||||||
|
|
||||||
|
d.program.Reset()
|
||||||
|
d.program.SetMemory(0, 2)
|
||||||
|
dustCollected := int64(0)
|
||||||
|
d.program.RunIn(func(inputStep int) int64 {
|
||||||
|
return int64(instructionStr[inputStep-1])
|
||||||
|
}, func(val int64, state u.IntcodeProgramState) {
|
||||||
|
dustCollected = val
|
||||||
|
})
|
||||||
|
|
||||||
|
return fmt.Sprintf("Dust collected after traveling all paths: %s%d%s", u.TextBold, dustCollected, u.TextReset)
|
||||||
|
}
|
@ -1,14 +1,16 @@
|
|||||||
package days
|
package days
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"parnic.com/aoc2019/utilities"
|
"fmt"
|
||||||
|
|
||||||
|
u "parnic.com/aoc2019/utilities"
|
||||||
)
|
)
|
||||||
|
|
||||||
type DayTemplate struct {
|
type DayTemplate struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *DayTemplate) Parse() {
|
func (d *DayTemplate) Parse() {
|
||||||
utilities.GetIntLines("Templatep")
|
u.GetIntLines("Templatep")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d DayTemplate) Num() int {
|
func (d DayTemplate) Num() int {
|
||||||
@ -16,9 +18,9 @@ func (d DayTemplate) Num() int {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (d *DayTemplate) Part1() string {
|
func (d *DayTemplate) Part1() string {
|
||||||
return ""
|
return fmt.Sprintf("%s%d%s", u.TextBold, 0, u.TextReset)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *DayTemplate) Part2() string {
|
func (d *DayTemplate) Part2() string {
|
||||||
return ""
|
return fmt.Sprintf("%s%d%s", u.TextBold, 0, u.TextReset)
|
||||||
}
|
}
|
||||||
|
116
inputs/14p.txt
116
inputs/14p.txt
@ -1,60 +1,56 @@
|
|||||||
11 RVCS => 8 CBMDT
|
6 WBVJ, 16 CDVNK => 2 PJBZT
|
||||||
29 QXPB, 8 QRGRH => 8 LGMKD
|
135 ORE => 8 MWDXJ
|
||||||
3 VPRVD => 6 PMFZG
|
27 NBRHT, 2 NSWK, 2 CMHMQ, 29 NFCB, 11 KNGJ, 12 MGCKC, 56 NHTKL, 7 WNFSV => 1 FUEL
|
||||||
1 CNWNQ, 11 MJVXS => 6 SPLM
|
1 SFJFX, 3 MXNK => 4 NLSBZ
|
||||||
13 SPDRZ, 13 PMFZG => 2 BLFM
|
2 PFKRW, 1 VXFRX, 22 QDJCL => 6 GBDG
|
||||||
8 QWPFN => 7 LWVB
|
7 TSTF, 4 ZLJN => 7 DMWS
|
||||||
1 SPLM => 8 TKWQ
|
5 KPCF, 1 DLMDJ, 1 FNWGH => 6 TSTF
|
||||||
2 QRGRH, 6 CNWNQ => 7 DTZW
|
8 DTWKS, 1 GBDG => 4 CGZQ
|
||||||
2 DMLT, 1 SPLM, 1 TMDK => 9 NKNS
|
26 CNWZM, 4 KPCF => 3 DTWKS
|
||||||
1 MJVXS, 1 HLBV => 7 PQCQH
|
1 JVLHM, 7 DTWKS, 7 PJBZT => 8 MRPHV
|
||||||
1 JZHZP, 9 LWVB => 7 MJSCQ
|
2 MWDXJ => 3 VHFPC
|
||||||
29 DGFR => 7 QRGRH
|
1 WXNW, 6 PFKRW => 7 ZVGVP
|
||||||
14 XFLKQ, 2 NKNS, 4 KMNJF, 3 MLZGQ, 7 TKWQ, 24 WTDW, 11 CBMDT => 4 GJKX
|
2 ZVGVP => 1 CMHMQ
|
||||||
4 TKWQ, 1 WLCFR => 4 PDKGT
|
8 JVLHM, 11 XRKN, 1 HCGKZ => 8 CHZLX
|
||||||
2 NKNS => 4 GDKL
|
20 TSTF => 4 XDZMZ
|
||||||
4 WRZST => 9 XFLKQ
|
3 CMHMQ, 7 ZVGVP, 10 XRKN => 9 FNWGH
|
||||||
19 DGFR => 4 VPRVD
|
12 HCGKZ, 4 NLSBZ, 15 RWRDP, 4 MRPHV, 31 KRDV, 6 PMXK, 2 NFVZ => 7 KNGJ
|
||||||
10 MJSCQ, 4 QWPFN, 4 QXPB => 2 MLZGQ
|
1 TXZCM => 9 BMPJ
|
||||||
1 JZHZP => 7 QWPFN
|
2 ZFXQ => 3 NBRHT
|
||||||
1 XFLKQ => 9 FQGVL
|
13 JVLHM, 1 VHFPC => 3 PBJPZ
|
||||||
3 GQGXC => 9 VHGP
|
7 HCGKZ => 7 PMXK
|
||||||
3 NQZTV, 1 JZHZP => 2 NVZWL
|
2 RWRDP, 3 VSTQ, 12 PMXK => 7 MXNK
|
||||||
38 WLCFR, 15 GJKX, 44 LGMKD, 2 CBVXG, 2 GDKL, 77 FQGVL, 10 MKRCZ, 29 WJQD, 33 BWXGC, 19 PQCQH, 24 BKXD => 1 FUEL
|
1 PJBZT, 3 QRSK => 1 KRDV
|
||||||
102 ORE => 5 DGFR
|
1 MGCKC, 6 CMHMQ => 6 PQTVS
|
||||||
17 NWKLB, 1 SBPLK => 5 HRQM
|
1 TNHCS, 24 ZLJN => 4 RWRDP
|
||||||
3 BWXGC => 8 TQDP
|
5 MWDXJ, 1 WXNW => 9 QBCLF
|
||||||
1 TQDP => 2 PSZDZ
|
1 ZFXQ, 1 DLMDJ => 4 DJXRM
|
||||||
2 MJVXS => 9 WNXG
|
1 ZFXQ => 2 CNWZM
|
||||||
2 NBTW, 1 HRQM => 2 SVHBH
|
1 KPCF => 6 ZXDVF
|
||||||
8 CNWNQ, 1 DTZW => 4 RVCS
|
2 MRPHV => 1 GSTG
|
||||||
4 VHGP, 20 WNXG, 2 SVHBH => 3 SPDRZ
|
5 BMPJ, 2 ZLJN => 8 XQJZ
|
||||||
110 ORE => 5 TXMC
|
1 MWDXJ, 1 ZVGVP => 3 CDVNK
|
||||||
10 QRGRH => 5 NWKLB
|
3 NFCB, 3 CMHMQ, 1 MWDXJ => 4 XRKN
|
||||||
1 SBPLK => 3 MJVXS
|
1 WXNW, 1 TXZCM => 5 ZLJN
|
||||||
9 DGFR => 5 RFSRL
|
4 ZXDVF => 4 WBVJ
|
||||||
5 LBTV => 3 DMLT
|
2 GBDG => 4 KPCF
|
||||||
1 NWKLB, 1 KMNJF, 1 HDQXB, 6 LBTV, 2 PSZDZ, 34 PMFZG, 2 SVHBH => 2 WJQD
|
4 CHZLX, 7 ZFXQ, 14 PQTVS => 9 VSTQ
|
||||||
1 RVCS => 5 MKRCZ
|
3 TXZCM, 7 ZLJN, 7 ZXDVF => 9 JVLHM
|
||||||
14 NQZTV, 3 FPLT, 1 SJMS => 2 GQGXC
|
1 DMWS, 3 TSTF => 5 HCGKZ
|
||||||
18 RFSRL, 13 VHGP, 23 NBTW => 5 WTDW
|
2 CGZQ => 4 NFVZ
|
||||||
1 VHGP, 6 TKWQ => 7 QXPB
|
2 PQTVS, 9 VMNJ => 9 TXZCM
|
||||||
1 JZHZP, 1 CNWNQ => 5 KMNJF
|
3 KPCF => 4 DLMDJ
|
||||||
109 ORE => 9 BWXGC
|
7 VMNJ, 24 XQJZ, 7 GSTG, 8 NLSBZ, 10 MGCKC, 2 SFJFX, 18 BMPJ => 1 NSWK
|
||||||
2 CNWNQ, 1 PDKGT, 2 KMNJF => 5 HDQXB
|
41 CNWZM, 5 DJXRM, 1 QRSK, 1 KPCF, 15 XDZMZ, 3 MRPHV, 1 NLSBZ, 9 KRDV => 2 WNFSV
|
||||||
1 PDKGT, 18 WRZST, 9 MJSCQ, 3 VHGP, 1 BLFM, 1 LGMKD, 7 WLCFR => 2 BKXD
|
10 PBJPZ, 29 BMPJ, 2 PMXK => 7 SFJFX
|
||||||
11 MLJK => 6 FPLT
|
116 ORE => 4 WXNW
|
||||||
8 DGFR, 2 TXMC, 3 WJRC => 9 SJMS
|
2 CNWZM => 2 TNHCS
|
||||||
2 SBPLK => 1 LBTV
|
10 QBCLF => 7 NFCB
|
||||||
22 QWPFN => 4 WRZST
|
1 QBCLF => 2 ZFXQ
|
||||||
5 WRZST, 22 WNXG, 1 VHGP => 7 NBTW
|
15 ZLJN => 7 QRSK
|
||||||
7 RVCS => 9 TMDK
|
183 ORE => 3 QDJCL
|
||||||
1 DGFR, 14 TXMC => 5 JZHZP
|
11 GBDG => 5 VMNJ
|
||||||
2 JZHZP => 3 SBPLK
|
4 DMWS, 3 QRSK => 3 NHTKL
|
||||||
19 PDKGT => 8 HLBV
|
124 ORE => 6 VXFRX
|
||||||
195 ORE => 6 WJRC
|
1 MWDXJ => 6 MGCKC
|
||||||
6 GQGXC => 8 CNWNQ
|
108 ORE => 9 PFKRW
|
||||||
1 NVZWL, 4 GQGXC => 2 CBVXG
|
|
||||||
1 NVZWL, 1 KMNJF => 8 WLCFR
|
|
||||||
153 ORE => 4 MLJK
|
|
||||||
1 BWXGC => 6 NQZTV
|
|
1
inputs/15p.txt
Normal file
1
inputs/15p.txt
Normal file
@ -0,0 +1 @@
|
|||||||
|
3,1033,1008,1033,1,1032,1005,1032,31,1008,1033,2,1032,1005,1032,58,1008,1033,3,1032,1005,1032,81,1008,1033,4,1032,1005,1032,104,99,102,1,1034,1039,101,0,1036,1041,1001,1035,-1,1040,1008,1038,0,1043,102,-1,1043,1032,1,1037,1032,1042,1105,1,124,102,1,1034,1039,1001,1036,0,1041,1001,1035,1,1040,1008,1038,0,1043,1,1037,1038,1042,1105,1,124,1001,1034,-1,1039,1008,1036,0,1041,1001,1035,0,1040,1001,1038,0,1043,1002,1037,1,1042,1105,1,124,1001,1034,1,1039,1008,1036,0,1041,102,1,1035,1040,101,0,1038,1043,1001,1037,0,1042,1006,1039,217,1006,1040,217,1008,1039,40,1032,1005,1032,217,1008,1040,40,1032,1005,1032,217,1008,1039,3,1032,1006,1032,165,1008,1040,33,1032,1006,1032,165,1101,0,2,1044,1105,1,224,2,1041,1043,1032,1006,1032,179,1101,1,0,1044,1106,0,224,1,1041,1043,1032,1006,1032,217,1,1042,1043,1032,1001,1032,-1,1032,1002,1032,39,1032,1,1032,1039,1032,101,-1,1032,1032,101,252,1032,211,1007,0,37,1044,1106,0,224,1102,1,0,1044,1105,1,224,1006,1044,247,101,0,1039,1034,101,0,1040,1035,1001,1041,0,1036,1002,1043,1,1038,101,0,1042,1037,4,1044,1106,0,0,42,4,15,10,25,91,86,34,69,14,50,9,24,24,54,10,18,63,17,2,88,36,31,60,20,13,20,76,94,25,41,36,78,3,39,17,94,10,25,22,16,67,72,31,47,15,25,66,8,17,54,8,89,67,29,28,92,11,54,14,4,64,78,28,80,66,6,70,36,56,13,63,17,19,83,17,27,29,34,54,4,93,24,71,6,66,22,21,92,93,39,4,31,76,72,25,74,89,18,62,18,27,57,35,83,39,14,23,95,2,79,25,97,86,13,79,1,34,90,81,29,45,31,38,67,17,92,32,31,50,1,42,81,1,2,87,7,52,74,20,85,22,32,47,16,77,96,28,14,74,22,55,15,75,44,29,19,8,73,2,54,18,26,64,95,21,98,48,25,36,11,78,77,5,16,70,18,10,76,51,51,10,25,43,56,12,13,48,8,17,68,10,64,25,93,42,3,52,24,72,99,23,54,13,44,17,15,8,68,59,15,95,61,9,50,8,51,23,8,39,13,95,64,12,28,56,90,1,62,27,12,60,6,5,18,24,13,99,12,18,92,97,7,56,22,48,91,34,87,32,98,20,89,74,16,51,84,21,46,14,23,52,17,57,12,50,17,97,23,99,11,21,68,21,61,89,13,45,64,89,18,36,40,35,90,9,1,3,81,33,32,83,99,97,34,4,46,31,21,90,62,14,93,11,22,99,51,70,88,51,2,4,29,36,35,48,17,25,30,69,34,3,39,89,31,89,33,30,88,77,18,30,67,17,40,61,19,40,85,26,23,49,22,41,30,13,79,6,34,40,33,43,49,84,19,78,43,10,74,18,61,15,22,51,86,2,78,11,33,92,24,88,27,24,44,2,97,4,4,49,72,93,24,65,79,21,60,33,46,36,22,15,87,33,78,2,49,70,7,78,78,11,14,64,41,61,41,6,1,49,35,78,47,65,14,66,10,86,76,2,32,88,3,24,14,87,9,95,32,19,4,10,67,60,15,19,53,47,24,29,65,5,95,35,1,70,16,43,53,11,64,17,34,84,74,65,30,18,58,2,35,48,38,33,46,16,87,27,12,79,11,88,35,7,5,35,67,83,38,6,17,56,82,13,45,32,30,67,25,62,7,43,63,9,36,14,58,53,25,98,12,38,78,13,63,93,33,11,54,9,66,32,79,62,47,28,6,67,31,53,71,2,30,59,12,90,59,67,2,58,52,1,30,51,49,22,89,88,27,19,41,27,13,19,76,5,82,58,12,49,51,17,15,73,35,25,74,90,29,14,96,83,69,11,18,14,10,40,93,35,31,35,36,58,36,16,48,7,66,98,31,47,34,47,33,5,28,82,88,1,30,80,95,32,87,2,19,91,74,74,19,8,25,63,65,51,30,14,41,98,99,21,90,15,91,3,31,74,27,31,77,28,74,4,27,88,82,11,54,35,52,13,88,71,93,20,82,18,36,68,33,83,1,18,5,42,46,29,62,10,78,67,9,84,48,22,33,74,36,53,58,31,5,8,55,10,24,49,34,81,1,4,86,5,25,2,75,36,49,2,24,88,72,8,64,36,38,10,23,36,93,28,51,90,4,99,57,31,10,14,94,21,27,61,34,70,41,32,14,91,20,83,30,54,26,44,30,85,96,87,35,16,61,99,16,32,53,68,87,1,89,43,9,17,4,39,50,61,8,49,27,48,13,51,34,47,30,89,68,50,18,63,99,50,32,41,33,71,1,43,57,64,24,95,9,89,8,64,18,75,23,97,74,67,24,55,1,87,97,44,0,0,21,21,1,10,1,0,0,0,0,0,0
|
1
inputs/16p.txt
Normal file
1
inputs/16p.txt
Normal file
@ -0,0 +1 @@
|
|||||||
|
59791875142707344554745984624833270124746225787022156176259864082972613206097260696475359886661459314067969858521185244807128606896674972341093111690401527976891268108040443281821862422244152800144859031661510297789792278726877676645835805097902853584093615895099152578276185267316851163313487136731134073054989870018294373731775466754420075119913101001966739563592696702233028356328979384389178001923889641041703308599918672055860556825287836987992883550004999016194930620165247185883506733712391462975446192414198344745434022955974228926237100271949068464343172968939069550036969073411905889066207300644632441054836725463178144030305115977951503567
|
1
inputs/16s1.txt
Normal file
1
inputs/16s1.txt
Normal file
@ -0,0 +1 @@
|
|||||||
|
12345678
|
1
inputs/16s2.txt
Normal file
1
inputs/16s2.txt
Normal file
@ -0,0 +1 @@
|
|||||||
|
80871224585914546619083218645595
|
1
inputs/16s3.txt
Normal file
1
inputs/16s3.txt
Normal file
@ -0,0 +1 @@
|
|||||||
|
19617804207202209144916044189917
|
1
inputs/16s4.txt
Normal file
1
inputs/16s4.txt
Normal file
@ -0,0 +1 @@
|
|||||||
|
69317163492948606335995924319873
|
1
inputs/17p.txt
Normal file
1
inputs/17p.txt
Normal file
@ -0,0 +1 @@
|
|||||||
|
1,330,331,332,109,2734,1102,1182,1,15,1102,1,1429,24,1002,0,1,570,1006,570,36,1001,571,0,0,1001,570,-1,570,1001,24,1,24,1106,0,18,1008,571,0,571,1001,15,1,15,1008,15,1429,570,1006,570,14,21102,58,1,0,1105,1,786,1006,332,62,99,21101,0,333,1,21102,73,1,0,1105,1,579,1101,0,0,572,1101,0,0,573,3,574,101,1,573,573,1007,574,65,570,1005,570,151,107,67,574,570,1005,570,151,1001,574,-64,574,1002,574,-1,574,1001,572,1,572,1007,572,11,570,1006,570,165,101,1182,572,127,1001,574,0,0,3,574,101,1,573,573,1008,574,10,570,1005,570,189,1008,574,44,570,1006,570,158,1105,1,81,21102,1,340,1,1105,1,177,21101,0,477,1,1106,0,177,21101,0,514,1,21101,0,176,0,1106,0,579,99,21102,1,184,0,1106,0,579,4,574,104,10,99,1007,573,22,570,1006,570,165,1001,572,0,1182,21102,1,375,1,21101,211,0,0,1106,0,579,21101,1182,11,1,21102,1,222,0,1105,1,979,21102,1,388,1,21102,233,1,0,1105,1,579,21101,1182,22,1,21101,0,244,0,1106,0,979,21101,401,0,1,21101,0,255,0,1105,1,579,21101,1182,33,1,21102,266,1,0,1106,0,979,21102,1,414,1,21102,1,277,0,1106,0,579,3,575,1008,575,89,570,1008,575,121,575,1,575,570,575,3,574,1008,574,10,570,1006,570,291,104,10,21102,1182,1,1,21101,313,0,0,1106,0,622,1005,575,327,1102,1,1,575,21102,327,1,0,1105,1,786,4,438,99,0,1,1,6,77,97,105,110,58,10,33,10,69,120,112,101,99,116,101,100,32,102,117,110,99,116,105,111,110,32,110,97,109,101,32,98,117,116,32,103,111,116,58,32,0,12,70,117,110,99,116,105,111,110,32,65,58,10,12,70,117,110,99,116,105,111,110,32,66,58,10,12,70,117,110,99,116,105,111,110,32,67,58,10,23,67,111,110,116,105,110,117,111,117,115,32,118,105,100,101,111,32,102,101,101,100,63,10,0,37,10,69,120,112,101,99,116,101,100,32,82,44,32,76,44,32,111,114,32,100,105,115,116,97,110,99,101,32,98,117,116,32,103,111,116,58,32,36,10,69,120,112,101,99,116,101,100,32,99,111,109,109,97,32,111,114,32,110,101,119,108,105,110,101,32,98,117,116,32,103,111,116,58,32,43,10,68,101,102,105,110,105,116,105,111,110,115,32,109,97,121,32,98,101,32,97,116,32,109,111,115,116,32,50,48,32,99,104,97,114,97,99,116,101,114,115,33,10,94,62,118,60,0,1,0,-1,-1,0,1,0,0,0,0,0,0,1,6,0,0,109,4,1202,-3,1,587,20101,0,0,-1,22101,1,-3,-3,21101,0,0,-2,2208,-2,-1,570,1005,570,617,2201,-3,-2,609,4,0,21201,-2,1,-2,1105,1,597,109,-4,2106,0,0,109,5,2102,1,-4,630,20102,1,0,-2,22101,1,-4,-4,21102,0,1,-3,2208,-3,-2,570,1005,570,781,2201,-4,-3,652,21002,0,1,-1,1208,-1,-4,570,1005,570,709,1208,-1,-5,570,1005,570,734,1207,-1,0,570,1005,570,759,1206,-1,774,1001,578,562,684,1,0,576,576,1001,578,566,692,1,0,577,577,21101,0,702,0,1105,1,786,21201,-1,-1,-1,1106,0,676,1001,578,1,578,1008,578,4,570,1006,570,724,1001,578,-4,578,21101,0,731,0,1106,0,786,1105,1,774,1001,578,-1,578,1008,578,-1,570,1006,570,749,1001,578,4,578,21101,0,756,0,1106,0,786,1106,0,774,21202,-1,-11,1,22101,1182,1,1,21102,774,1,0,1105,1,622,21201,-3,1,-3,1105,1,640,109,-5,2106,0,0,109,7,1005,575,802,21002,576,1,-6,20101,0,577,-5,1105,1,814,21102,1,0,-1,21102,1,0,-5,21102,0,1,-6,20208,-6,576,-2,208,-5,577,570,22002,570,-2,-2,21202,-5,29,-3,22201,-6,-3,-3,22101,1429,-3,-3,1202,-3,1,843,1005,0,863,21202,-2,42,-4,22101,46,-4,-4,1206,-2,924,21102,1,1,-1,1105,1,924,1205,-2,873,21102,1,35,-4,1105,1,924,1202,-3,1,878,1008,0,1,570,1006,570,916,1001,374,1,374,2101,0,-3,895,1101,2,0,0,2102,1,-3,902,1001,438,0,438,2202,-6,-5,570,1,570,374,570,1,570,438,438,1001,578,558,922,20101,0,0,-4,1006,575,959,204,-4,22101,1,-6,-6,1208,-6,29,570,1006,570,814,104,10,22101,1,-5,-5,1208,-5,45,570,1006,570,810,104,10,1206,-1,974,99,1206,-1,974,1101,1,0,575,21101,973,0,0,1105,1,786,99,109,-7,2105,1,0,109,6,21101,0,0,-4,21102,1,0,-3,203,-2,22101,1,-3,-3,21208,-2,82,-1,1205,-1,1030,21208,-2,76,-1,1205,-1,1037,21207,-2,48,-1,1205,-1,1124,22107,57,-2,-1,1205,-1,1124,21201,-2,-48,-2,1105,1,1041,21102,-4,1,-2,1106,0,1041,21101,-5,0,-2,21201,-4,1,-4,21207,-4,11,-1,1206,-1,1138,2201,-5,-4,1059,1201,-2,0,0,203,-2,22101,1,-3,-3,21207,-2,48,-1,1205,-1,1107,22107,57,-2,-1,1205,-1,1107,21201,-2,-48,-2,2201,-5,-4,1090,20102,10,0,-1,22201,-2,-1,-2,2201,-5,-4,1103,2101,0,-2,0,1106,0,1060,21208,-2,10,-1,1205,-1,1162,21208,-2,44,-1,1206,-1,1131,1105,1,989,21101,439,0,1,1105,1,1150,21102,1,477,1,1105,1,1150,21102,1,514,1,21102,1,1149,0,1105,1,579,99,21101,1157,0,0,1106,0,579,204,-2,104,10,99,21207,-3,22,-1,1206,-1,1138,2101,0,-5,1176,1202,-4,1,0,109,-6,2105,1,0,6,5,28,1,28,1,28,1,28,1,28,1,20,11,1,7,10,1,7,1,1,1,1,1,5,1,10,1,5,11,1,1,10,1,5,1,1,1,1,1,1,1,3,1,1,1,10,9,1,1,1,1,1,5,16,1,3,1,1,1,1,1,1,1,18,5,1,1,1,1,1,1,24,1,1,1,1,1,24,1,1,1,1,1,24,1,1,1,1,1,24,5,7,1,18,1,9,1,18,1,9,1,18,1,9,1,18,1,9,1,18,1,9,1,12,7,9,1,12,1,15,1,12,1,15,1,12,1,15,1,12,1,15,1,12,1,15,1,2,5,5,1,9,7,2,1,3,1,5,1,9,1,8,1,3,1,5,1,9,1,8,1,3,1,5,1,9,1,8,1,3,13,3,1,8,1,9,1,5,1,3,1,8,11,5,1,1,5,22,1,1,1,1,1,1,1,22,1,1,1,1,1,1,1,22,1,1,1,1,1,1,1,22,13,18,1,1,1,1,1,5,1,16,5,1,1,5,1,16,1,1,1,3,1,5,1,16,1,1,11,16,1,5,1,22,7,6
|
3
main.go
3
main.go
@ -45,6 +45,9 @@ var dayMap = []day{
|
|||||||
&days.Day12{},
|
&days.Day12{},
|
||||||
&days.Day13{},
|
&days.Day13{},
|
||||||
&days.Day14{},
|
&days.Day14{},
|
||||||
|
&days.Day15{},
|
||||||
|
&days.Day16{},
|
||||||
|
&days.Day17{},
|
||||||
}
|
}
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
|
@ -27,6 +27,7 @@ type IntcodeProgram struct {
|
|||||||
memory []int64
|
memory []int64
|
||||||
program []int64
|
program []int64
|
||||||
relativeBase int
|
relativeBase int
|
||||||
|
haltRequested bool
|
||||||
}
|
}
|
||||||
|
|
||||||
type IntcodeProgramState struct {
|
type IntcodeProgramState struct {
|
||||||
@ -141,7 +142,7 @@ func (p *IntcodeProgram) RunIn(inputFunc ProvideInputFunc, outputFunc ReceiveOut
|
|||||||
p.init()
|
p.init()
|
||||||
|
|
||||||
inputsRequested := 0
|
inputsRequested := 0
|
||||||
for instructionPointer := 0; instructionPointer < len(p.program); {
|
for instructionPointer := 0; instructionPointer < len(p.program) && !p.haltRequested; {
|
||||||
instruction := p.GetMemory(instructionPointer)
|
instruction := p.GetMemory(instructionPointer)
|
||||||
instructionPointer++
|
instructionPointer++
|
||||||
|
|
||||||
@ -247,4 +248,10 @@ func (p *IntcodeProgram) RunIn(inputFunc ProvideInputFunc, outputFunc ReceiveOut
|
|||||||
panic(fmt.Sprintf("exception executing program - unhandled opcode %d", opcode))
|
panic(fmt.Sprintf("exception executing program - unhandled opcode %d", opcode))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
p.haltRequested = false
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *IntcodeProgram) Stop() {
|
||||||
|
p.haltRequested = true
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
package utilities
|
package utilities
|
||||||
|
|
||||||
|
import "math"
|
||||||
|
|
||||||
func GCD[T Integer](a, b T) T {
|
func GCD[T Integer](a, b T) T {
|
||||||
if b == 0 {
|
if b == 0 {
|
||||||
return a
|
return a
|
||||||
@ -25,3 +27,23 @@ func LCM[T Integer](nums ...T) uint64 {
|
|||||||
func lcm[T Integer](a, b T) uint64 {
|
func lcm[T Integer](a, b T) uint64 {
|
||||||
return uint64(a*b) / uint64(GCD(a, b))
|
return uint64(a*b) / uint64(GCD(a, b))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func Min[T Number](nums ...T) T {
|
||||||
|
numNums := len(nums)
|
||||||
|
if numNums == 2 {
|
||||||
|
return T(math.Min(float64(nums[0]), float64(nums[1])))
|
||||||
|
}
|
||||||
|
|
||||||
|
if numNums == 0 {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
least := nums[0]
|
||||||
|
for i := 1; i < numNums; i++ {
|
||||||
|
if nums[i] < least {
|
||||||
|
least = nums[i]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return least
|
||||||
|
}
|
||||||
|
@ -4,7 +4,7 @@ type Permutable interface {
|
|||||||
~int | ~int8 | ~int16 | ~int32 | ~int64 | ~uint | ~uint8 | ~uint16 | ~uint32 | ~uint64
|
~int | ~int8 | ~int16 | ~int32 | ~int64 | ~uint | ~uint8 | ~uint16 | ~uint32 | ~uint64
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetPermutations[T Permutable](arr []T) [][]T {
|
func GetPermutations[T Permutable](arr ...T) [][]T {
|
||||||
var helper func([]T, int)
|
var helper func([]T, int)
|
||||||
res := [][]T{}
|
res := [][]T{}
|
||||||
|
|
||||||
|
@ -13,6 +13,8 @@ type Vec3[T Number] struct {
|
|||||||
Z T
|
Z T
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type Vec2i Vec2[int]
|
||||||
|
|
||||||
func (v Vec2[T]) Dot(other Vec2[T]) T {
|
func (v Vec2[T]) Dot(other Vec2[T]) T {
|
||||||
return (v.X * other.X) + (v.Y * other.Y)
|
return (v.X * other.X) + (v.Y * other.Y)
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user