I've gotta stop for now.

master
Brian Buller 5 years ago
parent 3d7ac83d3f
commit d16cc22158
  1. 317
      2017/day21/day21.go
  2. 108
      2017/day21/input
  3. 2
      2017/day21/testinput
  4. 213
      2017/day22/day22.go
  5. 25
      2017/day22/input
  6. 263
      2017/day22/problem
  7. 3
      2017/day22/testinput

@ -0,0 +1,317 @@
package main
import (
"bufio"
"fmt"
"log"
"math"
"os"
"strings"
"time"
)
var allRules []Rule
func main() {
inp := StdinToStrings()
for i := range inp {
allRules = append(allRules, Rule(inp[i]))
}
//pattern := Pattern(".#./..#/###")
pattern := Pattern("../##")
fmt.Println(pattern)
if !pattern.IsValid() {
fmt.Println("Invalid Pattern Given. Must be square.")
}
ClearScreen()
pattern.PrettyPrint()
time.Sleep(time.Second)
for iters := 0; iters < 5; iters++ {
ClearScreen()
pattern = Tick(pattern)
pattern.PrettyPrint()
time.Sleep(time.Second)
}
fmt.Println("On:", pattern.GetOnCount())
}
// Stitch takes a slice of patterns and turns them into one large (square) pattern
func Stitch(inp []Pattern) Pattern {
ppr := int(math.Sqrt(float64(len(inp))))
newSize := ppr * inp[0].Size()
var currRow int
rows := make(map[int]string)
for i := 0; i < len(inp); i++ {
currRow = (i / ppr) * 2
for j := 0; j < len(inp[0]); j++ {
if len(rows[currRow+j]) == newSize {
rows[currRow+j] += "/"
}
rows[currRow+j] += inp[i].GetRow(j)
}
}
var lines []string
for i := 0; i < newSize; i++ {
lines = append(lines, rows[i])
}
return Pattern(strings.Join(lines, "/"))
}
// Run the pattern, or all of it's subpatterns
// through the rules and return the new pattern
func Tick(inp Pattern) Pattern {
if inp.SubpatternCount() > 1 {
var subs []Pattern
// Tick each subpattern
for i := 0; i < inp.SubpatternCount(); i++ {
if s := inp.GetSubpattern(i); s.IsValid() {
subs = append(subs, Tick(s))
} else {
log.Fatal("Error ticking pattern")
}
}
return Stitch(subs)
}
var foundMatch bool
for i := range allRules {
if allRules[i].Matches(inp) {
inp = allRules[i].Output()
foundMatch = true
}
}
if !foundMatch {
fmt.Println("~ ERROR TICKING ~")
inp.PrettyPrint()
fmt.Println("~ ERROR TICKING ~")
os.Exit(1)
}
return inp
}
/**
* A pattern is a string with some special methods
*/
type Pattern string
// Print a pattern prettily. (in a square)
func (p Pattern) PrettyPrint() {
pts := strings.Split(string(p), "/")
for i := range pts {
fmt.Println(pts[i])
}
}
func (p Pattern) GetOnCount() int {
return strings.Count(string(p), "#")
}
// Returns if a pattern is valid.
// A pattern is valid if it has more than 0 rows
// and every row is the same length as the number
// of columns
func (p Pattern) IsValid() bool {
pts := strings.Split(string(p), "/")
if len(pts) == 0 {
return false
}
for i := range pts {
if len(pts[i]) != len(pts) {
return false
}
}
return true
}
// Returns the "size" of the pattern
// That is, how many rows/columns it has
func (p Pattern) Size() int {
return len(strings.Split(string(p), "/"))
}
// Flip returns a new pattern that has been flipped horizontally
func (p Pattern) Flip() Pattern {
// We can only flip the smallest patterns (2x2 or 3x3)
if p.SubpatternCount() != 1 {
return p
}
pts := strings.Split(string(p), "/")
for i := range pts {
pts[i] = RevString(pts[i])
}
return Pattern(strings.Join(pts, "/"))
}
// Rotate returns a new pattern that has been rotated deg degrees
// Only right-angles
func (p Pattern) Rotate(deg int) Pattern {
// We can only rotate the smallest patterns (2x2 or 3x3)
if p.SubpatternCount() != 1 {
return p
}
if deg < 0 {
deg += 360
} else if deg == 0 {
return p
}
pts := strings.Split(string(p), "/")
ret := make([]string, len(pts))
use := p
switch deg {
case 90:
if p.Size()%3 == 0 {
ret[0] = RevString(use.GetCol(2))
ret[1] = RevString(use.GetCol(1))
ret[2] = RevString(use.GetCol(0))
} else {
ret[0] = RevString(use.GetCol(1))
ret[1] = RevString(use.GetCol(0))
}
case 180:
if p.Size()%3 == 0 {
ret[0] = RevString(use.GetRow(2))
ret[1] = RevString(use.GetRow(1))
ret[2] = RevString(use.GetRow(0))
} else {
ret[0] = RevString(use.GetRow(1))
ret[1] = RevString(use.GetRow(0))
}
case 270:
if p.Size()%3 == 0 {
ret[0] = use.GetCol(2)
ret[1] = use.GetCol(1)
ret[2] = use.GetCol(0)
} else {
ret[0] = use.GetCol(1)
ret[1] = use.GetCol(0)
}
}
use = Pattern(strings.Join(ret, "/"))
return Pattern(strings.Join(ret, "/"))
}
// GetRow returns a row as a string
func (p Pattern) GetRow(row int) string {
pts := strings.Split(string(p), "/")
if row >= len(pts) {
return ""
}
return pts[row]
}
// GetCol returns a column as a string
func (p Pattern) GetCol(col int) string {
var ret string
pts := strings.Split(string(p), "/")
if col >= len(pts[0]) {
return ""
}
for i := 0; i < len(pts); i++ {
ret = ret + string(pts[i][col])
}
return ret
}
// Counts the number of subpatterns in the pattern
func (p Pattern) SubpatternCount() int {
if p.Size()%2 == 0 {
return (p.Size() / 2) * (p.Size() / 2)
} else {
return (p.Size() / 3) * (p.Size() / 3)
}
}
// Gets a specific subpattern out of the pattern
func (p Pattern) GetSubpattern(i int) Pattern {
if i > p.SubpatternCount() {
return Pattern("")
}
subSize := 3 // Assume 3x3 subpatterns
if p.Size()%2 == 0 {
// Subpatterns are actually 2x2
subSize = 2
}
ppr := p.Size() / subSize
col := i % (p.Size() / subSize)
row := i / ppr
ptString := ""
for j := 0; j < subSize; j++ {
ptString += p.GetRow((row * 2) + j)[(col*subSize):(col*subSize)+subSize] + "/"
}
return Pattern(ptString[:len(ptString)-1])
}
/**
* Rule is an interface that can take a pattern and return if it matches,
* report on it's size, or return the resulting pattern from applying itself
* to a pattern
*/
type RuleFace interface {
Matches(inp Pattern) bool
InputSize() int
Apply(inp Pattern) Pattern
}
/**
* Rule implements the RuleFace interface
* for 2x2 => 3x3 transitions
* or 3x3 => 4x4 transitions
*/
type Rule string
func (r Rule) Input() Pattern {
pts := strings.Split(string(r), " ")
return Pattern(pts[0])
}
func (r Rule) Output() Pattern {
pts := strings.Split(string(r), " ")
return Pattern(pts[2])
}
func (r Rule) Matches(inp Pattern) bool {
if inp.Size() != r.InputSize() {
return false
}
// Try it rotated 90,180,270
for i := 0; i < 360; i += 90 {
if r.Equals(inp.Rotate(i)) || r.Equals(inp.Flip().Rotate(i)) {
return true
}
}
return false
}
func (r Rule) InputSize() int {
return len(strings.Split(string(r.Input()), "/"))
}
// Equals is a direct string comparison
func (r Rule) Equals(inp Pattern) bool {
return string(r.Input()) == string(inp)
}
func RevString(s string) string {
runes := []rune(s)
for i, j := 0, len(runes)-1; i < j; i, j = i+1, j-1 {
runes[i], runes[j] = runes[j], runes[i]
}
return string(runes)
}
func ClearScreen() {
fmt.Println("\033[H\033[2J")
}
func StdinToStrings() []string {
var input []string
scanner := bufio.NewScanner(os.Stdin)
for scanner.Scan() {
input = append(input, scanner.Text())
}
return input
}

