2018 day 18 Done
This commit is contained in:
parent
3f65da791c
commit
1f6e1c932c
202
2018/day18/day18.go
Normal file
202
2018/day18/day18.go
Normal file
@ -0,0 +1,202 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bufio"
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
DIR_N = -1i
|
||||||
|
DIR_NE = 1 - 1i
|
||||||
|
DIR_E = 1
|
||||||
|
DIR_SE = 1 + 1i
|
||||||
|
DIR_S = 1i
|
||||||
|
DIR_SW = -1 + 1i
|
||||||
|
DIR_W = -1
|
||||||
|
DIR_NW = -1 - 1i
|
||||||
|
|
||||||
|
CLEAR_SCREEN = "\033[H\033[2J"
|
||||||
|
)
|
||||||
|
|
||||||
|
var scan []byte
|
||||||
|
var next []byte
|
||||||
|
var prevScans [][]byte
|
||||||
|
var width, height int
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
stdinToByteSlice()
|
||||||
|
part1()
|
||||||
|
part2()
|
||||||
|
}
|
||||||
|
|
||||||
|
func part1() {
|
||||||
|
printScan()
|
||||||
|
for i := 0; i < 10; i++ {
|
||||||
|
fmt.Print(CLEAR_SCREEN)
|
||||||
|
scan = tickToNext()
|
||||||
|
printScan()
|
||||||
|
time.Sleep(time.Millisecond * 250)
|
||||||
|
}
|
||||||
|
var ttlOpen, ttlTrees, ttlLmbr int
|
||||||
|
for i := range scan {
|
||||||
|
switch getByte(getPosFromInt(i)) {
|
||||||
|
case '.':
|
||||||
|
ttlOpen++
|
||||||
|
case '|':
|
||||||
|
ttlTrees++
|
||||||
|
case '#':
|
||||||
|
ttlLmbr++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ = ttlOpen
|
||||||
|
fmt.Println("= Part 1 =")
|
||||||
|
fmt.Println(ttlTrees * ttlLmbr)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 191080?
|
||||||
|
func part2() {
|
||||||
|
var isDupe bool
|
||||||
|
var i int
|
||||||
|
target := 1000000000
|
||||||
|
for i = 0; i < target; i++ {
|
||||||
|
//fmt.Print(CLEAR_SCREEN, target)
|
||||||
|
next := tickToNext()
|
||||||
|
if isDupe, prevScans = checkDuplicateState(next, prevScans); isDupe {
|
||||||
|
i++
|
||||||
|
scan = next
|
||||||
|
break
|
||||||
|
}
|
||||||
|
prevScans = append(prevScans, next)
|
||||||
|
scan = next
|
||||||
|
}
|
||||||
|
// We need to find the state after `target` increments
|
||||||
|
scan = prevScans[(target-i)%len(prevScans)]
|
||||||
|
var ttlOpen, ttlTrees, ttlLmbr int
|
||||||
|
for i := range scan {
|
||||||
|
switch getByte(getPosFromInt(i)) {
|
||||||
|
case '.':
|
||||||
|
ttlOpen++
|
||||||
|
case '|':
|
||||||
|
ttlTrees++
|
||||||
|
case '#':
|
||||||
|
ttlLmbr++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ = ttlOpen
|
||||||
|
fmt.Println("= Part 2 =")
|
||||||
|
fmt.Println(ttlTrees * ttlLmbr)
|
||||||
|
}
|
||||||
|
|
||||||
|
// checkDuplicateState returns the slice of prev that has all remaining available states
|
||||||
|
func checkDuplicateState(s []byte, prev [][]byte) (bool, [][]byte) {
|
||||||
|
for i, v := range prev {
|
||||||
|
if areasAreEqual(s, v) {
|
||||||
|
return true, prev[i:]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false, prev
|
||||||
|
}
|
||||||
|
|
||||||
|
func areasAreEqual(a1, a2 []byte) bool {
|
||||||
|
for i := range a1 {
|
||||||
|
if a1[i] != a2[i] {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
func tickToNext() []byte {
|
||||||
|
var ret []byte
|
||||||
|
for i := 0; i < len(scan); i++ {
|
||||||
|
c := getPosFromInt(i)
|
||||||
|
_, sTree, sLmbr := getSurroundingCounts(c)
|
||||||
|
b := getByte(c)
|
||||||
|
switch b {
|
||||||
|
case '.':
|
||||||
|
if sTree >= 3 {
|
||||||
|
ret = append(ret, '|')
|
||||||
|
} else {
|
||||||
|
ret = append(ret, '.')
|
||||||
|
}
|
||||||
|
case '|':
|
||||||
|
if sLmbr >= 3 {
|
||||||
|
ret = append(ret, '#')
|
||||||
|
} else {
|
||||||
|
ret = append(ret, '|')
|
||||||
|
}
|
||||||
|
case '#':
|
||||||
|
if sLmbr > 0 && sTree > 0 {
|
||||||
|
ret = append(ret, '#')
|
||||||
|
} else {
|
||||||
|
ret = append(ret, '.')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ret
|
||||||
|
}
|
||||||
|
|
||||||
|
// getSurroundingCounts takes a pos and returns:
|
||||||
|
// Number of open areas
|
||||||
|
// Number of trees
|
||||||
|
// Number of lumberyards
|
||||||
|
// Surrounding that spot
|
||||||
|
func getSurroundingCounts(c complex64) (int, int, int) {
|
||||||
|
var sOpen, sTree, sLmbr int
|
||||||
|
for _, v := range []complex64{DIR_NW, DIR_N, DIR_NE, DIR_W, DIR_E, DIR_SW, DIR_S, DIR_SE} {
|
||||||
|
switch getByte(c + v) {
|
||||||
|
case '.':
|
||||||
|
sOpen++
|
||||||
|
case '|':
|
||||||
|
sTree++
|
||||||
|
case '#':
|
||||||
|
sLmbr++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return sOpen, sTree, sLmbr
|
||||||
|
}
|
||||||
|
|
||||||
|
func printScan() {
|
||||||
|
for i := 0; i < len(scan)/width; i++ {
|
||||||
|
fmt.Println(string(scan[i*width : (i+1)*width]))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// getByte pulls a byte from the given position in the scan
|
||||||
|
func getByte(pos complex64) byte {
|
||||||
|
//idx := int(real(pos)) + int(imag(pos))*width
|
||||||
|
if int(real(pos)) < 0 || int(imag(pos)) < 0 || int(real(pos)) >= width || int(imag(pos)) >= height {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
return scan[int(real(pos))+int(imag(pos))*width]
|
||||||
|
}
|
||||||
|
|
||||||
|
func getPosComplex(x, y int) complex64 {
|
||||||
|
return complex(float32(x), float32(y))
|
||||||
|
}
|
||||||
|
|
||||||
|
func getPosFromInt(i int) complex64 {
|
||||||
|
return complex(float32(i%width), float32(i/width))
|
||||||
|
}
|
||||||
|
|
||||||
|
func getIdxFromPos(pos complex64) int {
|
||||||
|
return int(real(pos)) + int(imag(pos))*width
|
||||||
|
}
|
||||||
|
|
||||||
|
func getCoordString(p complex64) string {
|
||||||
|
return fmt.Sprintf("(%d,%d [%d])", int(real(p)), int(imag(p)), getIdxFromPos(p))
|
||||||
|
}
|
||||||
|
|
||||||
|
func stdinToByteSlice() {
|
||||||
|
scanner := bufio.NewScanner(os.Stdin)
|
||||||
|
for scanner.Scan() {
|
||||||
|
s := scanner.Bytes()
|
||||||
|
if width == 0 {
|
||||||
|
width = len(s)
|
||||||
|
}
|
||||||
|
scan = append(scan, s...)
|
||||||
|
height++
|
||||||
|
}
|
||||||
|
}
|
50
2018/day18/input
Normal file
50
2018/day18/input
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
.#|#.##....#|....|.#.#.|||.#.|....||....|...|..#..
|
||||||
|
..|#||.|#..|...|#|..#...|#...#..#..|.....||..#.|#.
|
||||||
|
#|||#..||.....||.#................|..#.##|.#...#.|
|
||||||
|
|#..#.|...##...#..#|#|#..|#.#...|....#..#...##....
|
||||||
|
.###.........|.||#...#|.|#.||||#..|...||....#..#..
|
||||||
|
###.|..|#|...|..||..##.....|..#.|.#.............|.
|
||||||
|
..|.|.||.#....|...|....#|.........##||..#||..|.##.
|
||||||
|
#||#|...#|..|.|.||#...#|...|#.......|...#.....|...
|
||||||
|
....||.....|.|.....#...|.......|...|..|...|......|
|
||||||
|
#......#..#|#|..|....#.|.|.#...#.#.|..#.|.....#.#.
|
||||||
|
.|#...|...........#|.#....#.#...#.|..|...|....|.|.
|
||||||
|
..||.#.|...||#|....#.#..||#..#...#|..#..|..#|.....
|
||||||
|
|..|.|..#...|.....#.|..|#.||..#|.|.||#|#..|#...##|
|
||||||
|
..|..|#......||##..|........#.|...#.|.|#.#...||..#
|
||||||
|
#.|...#.||#..|.|..|..|.#....|.||....|.|....#....#.
|
||||||
|
#||.|.#..#..|...#....##|#..#...#.#...|.#...#.....#
|
||||||
|
#.|.##.|##..#.##|##........#.|...#...|..#|.#|#|...
|
||||||
|
.|#|....|.#...#..|||.#.||..#||.||.|..#.|....|..##.
|
||||||
|
|.#.||#|.##.|.||.....#...#.#..###|.#......||#|....
|
||||||
|
.|.#..|#||......|##..##.#|..#|.|#.|.|#......|#.|#.
|
||||||
|
#..|........|||..|###..|#..|||#.|.|.....#|..|...|#
|
||||||
|
..####||#......|#||..###.|...|....#..|.#|.||....||
|
||||||
|
|##.......|||..........|..||.#.|#.......##...|...|
|
||||||
|
|.......#......####|#|....#....|......#.|#.###...#
|
||||||
|
#|.#.|||...|..|.....#....|...|......|#|#|......||.
|
||||||
|
...#.|......#..||||.#|.....|.|.|||.|.|.|#|.#...#.#
|
||||||
|
#.#.##.|.#|.|...|...|...#|...#.|#..|..##.|....#..|
|
||||||
|
|...#.......#....#....#.#....#.#|.|#||.|.|.|#...#.
|
||||||
|
#..|.||..|.#..|.#.....#|##.|.|....|....||.......|.
|
||||||
|
..||.#..|#|.###....#.#|..#|.#..........#...|...#|.
|
||||||
|
|#||.|.#..|....|....#.#||#.|......#..|#.#.|||||#|.
|
||||||
|
.|#.|#.##.....#.|.#.....|....|.#..#.#..|#.#.....|.
|
||||||
|
#.||.#.......|..|......|#||.|..#....#...|...|...|.
|
||||||
|
|.....#.|.....#||.....##...#.#...||.|..#........|.
|
||||||
|
||#..|.##.#...........#..|..|.|..#....|...#..||.#.
|
||||||
|
..||.##.##.|.||......#...|.#.#.#..#.#...##.#.|.#..
|
||||||
|
.|.#......#|#||.|.#|......||.#.|.|..|....#...||...
|
||||||
|
....|.##.....|#|####.#..#..#|.....|.#.#|......|...
|
||||||
|
...#..|......#....|#.#...|...|.#.#.......#.#.##..#
|
||||||
|
.|||#.||||...|..|#||.|.#|#||..|..#..|..|..#||.....
|
||||||
|
.....|..#..|#|.||.#||.||......|||..|..#|.|##......
|
||||||
|
.#...#|..#..|||..||.|..|.#.#.......||..|...|.|....
|
||||||
|
.##.||..|..||.|.......#.|||.|.|..|.#.#..|.||.|#|||
|
||||||
|
.|..##|..#.#|#|....|.#.#.#|#.#|.##|........###...#
|
||||||
|
..#..|#|...#.........#.#.####..#.#..#..#||#|...#|#
|
||||||
|
#.|...|.......|.#.#..#.|#..#|#|..#..|.....|..|...|
|
||||||
|
.##.|..#.....|...#..|#..|.|.#..##.#.|..#.|..|.##..
|
||||||
|
....|..|.|..||....|...|.....#..|.|.....|.#|......#
|
||||||
|
...##.|#..#..|.#|.##....|.#...||#|.....#...##.#|..
|
||||||
|
.|....##.....||...#.#.....#|#...#...#|.|..#.#.#.##
|
203
2018/day18/problem
Normal file
203
2018/day18/problem
Normal file
@ -0,0 +1,203 @@
|
|||||||
|
Advent of Code
|
||||||
|
|
||||||
|
--- Day 18: Settlers of The North Pole ---
|
||||||
|
|
||||||
|
On the outskirts of the North Pole base construction project, many Elves are collecting lumber.
|
||||||
|
|
||||||
|
The lumber collection area is 50 acres by 50 acres; each acre can be either open ground (.), trees (|), or a
|
||||||
|
lumberyard (#). You take a scan of the area (your puzzle input).
|
||||||
|
|
||||||
|
Strange magic is at work here: each minute, the landscape looks entirely different. In exactly one minute, an
|
||||||
|
open acre can fill with trees, a wooded acre can be converted to a lumberyard, or a lumberyard can be cleared
|
||||||
|
to open ground (the lumber having been sent to other projects).
|
||||||
|
|
||||||
|
The change to each acre is based entirely on the contents of that acre as well as the number of open, wooded,
|
||||||
|
or lumberyard acres adjacent to it at the start of each minute. Here, "adjacent" means any of the eight acres
|
||||||
|
surrounding that acre. (Acres on the edges of the lumber collection area might have fewer than eight adjacent
|
||||||
|
acres; the missing acres aren't counted.)
|
||||||
|
|
||||||
|
In particular:
|
||||||
|
|
||||||
|
• An open acre will become filled with trees if three or more adjacent acres contained trees. Otherwise,
|
||||||
|
nothing happens.
|
||||||
|
• An acre filled with trees will become a lumberyard if three or more adjacent acres were lumberyards.
|
||||||
|
Otherwise, nothing happens.
|
||||||
|
• An acre containing a lumberyard will remain a lumberyard if it was adjacent to at least one other
|
||||||
|
lumberyard and at least one acre containing trees. Otherwise, it becomes open.
|
||||||
|
|
||||||
|
These changes happen across all acres simultaneously, each of them using the state of all acres at the
|
||||||
|
beginning of the minute and changing to their new form by the end of that same minute. Changes that happen
|
||||||
|
during the minute don't affect each other.
|
||||||
|
|
||||||
|
For example, suppose the lumber collection area is instead only 10 by 10 acres with this initial
|
||||||
|
configuration:
|
||||||
|
|
||||||
|
Initial state:
|
||||||
|
.#.#...|#.
|
||||||
|
.....#|##|
|
||||||
|
.|..|...#.
|
||||||
|
..|#.....#
|
||||||
|
#.#|||#|#|
|
||||||
|
...#.||...
|
||||||
|
.|....|...
|
||||||
|
||...#|.#|
|
||||||
|
|.||||..|.
|
||||||
|
...#.|..|.
|
||||||
|
|
||||||
|
After 1 minute:
|
||||||
|
.......##.
|
||||||
|
......|###
|
||||||
|
.|..|...#.
|
||||||
|
..|#||...#
|
||||||
|
..##||.|#|
|
||||||
|
...#||||..
|
||||||
|
||...|||..
|
||||||
|
|||||.||.|
|
||||||
|
||||||||||
|
||||||
|
....||..|.
|
||||||
|
|
||||||
|
After 2 minutes:
|
||||||
|
.......#..
|
||||||
|
......|#..
|
||||||
|
.|.|||....
|
||||||
|
..##|||..#
|
||||||
|
..###|||#|
|
||||||
|
...#|||||.
|
||||||
|
|||||||||.
|
||||||
|
||||||||||
|
||||||
|
||||||||||
|
||||||
|
.|||||||||
|
||||||
|
|
||||||
|
After 3 minutes:
|
||||||
|
.......#..
|
||||||
|
....|||#..
|
||||||
|
.|.||||...
|
||||||
|
..###|||.#
|
||||||
|
...##|||#|
|
||||||
|
.||##|||||
|
||||||
|
||||||||||
|
||||||
|
||||||||||
|
||||||
|
||||||||||
|
||||||
|
||||||||||
|
||||||
|
|
||||||
|
After 4 minutes:
|
||||||
|
.....|.#..
|
||||||
|
...||||#..
|
||||||
|
.|.#||||..
|
||||||
|
..###||||#
|
||||||
|
...###||#|
|
||||||
|
|||##|||||
|
||||||
|
||||||||||
|
||||||
|
||||||||||
|
||||||
|
||||||||||
|
||||||
|
||||||||||
|
||||||
|
|
||||||
|
After 5 minutes:
|
||||||
|
....|||#..
|
||||||
|
...||||#..
|
||||||
|
.|.##||||.
|
||||||
|
..####|||#
|
||||||
|
.|.###||#|
|
||||||
|
|||###||||
|
||||||
|
||||||||||
|
||||||
|
||||||||||
|
||||||
|
||||||||||
|
||||||
|
||||||||||
|
||||||
|
|
||||||
|
After 6 minutes:
|
||||||
|
...||||#..
|
||||||
|
...||||#..
|
||||||
|
.|.###|||.
|
||||||
|
..#.##|||#
|
||||||
|
|||#.##|#|
|
||||||
|
|||###||||
|
||||||
|
||||#|||||
|
||||||
|
||||||||||
|
||||||
|
||||||||||
|
||||||
|
||||||||||
|
||||||
|
|
||||||
|
After 7 minutes:
|
||||||
|
...||||#..
|
||||||
|
..||#|##..
|
||||||
|
.|.####||.
|
||||||
|
||#..##||#
|
||||||
|
||##.##|#|
|
||||||
|
|||####|||
|
||||||
|
|||###||||
|
||||||
|
||||||||||
|
||||||
|
||||||||||
|
||||||
|
||||||||||
|
||||||
|
|
||||||
|
After 8 minutes:
|
||||||
|
..||||##..
|
||||||
|
..|#####..
|
||||||
|
|||#####|.
|
||||||
|
||#...##|#
|
||||||
|
||##..###|
|
||||||
|
||##.###||
|
||||||
|
|||####|||
|
||||||
|
||||#|||||
|
||||||
|
||||||||||
|
||||||
|
||||||||||
|
||||||
|
|
||||||
|
After 9 minutes:
|
||||||
|
..||###...
|
||||||
|
.||#####..
|
||||||
|
||##...##.
|
||||||
|
||#....###
|
||||||
|
|##....##|
|
||||||
|
||##..###|
|
||||||
|
||######||
|
||||||
|
|||###||||
|
||||||
|
||||||||||
|
||||||
|
||||||||||
|
||||||
|
|
||||||
|
After 10 minutes:
|
||||||
|
.||##.....
|
||||||
|
||###.....
|
||||||
|
||##......
|
||||||
|
|##.....##
|
||||||
|
|##.....##
|
||||||
|
|##....##|
|
||||||
|
||##.####|
|
||||||
|
||#####|||
|
||||||
|
||||#|||||
|
||||||
|
||||||||||
|
||||||
|
|
||||||
|
After 10 minutes, there are 37 wooded acres and 31 lumberyards. Multiplying the number of wooded acres by the
|
||||||
|
number of lumberyards gives the total resource value after ten minutes: 37 * 31 = 1147.
|
||||||
|
|
||||||
|
What will the total resource value of the lumber collection area be after 10 minutes?
|
||||||
|
|
||||||
|
Your puzzle answer was 644640.
|
||||||
|
|
||||||
|
--- Part Two ---
|
||||||
|
|
||||||
|
This important natural resource will need to last for at least thousands of years. Are the Elves collecting
|
||||||
|
this lumber sustainably?
|
||||||
|
|
||||||
|
What will the total resource value of the lumber collection area be after 1000000000 minutes?
|
||||||
|
|
||||||
|
Your puzzle answer was 191080.
|
||||||
|
|
||||||
|
Both parts of this puzzle are complete! They provide two gold stars: **
|
||||||
|
|
||||||
|
References
|
||||||
|
|
||||||
|
Visible links
|
||||||
|
. https://adventofcode.com/
|
||||||
|
. https://adventofcode.com/2018/about
|
||||||
|
. https://adventofcode.com/2018/events
|
||||||
|
. https://adventofcode.com/2018/settings
|
||||||
|
. https://adventofcode.com/2018/auth/logout
|
||||||
|
. Advent of Code Supporter
|
||||||
|
https://adventofcode.com/2018/support
|
||||||
|
. https://adventofcode.com/2018
|
||||||
|
. https://adventofcode.com/2018
|
||||||
|
. https://adventofcode.com/2018/support
|
||||||
|
. https://adventofcode.com/2018/sponsors
|
||||||
|
. https://adventofcode.com/2018/leaderboard
|
||||||
|
. https://adventofcode.com/2018/stats
|
||||||
|
. https://adventofcode.com/2018/sponsors
|
||||||
|
. https://adventofcode.com/2018
|
||||||
|
. https://adventofcode.com/2018/day/18/input
|
10
2018/day18/testinput
Normal file
10
2018/day18/testinput
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
.#.#...|#.
|
||||||
|
.....#|##|
|
||||||
|
.|..|...#.
|
||||||
|
..|#.....#
|
||||||
|
#.#|||#|#|
|
||||||
|
...#.||...
|
||||||
|
.|....|...
|
||||||
|
||...#|.#|
|
||||||
|
|.||||..|.
|
||||||
|
...#.|..|.
|
Loading…
Reference in New Issue
Block a user