2018 day 18 Done

This commit is contained in:
Brian Buller 2018-12-18 09:34:19 -06:00
parent 3f65da791c
commit 1f6e1c932c
4 changed files with 465 additions and 0 deletions

202
2018/day18/day18.go Normal file
View 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
View File

@ -0,0 +1,50 @@
.#|#.##....#|....|.#.#.|||.#.|....||....|...|..#..
..|#||.|#..|...|#|..#...|#...#..#..|.....||..#.|#.
#|||#..||.....||.#................|..#.##|.#...#.|
|#..#.|...##...#..#|#|#..|#.#...|....#..#...##....
.###.........|.||#...#|.|#.||||#..|...||....#..#..
###.|..|#|...|..||..##.....|..#.|.#.............|.
..|.|.||.#....|...|....#|.........##||..#||..|.##.
#||#|...#|..|.|.||#...#|...|#.......|...#.....|...
....||.....|.|.....#...|.......|...|..|...|......|
#......#..#|#|..|....#.|.|.#...#.#.|..#.|.....#.#.
.|#...|...........#|.#....#.#...#.|..|...|....|.|.
..||.#.|...||#|....#.#..||#..#...#|..#..|..#|.....
|..|.|..#...|.....#.|..|#.||..#|.|.||#|#..|#...##|
..|..|#......||##..|........#.|...#.|.|#.#...||..#
#.|...#.||#..|.|..|..|.#....|.||....|.|....#....#.
#||.|.#..#..|...#....##|#..#...#.#...|.#...#.....#
#.|.##.|##..#.##|##........#.|...#...|..#|.#|#|...
.|#|....|.#...#..|||.#.||..#||.||.|..#.|....|..##.
|.#.||#|.##.|.||.....#...#.#..###|.#......||#|....
.|.#..|#||......|##..##.#|..#|.|#.|.|#......|#.|#.
#..|........|||..|###..|#..|||#.|.|.....#|..|...|#
..####||#......|#||..###.|...|....#..|.#|.||....||
|##.......|||..........|..||.#.|#.......##...|...|
|.......#......####|#|....#....|......#.|#.###...#
#|.#.|||...|..|.....#....|...|......|#|#|......||.
...#.|......#..||||.#|.....|.|.|||.|.|.|#|.#...#.#
#.#.##.|.#|.|...|...|...#|...#.|#..|..##.|....#..|
|...#.......#....#....#.#....#.#|.|#||.|.|.|#...#.
#..|.||..|.#..|.#.....#|##.|.|....|....||.......|.
..||.#..|#|.###....#.#|..#|.#..........#...|...#|.
|#||.|.#..|....|....#.#||#.|......#..|#.#.|||||#|.
.|#.|#.##.....#.|.#.....|....|.#..#.#..|#.#.....|.
#.||.#.......|..|......|#||.|..#....#...|...|...|.
|.....#.|.....#||.....##...#.#...||.|..#........|.
||#..|.##.#...........#..|..|.|..#....|...#..||.#.
..||.##.##.|.||......#...|.#.#.#..#.#...##.#.|.#..
.|.#......#|#||.|.#|......||.#.|.|..|....#...||...
....|.##.....|#|####.#..#..#|.....|.#.#|......|...
...#..|......#....|#.#...|...|.#.#.......#.#.##..#
.|||#.||||...|..|#||.|.#|#||..|..#..|..|..#||.....
.....|..#..|#|.||.#||.||......|||..|..#|.|##......
.#...#|..#..|||..||.|..|.#.#.......||..|...|.|....
.##.||..|..||.|.......#.|||.|.|..|.#.#..|.||.|#|||
.|..##|..#.#|#|....|.#.#.#|#.#|.##|........###...#
..#..|#|...#.........#.#.####..#.#..#..#||#|...#|#
#.|...|.......|.#.#..#.|#..#|#|..#..|.....|..|...|
.##.|..#.....|...#..|#..|.|.#..##.#.|..#.|..|.##..
....|..|.|..||....|...|.....#..|.|.....|.#|......#
...##.|#..#..|.#|.##....|.#...||#|.....#...##.#|..
.|....##.....||...#.#.....#|#...#...#|.|..#.#.#.##

203
2018/day18/problem Normal file
View 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
View File

@ -0,0 +1,10 @@
.#.#...|#.
.....#|##|
.|..|...#.
..|#.....#
#.#|||#|#|
...#.||...
.|....|...
||...#|.#|
|.||||..|.
...#.|..|.