@ -0,0 +1,108 @@
../.. => .../.../..#
#./.. => #.#/..#/...
##/.. => #.#/..#/#.#
.#/#. => #../.../.##
##/#. => ###/#.#/..#
##/## => #.#/.../#..
.../.../... => #..#/..../.##./....
#../.../... => ..../.##./#.../.##.
.#./.../... => .#../####/..##/#...
##./.../... => ##.#/..#./####/...#
#.#/.../... => ##.#/##../#.#./.#..
###/.../... => #..#/#..#/##../##.#
.#./#../... => #.##/##../.#.#/..##
##./#../... => #.#./..../.###/.#.#
..#/#../... => ..##/####/..##/....
#.#/#../... => ..##/###./..##/#...
.##/#../... => #.../####/#..#/##..
###/#../... => ...#/..../..##/#...
.../.#./... => ##../##../..##/....
#../.#./... => #.../.#.#/.##./#..#
.#./.#./... => ..##/#.../...#/###.
##./.#./... => ####/.#.#/..##/####
#.#/.#./... => ####/.#../#.##/#..#
###/.#./... => ..#./#..#/.#.#/###.
.#./##./... => ##../.#.#/#..#/#..#
##./##./... => .###/####/#..#/..##
..#/##./... => ###./.#../..#./#.##
#.#/##./... => ##../#.#./#.../.#.#
.##/##./... => #.../#.../.#.#/####
###/##./... => .#../####/#.../#.#.
.../#.#/... => .#../..../##../.###
#../#.#/... => .##./...#/.###/...#
.#./#.#/... => ...#/#.../...#/####
##./#.#/... => #.##/..#./#..#/.#.#
#.#/#.#/... => #..#/..../..##/..#.
###/#.#/... => .#.#/#.#./##.#/#.#.
.../###/... => ##../.##./###./###.
#../###/... => ###./..##/.#../##.#
.#./###/... => .#../##../..../..##
##./###/... => #.#./...#/...#/##..
#.#/###/... => ..../.#../#.../.#..
###/###/... => ..#./.###/..../##.#
..#/.../#.. => #.#./.#../...#/##.#
#.#/.../#.. => ...#/##.#/#.#./#...
.##/.../#.. => ...#/..##/#.##/##.#
###/.../#.. => #..#/.#.#/.##./..#.
.##/#../#.. => ##../..#./#.##/##..
###/#../#.. => ..../###./#.#./##..
..#/.#./#.. => #.#./.##./.##./#...
#.#/.#./#.. => .#../#..#/#.#./#...
.##/.#./#.. => .#.#/#..#/..#./....
###/.#./#.. => #.##/####/#.../..#.
.##/##./#.. => #.##/.#.#/..../.#..
###/##./#.. => #.##/####/.###/##..
#../..#/#.. => ###./#.##/..#./..##
.#./..#/#.. => ##../.#../..#./..##
##./..#/#.. => #..#/.#../..../##.#
#.#/..#/#.. => .###/.##./..#./#.#.
.##/..#/#.. => .#.#/..../####/.#..
###/..#/#.. => .##./##../...#/.#..
#../#.#/#.. => #.#./#.##/..../.###
.#./#.#/#.. => ####/#.#./.#../#.##
##./#.#/#.. => ..##/.###/###./..#.
..#/#.#/#.. => .##./..#./..../#.#.
#.#/#.#/#.. => .###/..../..../##..
.##/#.#/#.. => #.#./#.../####/.###
###/#.#/#.. => #.../..##/###./#..#
#../.##/#.. => ..../#.#./..##/.#.#
.#./.##/#.. => ..##/..##/#..#/###.
##./.##/#.. => #.../.#../#.#./#.##
#.#/.##/#.. => ...#/#.../...#/###.
.##/.##/#.. => ###./..../..##/#..#
###/.##/#.. => #.#./##.#/####/#.#.
#../###/#.. => ##../##../###./#..#
.#./###/#.. => #.##/###./####/..##
##./###/#.. => ..../.###/###./.#..
..#/###/#.. => .###/..../..#./....
#.#/###/#.. => ####/#..#/.#.#/..##
.##/###/#.. => ..../##.#/####/##.#
###/###/#.. => #..#/.#.#/###./.##.
.#./#.#/.#. => #.##/...#/###./....
##./#.#/.#. => #..#/.#../..../#.#.
#.#/#.#/.#. => .#.#/####/..../.#.#
###/#.#/.#. => #.#./#.##/##.#/##..
.#./###/.#. => ..#./..../##../####
##./###/.#. => #.##/##.#/#.##/.#..
#.#/###/.#. => .#.#/..##/##.#/####
###/###/.#. => .#../...#/#..#/#.#.
#.#/..#/##. => .##./..#./...#/##.#
###/..#/##. => ..#./##.#/#..#/#..#
.##/#.#/##. => ##.#/#.../#..#/...#
###/#.#/##. => ##../.#../..../.##.
#.#/.##/##. => #.##/##.#/.#../.###
###/.##/##. => ..../#.#./##../##.#
.##/###/##. => ###./.#.#/.##./.###
###/###/##. => #..#/.###/#.../#...
#.#/.../#.# => .###/#.##/.#.#/#.#.
###/.../#.# => ...#/##../...#/##.#
###/#../#.# => ..../..#./..#./####
#.#/.#./#.# => ##../#.##/...#/#...
###/.#./#.# => #.#./...#/.#../#...
###/##./#.# => .#../..#./...#/##..
#.#/#.#/#.# => ####/#.##/.#../##..
###/#.#/#.# => #.../#.../###./.#..
#.#/###/#.# => ####/.#.#/.##./.#.#
###/###/#.# => #.##/.#.#/##.#/..##
###/#.#/### => .###/#.##/..../..#.
###/###/### => .###/#..#/##../.##.

