2022 Day 23 Complete
This commit is contained in:
parent
667c3a4dc9
commit
cdc31b204b
2643
2022/day21/input
Normal file
2643
2022/day21/input
Normal file
File diff suppressed because it is too large
Load Diff
143
2022/day21/main.go
Normal file
143
2022/day21/main.go
Normal file
@ -0,0 +1,143 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
h "git.bullercodeworks.com/brian/adventofcode/helpers"
|
||||
)
|
||||
|
||||
var output []string
|
||||
|
||||
func main() {
|
||||
inp := h.StdinToStringSlice()
|
||||
part1(inp)
|
||||
part2(inp)
|
||||
}
|
||||
|
||||
func showLog() {
|
||||
fmt.Println(h.CLEAR_SCREEN)
|
||||
fmt.Println(strings.Join(output, "\n"))
|
||||
}
|
||||
|
||||
func setLog(v ...string) {
|
||||
output = []string{}
|
||||
log(v...)
|
||||
}
|
||||
func log(v ...string) {
|
||||
output = append(output, v...)
|
||||
}
|
||||
|
||||
func loadMonkeys(inp []string) map[string]*Monkey {
|
||||
monkeys := make(map[string]*Monkey)
|
||||
for _, v := range inp {
|
||||
if len(v) == 0 {
|
||||
break
|
||||
}
|
||||
m := NewMonkey(strings.Split(v, ": ")...)
|
||||
monkeys[m.name] = m
|
||||
}
|
||||
for _, v := range monkeys {
|
||||
v.init(monkeys, 1)
|
||||
}
|
||||
return monkeys
|
||||
}
|
||||
|
||||
func part1(inp []string) {
|
||||
monkeys := loadMonkeys(inp)
|
||||
log("# Part 1", fmt.Sprintf("%d", monkeys["root"].Value()))
|
||||
showLog()
|
||||
}
|
||||
|
||||
func part2(inp []string) {
|
||||
fmt.Println()
|
||||
monkeys := loadMonkeys(inp)
|
||||
|
||||
m1 := monkeys["root"].inp1 // <- Human is in here
|
||||
m2 := monkeys["root"].inp2 // <- We need to make it match this
|
||||
monkeys["humn"].Value = func() int { return 0 }
|
||||
fmt.Println(m1.Value(), m2.Value())
|
||||
monkeys["humn"].Value = func() int { return 1000 }
|
||||
fmt.Println(m1.Value(), m2.Value())
|
||||
//v := monkeys["root"].Value()
|
||||
|
||||
/*
|
||||
i := 0
|
||||
var lastV int
|
||||
for {
|
||||
monkeys["humn"].Value = func() int {
|
||||
return i
|
||||
}
|
||||
v := monkeys["root"].Value()
|
||||
if v == 0 {
|
||||
output = append(output[:1], []string{"# Part 2", fmt.Sprintf("Found: %d", i)}...)
|
||||
showLog()
|
||||
return
|
||||
}
|
||||
output = append(output[:3], []string{
|
||||
"# Part 2",
|
||||
fmt.Sprintf("Scanning... [ humn: %d ]", i),
|
||||
fmt.Sprintf("CURR: %d =? 0", v),
|
||||
fmt.Sprintf("LAST: %d", lastV),
|
||||
}...)
|
||||
setLog(output...)
|
||||
showLog()
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
type Operation int
|
||||
|
||||
const (
|
||||
opAdd = iota
|
||||
opSub
|
||||
opMlt
|
||||
opDiv
|
||||
)
|
||||
|
||||
type Monkey struct {
|
||||
name string
|
||||
op Operation
|
||||
inp1, inp2 *Monkey
|
||||
rawValue string
|
||||
Value func() int
|
||||
}
|
||||
|
||||
func NewMonkey(inp ...string) *Monkey { return &Monkey{name: inp[0], rawValue: inp[1]} }
|
||||
func (m *Monkey) init(monkeys map[string]*Monkey, part int) {
|
||||
pts := strings.Fields(m.rawValue)
|
||||
if len(pts) == 1 {
|
||||
m.Value = func() int { return h.Atoi(pts[0]) }
|
||||
} else {
|
||||
if part == 2 && m.name == "root" {
|
||||
pts[1] = "-"
|
||||
}
|
||||
m.inp1, m.inp2 = monkeys[pts[0]], monkeys[pts[2]]
|
||||
switch pts[1] {
|
||||
case "+":
|
||||
m.Value = func() int {
|
||||
return m.inp1.Value() + m.inp2.Value()
|
||||
}
|
||||
case "-":
|
||||
m.Value = func() int {
|
||||
return m.inp1.Value() - m.inp2.Value()
|
||||
}
|
||||
case "*":
|
||||
m.Value = func() int {
|
||||
return m.inp1.Value() * m.inp2.Value()
|
||||
}
|
||||
case "/":
|
||||
m.Value = func() int {
|
||||
return m.inp1.Value() / m.inp2.Value()
|
||||
}
|
||||
case "=":
|
||||
m.Value = func() int {
|
||||
if m.inp1.Value() == m.inp2.Value() {
|
||||
return 1
|
||||
} else {
|
||||
return 0
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
102
2022/day21/problem
Normal file
102
2022/day21/problem
Normal file
@ -0,0 +1,102 @@
|
||||
Advent of Code
|
||||
|
||||
• [About]
|
||||
• [Events]
|
||||
• [Shop]
|
||||
• [Settings]
|
||||
• [Log Out]
|
||||
|
||||
br0xen (AoC++) 35*
|
||||
|
||||
/*2022*/
|
||||
|
||||
• [Calendar]
|
||||
• [AoC++]
|
||||
• [Sponsors]
|
||||
• [Leaderboard]
|
||||
• [Stats]
|
||||
|
||||
Our sponsors help make Advent of Code possible:
|
||||
Teradyne - Do you like coding algorithms where milliseconds matter? What about nanoseconds?
|
||||
|
||||
--- Day 21: Monkey Math ---
|
||||
|
||||
The monkeys are back! You're worried they're going to try to steal your stuff again, but it seems like they're just
|
||||
holding their ground and making various monkey noises at you.
|
||||
|
||||
Eventually, one of the elephants realizes you don't speak monkey and comes over to interpret. As it turns out, they
|
||||
overheard you talking about trying to find the grove; they can show you a shortcut if you answer their riddle.
|
||||
|
||||
Each monkey is given a job: either to yell a specific number or to yell the result of a math operation. All of the
|
||||
number-yelling monkeys know their number from the start; however, the math operation monkeys need to wait for two other
|
||||
monkeys to yell a number, and those two other monkeys might also be waiting on other monkeys.
|
||||
|
||||
Your job is to work out the number the monkey named root will yell before the monkeys figure it out themselves.
|
||||
|
||||
For example:
|
||||
|
||||
root: pppw + sjmn
|
||||
dbpl: 5
|
||||
cczh: sllz + lgvd
|
||||
zczc: 2
|
||||
ptdq: humn - dvpt
|
||||
dvpt: 3
|
||||
lfqf: 4
|
||||
humn: 5
|
||||
ljgn: 2
|
||||
sjmn: drzm * dbpl
|
||||
sllz: 4
|
||||
pppw: cczh / lfqf
|
||||
lgvd: ljgn * ptdq
|
||||
drzm: hmdt - zczc
|
||||
hmdt: 32
|
||||
|
||||
Each line contains the name of a monkey, a colon, and then the job of that monkey:
|
||||
|
||||
• A lone number means the monkey's job is simply to yell that number.
|
||||
• A job like aaaa + bbbb means the monkey waits for monkeys aaaa and bbbb to yell each of their numbers; the monkey
|
||||
then yells the sum of those two numbers.
|
||||
• aaaa - bbbb means the monkey yells aaaa's number minus bbbb's number.
|
||||
• Job aaaa * bbbb will yell aaaa's number multiplied by bbbb's number.
|
||||
• Job aaaa / bbbb will yell aaaa's number divided by bbbb's number.
|
||||
|
||||
So, in the above example, monkey drzm has to wait for monkeys hmdt and zczc to yell their numbers. Fortunately, both
|
||||
hmdt and zczc have jobs that involve simply yelling a single number, so they do this immediately: 32 and 2. Monkey drzm
|
||||
can then yell its number by finding 32 minus 2: 30.
|
||||
|
||||
Then, monkey sjmn has one of its numbers (30, from monkey drzm), and already has its other number, 5, from dbpl. This
|
||||
allows it to yell its own number by finding 30 multiplied by 5: 150.
|
||||
|
||||
This process continues until root yells a number: 152.
|
||||
|
||||
However, your actual situation involves considerably more monkeys. What number will the monkey named root yell?
|
||||
|
||||
To begin, get your puzzle input.
|
||||
|
||||
Answer: _____________________ [ [Submit] ]
|
||||
|
||||
You can also [Shareon Twitter Mastodon] this puzzle.
|
||||
|
||||
References
|
||||
|
||||
Visible links
|
||||
. https://adventofcode.com/
|
||||
. https://adventofcode.com/2022/about
|
||||
. https://adventofcode.com/2022/events
|
||||
. https://teespring.com/stores/advent-of-code
|
||||
. https://adventofcode.com/2022/settings
|
||||
. https://adventofcode.com/2022/auth/logout
|
||||
. Advent of Code Supporter
|
||||
https://adventofcode.com/2022/support
|
||||
. https://adventofcode.com/2022
|
||||
. https://adventofcode.com/2022
|
||||
. https://adventofcode.com/2022/support
|
||||
. https://adventofcode.com/2022/sponsors
|
||||
. https://adventofcode.com/2022/leaderboard
|
||||
. https://adventofcode.com/2022/stats
|
||||
. https://adventofcode.com/2022/sponsors
|
||||
. https://jobs.teradyne.com/?utm_source=adventofcode&utm_medium=ad&utm_campaign=2022
|
||||
. https://adventofcode.com/2022/day/11
|
||||
. https://adventofcode.com/2022/day/21/input
|
||||
. https://twitter.com/intent/tweet?text=%22Monkey+Math%22+%2D+Day+21+%2D+Advent+of+Code+2022&url=https%3A%2F%2Fadventofcode%2Ecom%2F2022%2Fday%2F21&related=ericwastl&hashtags=AdventOfCode
|
||||
. javascript:void(0);
|
15
2022/day21/testinput
Normal file
15
2022/day21/testinput
Normal file
@ -0,0 +1,15 @@
|
||||
root: pppw + sjmn
|
||||
dbpl: 5
|
||||
cczh: sllz + lgvd
|
||||
zczc: 2
|
||||
ptdq: humn - dvpt
|
||||
dvpt: 3
|
||||
lfqf: 4
|
||||
humn: 5
|
||||
ljgn: 2
|
||||
sjmn: drzm * dbpl
|
||||
sllz: 4
|
||||
pppw: cczh / lfqf
|
||||
lgvd: ljgn * ptdq
|
||||
drzm: hmdt - zczc
|
||||
hmdt: 32
|
202
2022/day22/input
Normal file
202
2022/day22/input
Normal file
File diff suppressed because one or more lines are too long
308
2022/day22/input-m
Normal file
308
2022/day22/input-m
Normal file
File diff suppressed because one or more lines are too long
422
2022/day22/main.go
Normal file
422
2022/day22/main.go
Normal file
@ -0,0 +1,422 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"math"
|
||||
|
||||
h "git.bullercodeworks.com/brian/adventofcode/helpers"
|
||||
)
|
||||
|
||||
func main() {
|
||||
inp := h.StdinToStringSlice()
|
||||
//part1(inp)
|
||||
part2(inp)
|
||||
}
|
||||
func part1(inp []string) {
|
||||
board, inst := inp[:len(inp)-2], inp[len(inp)-1]
|
||||
b := BuildBoard(board)
|
||||
var count int
|
||||
var turn byte
|
||||
fmt.Println(b)
|
||||
fmt.Println(b.pos)
|
||||
for len(inst) > 0 {
|
||||
count, turn, inst = getNextInstructions(inst)
|
||||
b.Move(count)
|
||||
if turn == 'L' || turn == 'R' {
|
||||
b.Turn(turn)
|
||||
}
|
||||
}
|
||||
fmt.Println("Password:", b.Password())
|
||||
}
|
||||
|
||||
func part2(inp []string) {
|
||||
board, inst := inp[:len(inp)-2], inp[len(inp)-1]
|
||||
b := BuildCubeBoard(board)
|
||||
var count int
|
||||
var turn byte
|
||||
fmt.Println(b)
|
||||
fmt.Println(b.pos)
|
||||
for len(inst) > 0 {
|
||||
count, turn, inst = getNextInstructions(inst)
|
||||
b.Move(count)
|
||||
if turn == 'L' || turn == 'R' {
|
||||
b.Turn(turn)
|
||||
}
|
||||
}
|
||||
fmt.Println("Password:", b.Password())
|
||||
}
|
||||
|
||||
func getNextInstructions(inst string) (int, byte, string) {
|
||||
for i := range inst {
|
||||
if inst[i] == 'L' || inst[i] == 'R' {
|
||||
return h.Atoi(inst[:i]), inst[i], inst[i+1:]
|
||||
}
|
||||
}
|
||||
return h.Atoi(inst), 0, ""
|
||||
}
|
||||
|
||||
const (
|
||||
dirR = iota
|
||||
dirD
|
||||
dirL
|
||||
dirU
|
||||
dirErr
|
||||
|
||||
sideTop = iota
|
||||
sideBottom
|
||||
sideRight
|
||||
sideLeft
|
||||
sideFront
|
||||
sideBack
|
||||
)
|
||||
|
||||
type CubeBoard struct {
|
||||
Top *CubeBoardSide
|
||||
Bottom *CubeBoardSide
|
||||
Left *CubeBoardSide
|
||||
Right *CubeBoardSide
|
||||
Front *CubeBoardSide
|
||||
Back *CubeBoardSide
|
||||
|
||||
// Pos now holds:
|
||||
// y, x, dir, side
|
||||
pos []int
|
||||
}
|
||||
|
||||
// For the purposes of directions, we treat the board like this:
|
||||
// [T]
|
||||
// [B][L][F][R]
|
||||
// [B]
|
||||
// So up from left, front, back, and right are all top
|
||||
// Up from bottom is front
|
||||
// Down from bottom is back
|
||||
// Up from top is back
|
||||
// Down from top is front
|
||||
// So you can continually go left on the main level and circumnavigate the cube
|
||||
// Continually going up from anywhere will eventually get you bouncing between top and back
|
||||
// Continually going down from anywhere will eventually get you bouncing between bottom and back
|
||||
func BuildCubeBoard(inp []string) *CubeBoard {
|
||||
cb := CubeBoard{}
|
||||
var side string
|
||||
for i := 0; i < len(inp); i++ {
|
||||
if len(inp) == 0 {
|
||||
break
|
||||
}
|
||||
side = inp[i]
|
||||
i++
|
||||
cbs := BuildCubeBoardSide(inp[i : i+len(inp[i])])
|
||||
switch side {
|
||||
case "Top":
|
||||
cb.Top = cbs
|
||||
case "Bottom":
|
||||
cb.Bottom = cbs
|
||||
case "Left":
|
||||
cb.Left = cbs
|
||||
case "Right":
|
||||
cb.Right = cbs
|
||||
case "Front":
|
||||
cb.Front = cbs
|
||||
case "Back":
|
||||
cb.Back = cbs
|
||||
}
|
||||
i = i + cbs.Size() - 1
|
||||
}
|
||||
cb.pos = []int{0, 0, dirR, sideTop}
|
||||
return &cb
|
||||
}
|
||||
func (cb *CubeBoard) Size() int { return cb.Top.Size() }
|
||||
func (cb *CubeBoard) Move(count int) {
|
||||
|
||||
}
|
||||
func (cb *CubeBoard) GetPosUp() []int {
|
||||
y := cb.pos[0]
|
||||
x := cb.pos[1]
|
||||
dir := cb.pos[2]
|
||||
side := cb.pos[3]
|
||||
if y == 0 {
|
||||
// Going to another side
|
||||
switch side {
|
||||
case sideTop:
|
||||
side = sideBack
|
||||
case sideBottom:
|
||||
side = sideFront
|
||||
case sideFront:
|
||||
side = sideTop
|
||||
case sideBack:
|
||||
side = sideTop
|
||||
case sideLeft:
|
||||
side = sideTop
|
||||
case sideRight:
|
||||
side = sideTop
|
||||
}
|
||||
}
|
||||
return []int{y, x, dir, side}
|
||||
}
|
||||
func (cb *CubeBoard) GetPosDown() []int {
|
||||
y := cb.pos[0]
|
||||
x := cb.pos[1]
|
||||
dir := cb.pos[2]
|
||||
side := cb.pos[3]
|
||||
if y == cb.Size()-1 {
|
||||
// Going to another side
|
||||
switch side {
|
||||
case sideTop:
|
||||
side = sideFront
|
||||
case sideBottom:
|
||||
side = sideBack
|
||||
case sideFront:
|
||||
side = sideBottom
|
||||
case sideBack:
|
||||
side = sideBottom
|
||||
case sideLeft:
|
||||
side = sideBottom
|
||||
case sideRight:
|
||||
side = sideBottom
|
||||
}
|
||||
} else {
|
||||
y = y + 1
|
||||
}
|
||||
return []int{y, x, dir, side}
|
||||
}
|
||||
func (cb *CubeBoard) GetPosRight() []int {
|
||||
y := cb.pos[0]
|
||||
x := cb.pos[1]
|
||||
dir := cb.pos[2]
|
||||
side := cb.pos[3]
|
||||
if x == cb.Size()-1 {
|
||||
// Going to another side
|
||||
switch side {
|
||||
case sideTop:
|
||||
side = sideRight
|
||||
case sideBottom:
|
||||
side = sideRight
|
||||
case sideFront:
|
||||
side = sideRight
|
||||
case sideBack:
|
||||
side = sideLeft
|
||||
case sideLeft:
|
||||
side = sideFront
|
||||
case sideRight:
|
||||
side = sideBack
|
||||
}
|
||||
} else {
|
||||
y = y + 1
|
||||
}
|
||||
return []int{y, x, dir, side}
|
||||
}
|
||||
|
||||
// Get the current pos' side
|
||||
func (cb *CubeBoard) Side() *CubeBoardSide {
|
||||
switch cb.pos[3] {
|
||||
case sideTop:
|
||||
return cb.Top
|
||||
case sideBottom:
|
||||
return cb.Bottom
|
||||
case sideFront:
|
||||
return cb.Front
|
||||
case sideBack:
|
||||
return cb.Back
|
||||
case sideLeft:
|
||||
return cb.Left
|
||||
case sideRight:
|
||||
return cb.Right
|
||||
}
|
||||
return nil
|
||||
}
|
||||
func (cb *CubeBoard) Turn(dir byte) {
|
||||
if dir == 'R' {
|
||||
cb.pos[2] = (cb.pos[2] + 1) % dirErr
|
||||
} else if dir == 'L' {
|
||||
cb.pos[2] = (cb.pos[2] - 1 + dirErr) % dirErr
|
||||
}
|
||||
}
|
||||
func (cb *CubeBoard) Tile(y, x, side int) byte {
|
||||
switch side {
|
||||
case sideTop:
|
||||
return cb.Top.Tile(y, x)
|
||||
case sideBottom:
|
||||
return cb.Bottom.Tile(y, x)
|
||||
case sideLeft:
|
||||
return cb.Left.Tile(y, x)
|
||||
case sideRight:
|
||||
return cb.Right.Tile(y, x)
|
||||
case sideFront:
|
||||
return cb.Front.Tile(y, x)
|
||||
case sideBack:
|
||||
return cb.Back.Tile(y, x)
|
||||
}
|
||||
return 0
|
||||
}
|
||||
func (cb *CubeBoard) Password() int {
|
||||
return 0
|
||||
}
|
||||
|
||||
type CubeBoardSide struct {
|
||||
spots [][]byte
|
||||
}
|
||||
|
||||
func BuildCubeBoardSide(inp []string) *CubeBoardSide {
|
||||
cbs := CubeBoardSide{}
|
||||
fmt.Println("Building CBS from:", inp)
|
||||
cbs.spots = make([][]byte, len(inp))
|
||||
for y := range inp {
|
||||
row := make([]byte, len(inp[y]))
|
||||
for x := range inp[y] {
|
||||
row[x] = inp[y][x]
|
||||
}
|
||||
cbs.spots[y] = row
|
||||
}
|
||||
return &cbs
|
||||
}
|
||||
func (cbs *CubeBoardSide) Size() int {
|
||||
return len(cbs.spots)
|
||||
}
|
||||
func (cbs *CubeBoardSide) Tile(y, x int) byte {
|
||||
if len(cbs.spots) < y && len(cbs.spots[y]) < x {
|
||||
return cbs.spots[y][x]
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
type Board struct {
|
||||
spots [][]byte
|
||||
// pos holds
|
||||
// y, x, dir
|
||||
pos []int
|
||||
}
|
||||
|
||||
func BuildBoard(inp []string) *Board {
|
||||
maxX := math.MinInt
|
||||
for y := range inp {
|
||||
maxX = h.Max(maxX, len(inp[y]))
|
||||
}
|
||||
b := Board{
|
||||
spots: make([][]byte, len(inp)),
|
||||
}
|
||||
for y := range inp {
|
||||
sl := make([]byte, maxX)
|
||||
for x := range inp[y] {
|
||||
sl[x] = inp[y][x]
|
||||
}
|
||||
b.spots[y] = sl
|
||||
}
|
||||
|
||||
b.pos = make([]int, 3)
|
||||
for x := range b.spots[0] {
|
||||
if b.spots[0][x] == '.' {
|
||||
b.pos = []int{0, x, dirR}
|
||||
break
|
||||
}
|
||||
}
|
||||
return &b
|
||||
}
|
||||
func (b *Board) Password() int {
|
||||
return ((b.pos[0] + 1) * 1000) + ((b.pos[1] + 1) * 4) + b.pos[2]
|
||||
}
|
||||
func (b *Board) Tile(y, x int) byte {
|
||||
if len(b.spots) > y && len(b.spots[y]) > x {
|
||||
return b.spots[y][x]
|
||||
}
|
||||
return 0
|
||||
}
|
||||
func (b *Board) GetNextPos() []int {
|
||||
switch b.pos[2] {
|
||||
case dirU:
|
||||
return b.GetPosUp()
|
||||
case dirR:
|
||||
return b.GetPosRight()
|
||||
case dirD:
|
||||
return b.GetPosDown()
|
||||
case dirL:
|
||||
return b.GetPosLeft()
|
||||
}
|
||||
return []int{-1, -1}
|
||||
}
|
||||
func (b *Board) GetPosUp() []int {
|
||||
x := b.pos[1]
|
||||
y := ((b.pos[0] - 1) + len(b.spots)) % len(b.spots)
|
||||
for (b.spots[y][x] == 0 || b.spots[y][x] == 32) && y != b.pos[0] {
|
||||
y = ((y - 1) + len(b.spots)) % len(b.spots)
|
||||
}
|
||||
return []int{y, x}
|
||||
}
|
||||
func (b *Board) GetPosRight() []int {
|
||||
y := b.pos[0]
|
||||
x := (b.pos[1] + 1) % len(b.spots[y])
|
||||
for (b.spots[y][x] == 0 || b.spots[y][x] == 32) && x != b.pos[1] {
|
||||
x = (x + 1) % len(b.spots[y])
|
||||
}
|
||||
return []int{y, x}
|
||||
}
|
||||
func (b *Board) GetPosDown() []int {
|
||||
x := b.pos[1]
|
||||
y := (b.pos[0] + 1) % len(b.spots)
|
||||
for (b.spots[y][x] == 0 || b.spots[y][x] == 32) && y != b.pos[0] {
|
||||
y = (y + 1) % len(b.spots)
|
||||
}
|
||||
return []int{y, x}
|
||||
}
|
||||
func (b *Board) GetPosLeft() []int {
|
||||
y := b.pos[0]
|
||||
x := ((b.pos[1] - 1) + len(b.spots[y])) % len(b.spots[y])
|
||||
for (b.spots[y][x] == 0 || b.spots[y][x] == 32) && x != b.pos[1] {
|
||||
x = ((x - 1) + len(b.spots[y])) % len(b.spots[y])
|
||||
}
|
||||
return []int{y, x}
|
||||
}
|
||||
|
||||
func (b *Board) Move(count int) {
|
||||
var to []int
|
||||
for count > 0 {
|
||||
switch b.pos[2] {
|
||||
case dirU:
|
||||
to = b.GetPosUp()
|
||||
case dirR:
|
||||
to = b.GetPosRight()
|
||||
case dirD:
|
||||
to = b.GetPosDown()
|
||||
case dirL:
|
||||
to = b.GetPosLeft()
|
||||
}
|
||||
if b.Tile(to[0], to[1]) == '.' {
|
||||
count--
|
||||
b.pos[0], b.pos[1] = to[0], to[1]
|
||||
} else {
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (b *Board) Turn(dir byte) {
|
||||
if dir == 'R' {
|
||||
b.pos[2] = (b.pos[2] + 1) % dirErr
|
||||
} else if dir == 'L' {
|
||||
b.pos[2] = (b.pos[2] - 1 + dirErr) % dirErr
|
||||
}
|
||||
}
|
||||
|
||||
func (b Board) String() string {
|
||||
var ret string
|
||||
for y := range b.spots {
|
||||
for x := range b.spots[y] {
|
||||
bt := b.spots[y][x]
|
||||
if b.pos[1] == x && b.pos[0] == y {
|
||||
switch b.pos[2] {
|
||||
case dirU:
|
||||
bt = '^'
|
||||
case dirR:
|
||||
bt = '>'
|
||||
case dirD:
|
||||
bt = 'v'
|
||||
case dirL:
|
||||
bt = '<'
|
||||
default:
|
||||
bt = '!'
|
||||
}
|
||||
}
|
||||
ret = ret + fmt.Sprint(string(bt))
|
||||
}
|
||||
ret = ret + "\n"
|
||||
}
|
||||
return ret
|
||||
}
|
156
2022/day22/problem
Normal file
156
2022/day22/problem
Normal file
@ -0,0 +1,156 @@
|
||||
Advent of Code
|
||||
|
||||
• [About]
|
||||
• [Events]
|
||||
• [Shop]
|
||||
• [Settings]
|
||||
• [Log Out]
|
||||
|
||||
br0xen (AoC++) 36*
|
||||
|
||||
var y=2022;
|
||||
|
||||
• [Calendar]
|
||||
• [AoC++]
|
||||
• [Sponsors]
|
||||
• [Leaderboard]
|
||||
• [Stats]
|
||||
|
||||
Our sponsors help make Advent of Code possible:
|
||||
Infi - De kerstman wil weer cadeaus bezorgen maar komt tot de ontdekking dat zijn
|
||||
Kerstman Positioning System (KPS) niet meer werkt. Kan jij hem helpen?
|
||||
|
||||
--- Day 22: Monkey Map ---
|
||||
|
||||
The monkeys take you on a surprisingly easy trail through the jungle. They're even
|
||||
going in roughly the right direction according to your handheld device's Grove
|
||||
Positioning System.
|
||||
|
||||
As you walk, the monkeys explain that the grove is protected by a force field. To pass
|
||||
through the force field, you have to enter a password; doing so involves tracing a
|
||||
specific path on a strangely-shaped board.
|
||||
|
||||
At least, you're pretty sure that's what you have to do; the elephants aren't exactly
|
||||
fluent in monkey.
|
||||
|
||||
The monkeys give you notes that they took when they last saw the password entered
|
||||
(your puzzle input).
|
||||
|
||||
For example:
|
||||
|
||||
...#
|
||||
.#..
|
||||
#...
|
||||
....
|
||||
...#.......#
|
||||
........#...
|
||||
..#....#....
|
||||
..........#.
|
||||
...#....
|
||||
.....#..
|
||||
.#......
|
||||
......#.
|
||||
|
||||
10R5L5R10L4R5L5
|
||||
|
||||
The first half of the monkeys' notes is a map of the board. It is comprised of a set
|
||||
of open tiles (on which you can move, drawn .) and solid walls (tiles which you cannot
|
||||
enter, drawn #).
|
||||
|
||||
The second half is a description of the path you must follow. It consists of
|
||||
alternating numbers and letters:
|
||||
|
||||
• A number indicates the number of tiles to move in the direction you are facing. If
|
||||
you run into a wall, you stop moving forward and continue with the next
|
||||
instruction.
|
||||
• A letter indicates whether to turn 90 degrees clockwise (R) or counterclockwise
|
||||
(L). Turning happens in-place; it does not change your current tile.
|
||||
|
||||
So, a path like 10R5 means "go forward 10 tiles, then turn clockwise 90 degrees, then
|
||||
go forward 5 tiles".
|
||||
|
||||
You begin the path in the leftmost open tile of the top row of tiles. Initially, you
|
||||
are facing to the right (from the perspective of how the map is drawn).
|
||||
|
||||
If a movement instruction would take you off of the map, you wrap around to the other
|
||||
side of the board. In other words, if your next tile is off of the board, you should
|
||||
instead look in the direction opposite of your current facing as far as you can until
|
||||
you find the opposite edge of the board, then reappear there.
|
||||
|
||||
For example, if you are at A and facing to the right, the tile in front of you is
|
||||
marked B; if you are at C and facing down, the tile in front of you is marked D:
|
||||
|
||||
...#
|
||||
.#..
|
||||
#...
|
||||
....
|
||||
...#.D.....#
|
||||
........#...
|
||||
B.#....#...A
|
||||
.....C....#.
|
||||
...#....
|
||||
.....#..
|
||||
.#......
|
||||
......#.
|
||||
|
||||
It is possible for the next tile (after wrapping around) to be a wall; this still
|
||||
counts as there being a wall in front of you, and so movement stops before you
|
||||
actually wrap to the other side of the board.
|
||||
|
||||
By drawing the last facing you had with an arrow on each tile you visit, the full path
|
||||
taken by the above example looks like this:
|
||||
|
||||
>>v#
|
||||
.#v.
|
||||
#.v.
|
||||
..v.
|
||||
...#...v..v#
|
||||
>>>v...>#.>>
|
||||
..#v...#....
|
||||
...>>>>v..#.
|
||||
...#....
|
||||
.....#..
|
||||
.#......
|
||||
......#.
|
||||
|
||||
To finish providing the password to this strange input device, you need to determine
|
||||
numbers for your final row, column, and facing as your final position appears from the
|
||||
perspective of the original map. Rows start from 1 at the top and count downward;
|
||||
columns start from 1 at the left and count rightward. (In the above example, row 1,
|
||||
column 1 refers to the empty space with no tile on it in the top-left corner.) Facing
|
||||
is 0 for right (>), 1 for down (v), 2 for left (<), and 3 for up (^). The final
|
||||
password is the sum of 1000 times the row, 4 times the column, and the facing.
|
||||
|
||||
In the above example, the final row is 6, the final column is 8, and the final facing
|
||||
is 0. So, the final password is 1000 * 6 + 4 * 8 + 0: 6032.
|
||||
|
||||
Follow the path given in the monkeys' notes. What is the final password?
|
||||
|
||||
To begin, get your puzzle input.
|
||||
|
||||
Answer: _____________________ [ [Submit] ]
|
||||
|
||||
You can also [Shareon Twitter Mastodon] this puzzle.
|
||||
|
||||
References
|
||||
|
||||
Visible links
|
||||
. https://adventofcode.com/
|
||||
. https://adventofcode.com/2022/about
|
||||
. https://adventofcode.com/2022/events
|
||||
. https://teespring.com/stores/advent-of-code
|
||||
. https://adventofcode.com/2022/settings
|
||||
. https://adventofcode.com/2022/auth/logout
|
||||
. Advent of Code Supporter
|
||||
https://adventofcode.com/2022/support
|
||||
. https://adventofcode.com/2022
|
||||
. https://adventofcode.com/2022
|
||||
. https://adventofcode.com/2022/support
|
||||
. https://adventofcode.com/2022/sponsors
|
||||
. https://adventofcode.com/2022/leaderboard
|
||||
. https://adventofcode.com/2022/stats
|
||||
. https://adventofcode.com/2022/sponsors
|
||||
. https://aoc.infi.nl/?mtm_campaign=aoc2022&mtm_source=aoc
|
||||
. https://adventofcode.com/2022/day/22/input
|
||||
. https://twitter.com/intent/tweet?text=%22Monkey+Map%22+%2D+Day+22+%2D+Advent+of+Code+2022&url=https%3A%2F%2Fadventofcode%2Ecom%2F2022%2Fday%2F22&related=ericwastl&hashtags=AdventOfCode
|
||||
. javascript:void(0);
|
14
2022/day22/testinput
Normal file
14
2022/day22/testinput
Normal file
@ -0,0 +1,14 @@
|
||||
...#
|
||||
.#..
|
||||
#...
|
||||
....
|
||||
...#.......#
|
||||
........#...
|
||||
..#....#....
|
||||
..........#.
|
||||
...#....
|
||||
.....#..
|
||||
.#......
|
||||
......#.
|
||||
|
||||
10R5L5R10L4R5L5
|
32
2022/day22/testinput-m
Normal file
32
2022/day22/testinput-m
Normal file
@ -0,0 +1,32 @@
|
||||
Top
|
||||
...#
|
||||
.#..
|
||||
#...
|
||||
....
|
||||
Back
|
||||
...#
|
||||
....
|
||||
..#.
|
||||
....
|
||||
Left
|
||||
....
|
||||
....
|
||||
...#
|
||||
....
|
||||
Front
|
||||
...#
|
||||
#...
|
||||
....
|
||||
..#.
|
||||
Bottom
|
||||
...#
|
||||
....
|
||||
.#..
|
||||
....
|
||||
Right
|
||||
....
|
||||
.#..
|
||||
....
|
||||
..#.
|
||||
|
||||
10R5L5R10L4R5L5
|
73
2022/day23/input
Normal file
73
2022/day23/input
Normal file
@ -0,0 +1,73 @@
|
||||
.#.###...###....##..####.#.###.####.#..##......#.####.###.###...#.####.##
|
||||
.#...#.####.##.#.#.#####.#.#.....#...#.####.#..#.###.###....##.#.###.#...
|
||||
.....#..#........###.##.......###..#.....#####......###.#.#.####..#...#.#
|
||||
.##.##.#.####....###.#..###..#########..##....#..##..#.##.#....#.#.##.#.#
|
||||
..#..##...#.#..##.#...###.#.#..#...#....####.##.##...#.###.###...##..#.#.
|
||||
###.###....#.##.#...#.##.##.##..###.#.#..##...###.###...###.#.#..#.######
|
||||
.#.#####..#.####.###..##.#.#.#.#.#.#...##.####.#..#.#####.#..#....#.#..#.
|
||||
..######.##.#.##.###..#.#.#.#.##..###.######..#.......######.#.##.##..#.#
|
||||
#####......#.......######.#####.###..###......#..#..###.....#.#####......
|
||||
##...#.#..###.#######.###.##########...#...#.##.#..#..##.#...#.##....##..
|
||||
####.#...######....##..#.###.#...#.#.#..########...#..#######.####.#.#.##
|
||||
#....###..#.##..###.....#.#####...#.##....###..##.#..##..#....###......#.
|
||||
##.#..#.##.#.####...#.....##.##.#.#.######.#.###.....##..#......#..##.#..
|
||||
.......#.#####.#..#.##.#....##..#.##.#..#..#.###.#.##...#..#.##.#..#.....
|
||||
#.#..#...#..####.#.#.###..###..#######.#...#....##..###...#...##.###.###.
|
||||
#.#..#..#...##..#.#...#..#.#.#..#.#..#####......##..##.#...#.#.###....##.
|
||||
#..#...##.#.#.#....##......##...#.###.#..#..#...#.###.####.#.##..##....#.
|
||||
###.#..#.#.##..#.##......#...####.....##...#.#......##..######.#.#..#..#.
|
||||
.......#.######...##..#....#.#...##......#.....#..###.######.#...#.####.#
|
||||
...##.....#....#.##.##.########.#..#....#####.######....##.###...#.#.##..
|
||||
##...##..#...#.#..#..#.#.##.###.########..##...#..##....##..##..#####..##
|
||||
##..#####..#.####..##...#.##..##.##..#....####..####..#.########.#######.
|
||||
.#.#.######..#.##.###.#.#...#.#...###..#.##.#####.##.####.#...####.##.###
|
||||
##.#..#.#####.#....#..##...##..##.###..#.#....#.##....###.....#..##.##..#
|
||||
##.##.#..##.###.#.##.#..###...##.##...##.###...####.###...#.####.#.....#.
|
||||
.#.##..#####..#..#.....#####.#.#.###.#.#.####.##....##..#..##.####.###...
|
||||
.#...#.#.######.#....##.##.#.##...#..#.##....##...#.##.....###.#......###
|
||||
##....###.##.###.##.###..##...####..#..#####..##..........##.....#.#.#..#
|
||||
..#####.##.#...#......#..###..#...##..#.###....##.##.##.####.#.##.###..##
|
||||
##.##..#####..####..#..##.#....##...#..####..######...##..##.#.###.#.##.#
|
||||
.#.#..#...######.###..##.#......##.##..#.##.##..#.##.#.#.###.##..###....#
|
||||
..###.#...#......#.#.#........#.#######..#.#.######..##.#...###.##.#....#
|
||||
#..####.....#.#.#.#.###...#..##.#.#.##.#.#...###.#.#.#.#####..#.##.###..#
|
||||
##...####.....#....#.####.#....#...####.########..#....######.#..##..#.##
|
||||
.#.#.##...########.#######.......##......###..#....########..#......#..##
|
||||
.##......#..#######..#....#..##.#.####..##.#.#..##..##..#######..###.#.#.
|
||||
..##.######...##..#.#.##...##.###.##.##....##.#...#..#..#..###.####......
|
||||
.#.###.###.#..###..#.#.##.#..##.#.#..#.####.#.#...##.#####.#.##..#..##.#.
|
||||
.#..#........#..#..#.#..####.#.#....#.#.#.#...##...####..##.##.##.#.##.#.
|
||||
##...#.#.#.###...#....###..####.##..##.##..#.#####.##....#..##.########.#
|
||||
.#.#..##.#.####..#..#...#.######...###.#.#####.###.##.##..............##.
|
||||
.....###.#..###.#.##...#.#.####..##.#####.##..#.###.##.....#..##.#.#.#.#.
|
||||
##.#...###.#.#.###.#...#....#.#.....#.#..#.#..###.##.#...##..#####.#..#..
|
||||
.###....#######.##.#..#####.#.#.##.#..###.#.#.###.#.#.###...#.##.....###.
|
||||
##.#.#.#...#...#.#...#.....##..###..#......#.#.###.#.#.##.##..####.####..
|
||||
#.###.#####.#####....#..###..####.###.#####..##.....#.#####.###...#..#.#.
|
||||
.#..#..#..##..####.######...#...#.#.#.#....#.#......###...###.....#..###.
|
||||
#..####.##.#.#..##..#####.###..#.######.##..####.........##.....##..#.#..
|
||||
#..#.#..##.#.#..##..##.#.#.#.#..#.#....#.#.###.#.#.##.#.#.#..###..#...###
|
||||
##....###.##..#..##.##.#.##.#.....#...###.######....#.##.##.#..##.##...##
|
||||
.#..#....#...#.###..########.#...#..#.#.###.#.###...#..#.#..##.###.##..##
|
||||
#.#.##.##.#...######.#...#...###.###.##...###.#..#.##...#.###.###.##.#.##
|
||||
.....#..##..##.####..##..#.###.#######.#...##..#...#####..##...####......
|
||||
#.#####..##...#.##...#.#...##....######.#.#####...#.....#.#..#.#...#..#..
|
||||
#####.####.####.#..#.####..##..###.######..##.###..####.#...#.#.###....#.
|
||||
###..#.##.#######.#.#.#.#......###.#.##..##.##.##..#.#....#..####......#.
|
||||
.....#..#..#..###...#.###..####.#...###...######.#.##....###.##..#..#..#.
|
||||
#.#..##..##.##...#.###.#.###.#####.#.#.####.###.##.####..##.###..#.#####.
|
||||
.###....#...#.##.####.#.....####..#.##..##..##.##.#.##.##..###.###.#..#..
|
||||
..#.###.....#...##..###.##....###..####.#.##.###.####.##.#.##.#...#.#####
|
||||
.##.#..#....#..##.###..#..#.#..####.##.#...#.......###.#...#.##......#.#.
|
||||
......###.##########..###.##..#...#....#....#.####....##.#.#.##.##......#
|
||||
#.#.####..#.#..##..##......##..#####..##.#.#.###........#.#..#.#####.#.#.
|
||||
#...###..#...##..#.#.##..#.#..#..#.##..#.#...#####..#.#.###.##.#..##.#.#.
|
||||
..#.###.###..###..#.#.#.##.###.#####......#.###...##.#.##.###.##.##.#####
|
||||
....###..##.#.##....#..###.#.##.###.#....#.##...#...####.#.#..##..##.#.#.
|
||||
#..#.###.###.######.#.##.#..#.#.#...#..#........##..#...##.###.#.##.#...#
|
||||
####...###...#.###.#..#.#.#..#.#..##....#.##.#..#.##.#..#.###.#.##.####..
|
||||
.#####....##.#..##.....##.#..#......#..##..#.....#..#.###.#.#.###...###.#
|
||||
.#........#.....###.####..##....##.##....####.##.#####...##..#........#..
|
||||
...#####.#.####.#.#....#..##.#..#.#.##....###....#..#..#...##.#.##.##...#
|
||||
#...##..#.####.####.##.##.###.##....#...#.####..##.#.......#..#.###..#..#
|
||||
.##...#####..####..#.###.##..##.#.#...#....#.#..####..##...#.....#.##.##.
|
201
2022/day23/main.go
Normal file
201
2022/day23/main.go
Normal file
@ -0,0 +1,201 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"math"
|
||||
"sort"
|
||||
|
||||
h "git.bullercodeworks.com/brian/adventofcode/helpers"
|
||||
)
|
||||
|
||||
func main() {
|
||||
inp := h.StdinToStringSlice()
|
||||
part1(inp)
|
||||
part2(inp)
|
||||
}
|
||||
|
||||
func part1(inp []string) {
|
||||
field := plotElves(inp)
|
||||
for i := 0; i < 10; i++ {
|
||||
proposals := buildProposals(field, i)
|
||||
for k, v := range proposals {
|
||||
delete(field, v)
|
||||
field[k] = true
|
||||
}
|
||||
}
|
||||
fmt.Println("# Part 1")
|
||||
fmt.Println("Empty Tiles:", countEmpties(field))
|
||||
}
|
||||
func part2(inp []string) {
|
||||
field := plotElves(inp)
|
||||
var lastHash string
|
||||
for i := 0; i < 100000000; i++ {
|
||||
proposals := buildProposals(field, i)
|
||||
for k, v := range proposals {
|
||||
delete(field, v)
|
||||
field[k] = true
|
||||
}
|
||||
currHash := fieldHash(field)
|
||||
if currHash == lastHash {
|
||||
fmt.Println("# Part 2")
|
||||
fmt.Println("Stable on round", i+1)
|
||||
return
|
||||
}
|
||||
lastHash = currHash
|
||||
}
|
||||
fmt.Println("# Part 2")
|
||||
fmt.Println("No solution found.")
|
||||
}
|
||||
func fieldHash(field map[h.Coordinate]bool) string {
|
||||
var sorted []h.Coordinate
|
||||
for k := range field {
|
||||
sorted = append(sorted, k)
|
||||
}
|
||||
sort.Slice(sorted, func(i, j int) bool {
|
||||
if sorted[i].X == sorted[j].X {
|
||||
return sorted[i].Y > sorted[j].Y
|
||||
}
|
||||
return sorted[i].X > sorted[j].X
|
||||
})
|
||||
return fmt.Sprintf("%v", sorted)
|
||||
}
|
||||
|
||||
func countEmpties(field map[h.Coordinate]bool) int {
|
||||
maxX, minX := math.MinInt, math.MaxInt
|
||||
maxY, minY := math.MinInt, math.MaxInt
|
||||
for k := range field {
|
||||
maxX = h.Max(maxX, k.X)
|
||||
minX = h.Min(minX, k.X)
|
||||
maxY = h.Max(maxY, k.Y)
|
||||
minY = h.Min(minY, k.Y)
|
||||
}
|
||||
var ret int
|
||||
for y := minY; y <= maxY; y++ {
|
||||
for x := minX; x <= maxX; x++ {
|
||||
if _, ok := field[h.Coordinate{X: x, Y: y}]; !ok {
|
||||
ret++
|
||||
}
|
||||
}
|
||||
}
|
||||
return ret
|
||||
}
|
||||
func printField(field map[h.Coordinate]bool) {
|
||||
maxX, minX := math.MinInt, 0
|
||||
maxY, minY := math.MinInt, 0
|
||||
for k := range field {
|
||||
maxX = h.Max(maxX, k.X)
|
||||
minX = h.Min(minX, k.X)
|
||||
maxY = h.Max(maxY, k.Y)
|
||||
minY = h.Min(minY, k.Y)
|
||||
}
|
||||
maxX = maxX + 2
|
||||
maxY = maxY + 2
|
||||
for y := minY; y <= maxY; y++ {
|
||||
for x := minX; x <= maxX; x++ {
|
||||
if _, ok := field[h.Coordinate{X: x, Y: y}]; ok {
|
||||
fmt.Print("#")
|
||||
} else {
|
||||
fmt.Print(".")
|
||||
}
|
||||
}
|
||||
fmt.Println()
|
||||
}
|
||||
}
|
||||
func plotElves(inp []string) map[h.Coordinate]bool {
|
||||
field := make(map[h.Coordinate]bool)
|
||||
for y := range inp {
|
||||
for x := range inp[y] {
|
||||
if inp[y][x] == '#' {
|
||||
field[h.Coordinate{X: x, Y: y}] = true
|
||||
}
|
||||
}
|
||||
}
|
||||
return field
|
||||
}
|
||||
func buildProposals(field map[h.Coordinate]bool, round int) map[h.Coordinate]h.Coordinate {
|
||||
props := make(map[h.Coordinate]h.Coordinate)
|
||||
var errProps []h.Coordinate
|
||||
for k := range field {
|
||||
var neighbors []h.Coordinate
|
||||
for _, n := range k.GetAllNeighbors() {
|
||||
if _, ok := field[n]; ok {
|
||||
neighbors = append(neighbors, n)
|
||||
}
|
||||
}
|
||||
if len(neighbors) == 0 {
|
||||
continue
|
||||
}
|
||||
var hasNorth, hasEast, hasSouth, hasWest bool
|
||||
for _, n := range neighbors {
|
||||
if n.Y < k.Y {
|
||||
hasNorth = true
|
||||
}
|
||||
if n.Y > k.Y {
|
||||
hasSouth = true
|
||||
}
|
||||
if n.X < k.X {
|
||||
hasWest = true
|
||||
}
|
||||
if n.X > k.X {
|
||||
hasEast = true
|
||||
}
|
||||
}
|
||||
addProp := func(c h.Coordinate) {
|
||||
if _, ok := props[c]; ok {
|
||||
errProps = append(errProps, c)
|
||||
} else {
|
||||
props[c] = k
|
||||
}
|
||||
}
|
||||
testNorth := func(c h.Coordinate) bool {
|
||||
if !hasNorth {
|
||||
addProp(k.North())
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
testSouth := func(c h.Coordinate) bool {
|
||||
if !hasSouth {
|
||||
addProp(k.South())
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
testWest := func(c h.Coordinate) bool {
|
||||
if !hasWest {
|
||||
addProp(k.West())
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
testEast := func(c h.Coordinate) bool {
|
||||
if !hasEast {
|
||||
addProp(k.East())
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
findProposal := func(c h.Coordinate, tests ...func(h.Coordinate) bool) {
|
||||
for i := range tests {
|
||||
if tests[i](c) == true {
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
switch round % 4 {
|
||||
case 0: // North First
|
||||
findProposal(k, testNorth, testSouth, testWest, testEast)
|
||||
case 1: // South First
|
||||
findProposal(k, testSouth, testWest, testEast, testNorth)
|
||||
case 2: // West First
|
||||
findProposal(k, testWest, testEast, testNorth, testSouth)
|
||||
case 3: // East First
|
||||
findProposal(k, testEast, testNorth, testSouth, testWest)
|
||||
}
|
||||
}
|
||||
// Now remove all conflicts
|
||||
for i := range errProps {
|
||||
delete(props, errProps[i])
|
||||
}
|
||||
return props
|
||||
}
|
299
2022/day23/problem
Normal file
299
2022/day23/problem
Normal file
@ -0,0 +1,299 @@
|
||||
Advent of Code
|
||||
br0xen (AoC++) 39*
|
||||
|
||||
--- Day 23: Unstable Diffusion ---
|
||||
|
||||
You enter a large crater of gray dirt where the grove is supposed to be. All around
|
||||
you, plants you imagine were expected to be full of fruit are instead withered and
|
||||
broken. A large group of Elves has formed in the middle of the grove.
|
||||
|
||||
"...but this volcano has been dormant for months. Without ash, the fruit can't grow!"
|
||||
|
||||
You look up to see a massive, snow-capped mountain towering above you.
|
||||
|
||||
"It's not like there are other active volcanoes here; we've looked everywhere."
|
||||
|
||||
"But our scanners show active magma flows; clearly it's going somewhere."
|
||||
|
||||
They finally notice you at the edge of the grove, your pack almost overflowing from
|
||||
the random star fruit you've been collecting. Behind you, elephants and monkeys
|
||||
explore the grove, looking concerned. Then, the Elves recognize the ash cloud slowly
|
||||
spreading above your recent detour.
|
||||
|
||||
"Why do you--" "How is--" "Did you just--"
|
||||
|
||||
Before any of them can form a complete question, another Elf speaks up: "Okay, new
|
||||
plan. We have almost enough fruit already, and ash from the plume should spread here
|
||||
eventually. If we quickly plant new seedlings now, we can still make it to the
|
||||
extraction point. Spread out!"
|
||||
|
||||
The Elves each reach into their pack and pull out a tiny plant. The plants rely on
|
||||
important nutrients from the ash, so they can't be planted too close together.
|
||||
|
||||
There isn't enough time to let the Elves figure out where to plant the seedlings
|
||||
themselves; you quickly scan the grove (your puzzle input) and note their positions.
|
||||
|
||||
For example:
|
||||
|
||||
....#..
|
||||
..###.#
|
||||
#...#.#
|
||||
.#...##
|
||||
#.###..
|
||||
##.#.##
|
||||
.#..#..
|
||||
|
||||
The scan shows Elves # and empty ground .; outside your scan, more empty ground
|
||||
extends a long way in every direction. The scan is oriented so that north is up;
|
||||
orthogonal directions are written N (north), S (south), W (west), and E (east), while
|
||||
diagonal directions are written NE, NW, SE, SW.
|
||||
|
||||
The Elves follow a time-consuming process to figure out where they should each go; you
|
||||
can speed up this process considerably. The process consists of some number of rounds
|
||||
during which Elves alternate between considering where to move and actually moving.
|
||||
|
||||
During the first half of each round, each Elf considers the eight positions adjacent
|
||||
to themself. If no other Elves are in one of those eight positions, the Elf does not
|
||||
do anything during this round. Otherwise, the Elf looks in each of four directions in
|
||||
the following order and proposes moving one step in the first valid direction:
|
||||
|
||||
• If there is no Elf in the N, NE, or NW adjacent positions, the Elf proposes moving
|
||||
north one step.
|
||||
• If there is no Elf in the S, SE, or SW adjacent positions, the Elf proposes moving
|
||||
south one step.
|
||||
• If there is no Elf in the W, NW, or SW adjacent positions, the Elf proposes moving
|
||||
west one step.
|
||||
• If there is no Elf in the E, NE, or SE adjacent positions, the Elf proposes moving
|
||||
east one step.
|
||||
|
||||
After each Elf has had a chance to propose a move, the second half of the round can
|
||||
begin. Simultaneously, each Elf moves to their proposed destination tile if they were
|
||||
the only Elf to propose moving to that position. If two or more Elves propose moving
|
||||
to the same position, none of those Elves move.
|
||||
|
||||
Finally, at the end of the round, the first direction the Elves considered is moved to
|
||||
the end of the list of directions. For example, during the second round, the Elves
|
||||
would try proposing a move to the south first, then west, then east, then north. On
|
||||
the third round, the Elves would first consider west, then east, then north, then
|
||||
south.
|
||||
|
||||
As a smaller example, consider just these five Elves:
|
||||
|
||||
.....
|
||||
..##.
|
||||
..#..
|
||||
.....
|
||||
..##.
|
||||
.....
|
||||
|
||||
The northernmost two Elves and southernmost two Elves all propose moving north, while
|
||||
the middle Elf cannot move north and proposes moving south. The middle Elf proposes
|
||||
the same destination as the southwest Elf, so neither of them move, but the other
|
||||
three do:
|
||||
|
||||
..##.
|
||||
.....
|
||||
..#..
|
||||
...#.
|
||||
..#..
|
||||
.....
|
||||
|
||||
Next, the northernmost two Elves and the southernmost Elf all propose moving south. Of
|
||||
the remaining middle two Elves, the west one cannot move south and proposes moving
|
||||
west, while the east one cannot move south or west and proposes moving east. All five
|
||||
Elves succeed in moving to their proposed positions:
|
||||
|
||||
.....
|
||||
..##.
|
||||
.#...
|
||||
....#
|
||||
.....
|
||||
..#..
|
||||
|
||||
Finally, the southernmost two Elves choose not to move at all. Of the remaining three
|
||||
Elves, the west one proposes moving west, the east one proposes moving east, and the
|
||||
middle one proposes moving north; all three succeed in moving:
|
||||
|
||||
..#..
|
||||
....#
|
||||
#....
|
||||
....#
|
||||
.....
|
||||
..#..
|
||||
|
||||
At this point, no Elves need to move, and so the process ends.
|
||||
|
||||
The larger example above proceeds as follows:
|
||||
|
||||
== Initial State ==
|
||||
..............
|
||||
..............
|
||||
.......#......
|
||||
.....###.#....
|
||||
...#...#.#....
|
||||
....#...##....
|
||||
...#.###......
|
||||
...##.#.##....
|
||||
....#..#......
|
||||
..............
|
||||
..............
|
||||
..............
|
||||
|
||||
== End of Round 1 ==
|
||||
..............
|
||||
.......#......
|
||||
.....#...#....
|
||||
...#..#.#.....
|
||||
.......#..#...
|
||||
....#.#.##....
|
||||
..#..#.#......
|
||||
..#.#.#.##....
|
||||
..............
|
||||
....#..#......
|
||||
..............
|
||||
..............
|
||||
|
||||
== End of Round 2 ==
|
||||
..............
|
||||
.......#......
|
||||
....#.....#...
|
||||
...#..#.#.....
|
||||
.......#...#..
|
||||
...#..#.#.....
|
||||
.#...#.#.#....
|
||||
..............
|
||||
..#.#.#.##....
|
||||
....#..#......
|
||||
..............
|
||||
..............
|
||||
|
||||
== End of Round 3 ==
|
||||
..............
|
||||
.......#......
|
||||
.....#....#...
|
||||
..#..#...#....
|
||||
.......#...#..
|
||||
...#..#.#.....
|
||||
.#..#.....#...
|
||||
.......##.....
|
||||
..##.#....#...
|
||||
...#..........
|
||||
.......#......
|
||||
..............
|
||||
|
||||
== End of Round 4 ==
|
||||
..............
|
||||
.......#......
|
||||
......#....#..
|
||||
..#...##......
|
||||
...#.....#.#..
|
||||
.........#....
|
||||
.#...###..#...
|
||||
..#......#....
|
||||
....##....#...
|
||||
....#.........
|
||||
.......#......
|
||||
..............
|
||||
|
||||
== End of Round 5 ==
|
||||
.......#......
|
||||
..............
|
||||
..#..#.....#..
|
||||
.........#....
|
||||
......##...#..
|
||||
.#.#.####.....
|
||||
...........#..
|
||||
....##..#.....
|
||||
..#...........
|
||||
..........#...
|
||||
....#..#......
|
||||
..............
|
||||
|
||||
After a few more rounds...
|
||||
|
||||
== End of Round 10 ==
|
||||
.......#......
|
||||
...........#..
|
||||
..#.#..#......
|
||||
......#.......
|
||||
...#.....#..#.
|
||||
.#......##....
|
||||
.....##.......
|
||||
..#........#..
|
||||
....#.#..#....
|
||||
..............
|
||||
....#..#..#...
|
||||
..............
|
||||
|
||||
To make sure they're on the right track, the Elves like to check after round 10 that
|
||||
they're making good progress toward covering enough ground. To do this, count the
|
||||
number of empty ground tiles contained by the smallest rectangle that contains every
|
||||
Elf. (The edges of the rectangle should be aligned to the N/S/E/W directions; the
|
||||
Elves do not have the patience to calculate arbitrary rectangles.) In the above
|
||||
example, that rectangle is:
|
||||
|
||||
......#.....
|
||||
..........#.
|
||||
.#.#..#.....
|
||||
.....#......
|
||||
..#.....#..#
|
||||
#......##...
|
||||
....##......
|
||||
.#........#.
|
||||
...#.#..#...
|
||||
............
|
||||
...#..#..#..
|
||||
|
||||
In this region, the number of empty ground tiles is 110.
|
||||
|
||||
Simulate the Elves' process and find the smallest rectangle that contains the Elves
|
||||
after 10 rounds. How many empty ground tiles does that rectangle contain?
|
||||
|
||||
Your puzzle answer was 4000.
|
||||
|
||||
--- Part Two ---
|
||||
|
||||
It seems you're on the right track. Finish simulating the process and figure out where
|
||||
the Elves need to go. How many rounds did you save them?
|
||||
|
||||
In the example above, the first round where no Elf moved was round 20:
|
||||
|
||||
.......#......
|
||||
....#......#..
|
||||
..#.....#.....
|
||||
......#.......
|
||||
...#....#.#..#
|
||||
#.............
|
||||
....#.....#...
|
||||
..#.....#.....
|
||||
....#.#....#..
|
||||
.........#....
|
||||
....#......#..
|
||||
.......#......
|
||||
|
||||
Figure out where the Elves need to go. What is the number of the first round where no
|
||||
Elf moves?
|
||||
|
||||
Your puzzle answer was 1040.
|
||||
|
||||
Both parts of this puzzle are complete! They provide two gold stars: **
|
||||
|
||||
References
|
||||
|
||||
Visible links
|
||||
. https://adventofcode.com/
|
||||
. https://adventofcode.com/2022/about
|
||||
. https://adventofcode.com/2022/events
|
||||
. https://adventofcode.com/2022/settings
|
||||
. https://adventofcode.com/2022/auth/logout
|
||||
. Advent of Code Supporter
|
||||
https://adventofcode.com/2022/support
|
||||
. https://adventofcode.com/2022
|
||||
. https://adventofcode.com/2022
|
||||
. https://adventofcode.com/2022/support
|
||||
. https://adventofcode.com/2022/sponsors
|
||||
. https://adventofcode.com/2022/leaderboard
|
||||
. https://adventofcode.com/2022/stats
|
||||
. https://adventofcode.com/2022/sponsors
|
||||
. https://adventofcode.com/2022
|
||||
. https://adventofcode.com/2022/day/23/input
|
7
2022/day23/testinput
Normal file
7
2022/day23/testinput
Normal file
@ -0,0 +1,7 @@
|
||||
....#..
|
||||
..###.#
|
||||
#...#.#
|
||||
.#...##
|
||||
#.###..
|
||||
##.#.##
|
||||
.#..#..
|
6
2022/day23/testinput2
Normal file
6
2022/day23/testinput2
Normal file
@ -0,0 +1,6 @@
|
||||
.....
|
||||
..##.
|
||||
..#..
|
||||
.....
|
||||
..##.
|
||||
.....
|
2
go.mod
2
go.mod
@ -1,6 +1,6 @@
|
||||
module git.bullercodeworks.com/brian/adventofcode
|
||||
|
||||
go 1.13
|
||||
go 1.16
|
||||
|
||||
require (
|
||||
github.com/br0xen/termbox-screen v0.0.0-20190712162752-c91f70ac38c6
|
||||
|
@ -66,6 +66,13 @@ func (c *Coordinate) SE() Coordinate {
|
||||
func (c *Coordinate) GetOrthNeighbors() []Coordinate {
|
||||
return []Coordinate{c.North(), c.East(), c.South(), c.West()}
|
||||
}
|
||||
func (c *Coordinate) GetAllNeighbors() []Coordinate {
|
||||
return []Coordinate{
|
||||
c.North(), c.NE(),
|
||||
c.East(), c.SE(),
|
||||
c.South(), c.SW(),
|
||||
c.West(), c.NW()}
|
||||
}
|
||||
|
||||
func (c *Coordinate) GetNorthCoord() *Coordinate {
|
||||
return &Coordinate{
|
||||
|
Loading…
Reference in New Issue
Block a user