@ -0,0 +1,2 @@
../.# => ##./#../...
.#./..#/### => #..#/..../..../#..#

@ -0,0 +1,213 @@
package main
import (
"bufio"
"fmt"
"log"
"os"
"strconv"
"strings"
)
const (
N = iota
E
S
W
)
const (
ST_CLEAN = iota
ST_WEAK
ST_INFECTED
ST_FLAGGED
ST_ERROR
)
var nodes map[string]int
var cX, cY, cD int
var minX, minY, maxX, maxY int
var tickCount, infectCount int
func main() {
inp := StdinToStrings()
nodes = make(map[string]int)
cX, cY, cD = len(inp)/2, len(inp[0])/2, N
for y := 0; y < len(inp); y++ {
for x := 0; x < len(inp[y]); x++ {
nodes[cs(x, y)] = ST_CLEAN
if inp[y][x] == '#' {
nodes[cs(x, y)] = ST_INFECTED
}
updateMinMax(x, y)
}
}
for i := 0; i < 10000000; i++ {
//ClearScreen()
if part1 {
p1Tick()
} else {
p2Tick()
}
//PrettyPrint()
//PrintStatus()
//time.Sleep(time.Second / 5)
}
}
func p1Tick() {
tickCount++
switch nodes[cs(cX, cY)] {
case ST_INFECTED:
TurnRight()
nodes[cs(cX, cY)] = ST_CLEAN
infectCount++
default:
TurnLeft()
nodes[cs(cX, cY)] = ST_INFECTED
infectCount++
}
cX, cY = getXYInDir()
updateMinMax(cX, cY)
}
func p2Tick() {
tickCount++
switch nodes[cs(cX, cY)] {
case ST_CLEAN:
TurnLeft()
nodes[cs(cX, cY)] = ST_WEAK
case ST_WEAK:
nodes[cs(cX, cY)] = ST_INFECTED
infectCount++
case ST_INFECTED:
TurnRight()
nodes[cs(cX, cY)] = ST_FLAGGED
case ST_FLAGGED:
TurnRight()
TurnRight()
nodes[cs(cX, cY)] = ST_CLEAN
}
cX, cY = getXYInDir()
updateMinMax(cX, cY)
}
func updateMinMax(x, y int) {
if x < minX {
minX = x
}
if x > maxX {
maxX = x
}
if y < minY {
minY = y
}
if y > maxY {
maxY = y
}
}
func PrettyPrint() {
for kY := minY; kY <= maxY; kY++ {
for kX := minX; kX <= maxX; kX++ {
if kX == cX && kY == cY {
fmt.Print("[")
} else {
fmt.Print(" ")
}
switch nodes[cs(kX, kY)] {
case ST_CLEAN:
fmt.Print(".")
case ST_WEAK:
fmt.Print("W")
case ST_INFECTED:
fmt.Print("#")
case ST_FLAGGED:
fmt.Print("F")
}
if kX == cX && kY == cY {
fmt.Print("]")
} else {
fmt.Print(" ")
}
}
fmt.Println()
}
}
func PrintStatus() {
fmt.Println("Ticks:", tickCount)
fmt.Println("Infections:", infectCount)
}
func TurnRight() {
switch cD {
case N:
cD = E
case E:
cD = S
case S:
cD = W
case W:
cD = N
}
}
func TurnLeft() {
switch cD {
case N:
cD = W
case E:
cD = N
case S:
cD = E
case W:
cD = S
}
}
func getXYInDir() (int, int) {
switch cD {
case N:
return cX, cY - 1
case E:
return cX + 1, cY
case S:
return cX, cY + 1
case W:
return cX - 1, cY
}
return cX, cY
}
func cs(x, y int) string {
return fmt.Sprintf("%d;%d", x, y)
}
func sc(key string) (int, int) {
pts := strings.Split(key, ";")
return Atoi(pts[0]), Atoi(pts[1])
}
func Atoi(i string) int {
var ret int
var err error
if ret, err = strconv.Atoi(i); err != nil {
log.Fatal("Invalid Atoi")
}
return ret
}
func ClearScreen() {
fmt.Println("\033[H\033[2J")
}
func StdinToStrings() []string {
var input []string
scanner := bufio.NewScanner(os.Stdin)
for scanner.Scan() {
input = append(input, scanner.Text())
}
return input
}

@ -0,0 +1,25 @@
###.#######...#####.#..##
.####...###.##...#..#....
.#.#...####.###..##..##.#
########.#.#...##.#.##.#.
..#.#...##..#.#.##..####.
..#.#.....#....#####..#..
#.#..##...#....#.##...###
.#.##########...#......#.
.#...#..##...#...###.#...
......#.###.#..#...#.####
.#.###.##...###.###.###.#
.##..##...#.#.#####.#...#
#...#..###....#.##.......
####.....######.#.##..#..
..#...#..##.####.#####.##
#...#.#.#.#.#...##..##.#.
#####.#...#.#.#.#.##.####
....###...#.##.#.##.####.
.#....###.#####...#.....#
#.....#....#####.#..#....
.#####.#....#..##.#.#.###
####.#..#..##..#.#..#.###
.##.##.#.#.#.#.#..####.#.
#####..##.#.#..#..#...#..
#.#..#.###...##....###.##

@ -0,0 +1,263 @@
Advent of Code
--- Day 22: Sporifica Virus ---
Diagnostics indicate that the local grid computing cluster has been
contaminated with the Sporifica Virus. The grid computing cluster is a
seemingly-infinite two-dimensional grid of compute nodes. Each node is either
clean or infected by the virus.
To prevent overloading the nodes (which would render them useless to the
virus) or detection by system administrators, exactly one virus carrier moves
through the network, infecting or cleaning nodes as it moves. The virus
carrier is always located on a single node in the network (the current node)
and keeps track of the direction it is facing.
To avoid detection, the virus carrier works in bursts; in each burst, it
wakes up, does some work, and goes back to sleep. The following steps are all
executed in order one time each burst:
* If the current node is infected, it turns to its right. Otherwise, it
turns to its left. (Turning is done in-place; the current node does not
change.)
* If the current node is clean, it becomes infected. Otherwise, it becomes
cleaned. (This is done after the node is considered for the purposes of
changing direction.)
* The virus carrier moves forward one node in the direction it is facing.
Diagnostics have also provided a map of the node infection status (your
puzzle input). Clean nodes are shown as .; infected nodes are shown as #.
This map only shows the center of the grid; there are many more nodes beyond
those shown, but none of them are currently infected.
The virus carrier begins in the middle of the map facing up.
For example, suppose you are given a map like this:
..#
#..
...
Then, the middle of the infinite grid looks like this, with the virus
carrier's position marked with [ ]:
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . # . . .
. . . #[.]. . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
The virus carrier is on a clean node, so it turns left, infects the node, and
moves left:
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . # . . .
. . .[#]# . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
The virus carrier is on an infected node, so it turns right, cleans the node,
and moves up:
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . .[.]. # . . .
. . . . # . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
Four times in a row, the virus carrier finds a clean, infects it, turns left,
and moves forward, ending in the same place and still facing up:
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . #[#]. # . . .
. . # # # . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
Now on the same node as before, it sees an infection, which causes it to turn
right, clean the node, and move forward:
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . # .[.]# . . .
. . # # # . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
After the above actions, a total of 7 bursts of activity had taken place. Of
them, 5 bursts of activity caused an infection.
After a total of 70, the grid looks like this, with the virus carrier facing
up:
. . . . . # # . .
. . . . # . . # .
. . . # . . . . #
. . # . #[.]. . #
. . # . # . . # .
. . . . . # # . .
. . . . . . . . .
. . . . . . . . .
By this time, 41 bursts of activity caused an infection (though most of those
nodes have since been cleaned).
After a total of 10000 bursts of activity, 5587 bursts will have caused an
infection.
Given your actual map, after 10000 bursts of activity, how many bursts cause
a node to become infected? (Do not count nodes that begin infected.)
Your puzzle answer was _______.
The first half of this puzzle is complete! It provides one gold star: *
--- Part Two ---
As you go to remove the virus from the infected nodes, it evolves to resist
your attempt.
Now, before it infects a clean node, it will weaken it to disable your
defenses. If it encounters an infected node, it will instead flag the node to
be cleaned in the future. So:
* Clean nodes become weakened.
* Weakened nodes become infected.
* Infected nodes become flagged.
* Flagged nodes become clean.
Every node is always in exactly one of the above states.
The virus carrier still functions in a similar way, but now uses the
following logic during its bursts of action:
* Decide which way to turn based on the current node:
* If it is clean, it turns left.
* If it is weakened, it does not turn, and will continue moving in the
same direction.
* If it is infected, it turns right.
* If it is flagged, it reverses direction, and will go back the way it
came.
* Modify the state of the current node, as described above.
* The virus carrier moves forward one node in the direction it is facing.
Start with the same map (still using . for clean and # for infected) and
still with the virus carrier starting in the middle and facing up.
Using the same initial state as the previous example, and drawing weakened as
W and flagged as F, the middle of the infinite grid looks like this, with the
virus carrier's position again marked with [ ]:
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . # . . .
. . . #[.]. . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
This is the same as before, since no initial nodes are weakened or flagged.
The virus carrier is on a clean node, so it still turns left, instead weakens
the node, and moves left:
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . # . . .
. . .[#]W . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
The virus carrier is on an infected node, so it still turns right, instead
flags the node, and moves up:
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . .[.]. # . . .
. . . F W . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
This process repeats three more times, ending on the previously-flagged node
and facing right:
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . W W . # . . .
. . W[F]W . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
Finding a flagged node, it reverses direction and cleans the node:
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . W W . # . . .
. .[W]. W . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
The weakened node becomes infected, and it continues in the same direction:
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . W W . # . . .
.[.]# . W . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
Of the first 100 bursts, 26 will result in infection. Unfortunately, another
feature of this evolved virus is speed; of the first 10000000 bursts, 2511944
will result in infection.
Given your actual map, after 10000000 bursts of activity, how many bursts
cause a node to become infected? (Do not count nodes that begin infected.)
Although it hasn't changed, you can still get your puzzle input.
Answer: _____________________ [ [Submit] ]
References
Visible links
. http://adventofcode.com/
. http://adventofcode.com/2017/about
. http://adventofcode.com/2017/support
. http://adventofcode.com/2017/events
. http://adventofcode.com/2017/settings
. http://adventofcode.com/2017/auth/logout
. http://adventofcode.com/2017
. http://adventofcode.com/2017
. http://adventofcode.com/2017/leaderboard
. http://adventofcode.com/2017/stats
. http://adventofcode.com/2017/sponsors
. http://adventofcode.com/2017/sponsors
. https://en.wikipedia.org/wiki/Morris_worm#The_mistake
. https://www.youtube.com/watch?v=2vj37yeQQHg
. http://adventofcode.com/2017/day/22/input

@ -0,0 +1,3 @@
..#
#..
...
Loading…
Cancel
Save