Added 2017/22 part 1
This commit is contained in:
+255
@@ -0,0 +1,255 @@
|
|||||||
|
## \-\-- 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](https://en.wikipedia.org/wiki/Morris_worm#The_mistake) 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](https://www.youtube.com/watch?v=2vj37yeQQHg) *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 `5266`.
|
||||||
|
|
||||||
|
The first half of this puzzle is complete! It provides one gold star: \*
|
||||||
|
|
||||||
|
## \-\-- Part Two \-\-- {#part2}
|
||||||
|
|
||||||
|
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.)
|
||||||
|
|
||||||
|
Answer:
|
||||||
|
|
||||||
|
Although it hasn\'t changed, you can still [get your puzzle
|
||||||
|
input](22/input).
|
||||||
|
|
||||||
@@ -0,0 +1,116 @@
|
|||||||
|
#!/bin/python3
|
||||||
|
import sys,re
|
||||||
|
from pprint import pprint
|
||||||
|
sys.path.insert(0, '../../')
|
||||||
|
from fred import list2int, toGrid,nprint,get_value_in_direction, expand_grid, getCenter
|
||||||
|
|
||||||
|
input_f = 'input'
|
||||||
|
|
||||||
|
part = 1
|
||||||
|
#########################################
|
||||||
|
# #
|
||||||
|
# Part 1 #
|
||||||
|
# #
|
||||||
|
#########################################
|
||||||
|
|
||||||
|
def goLeft(dir:str):
|
||||||
|
|
||||||
|
if dir == 'north':
|
||||||
|
new_dir = (0,-1)
|
||||||
|
facing = 'west'
|
||||||
|
|
||||||
|
elif dir == 'south':
|
||||||
|
new_dir = (0,1)
|
||||||
|
facing = 'east'
|
||||||
|
|
||||||
|
elif dir == 'east':
|
||||||
|
new_dir = (-1,0)
|
||||||
|
facing = 'north'
|
||||||
|
|
||||||
|
elif dir == 'west':
|
||||||
|
new_dir = (1,0)
|
||||||
|
facing = 'south'
|
||||||
|
|
||||||
|
return new_dir,facing
|
||||||
|
|
||||||
|
def goRight(dir:str):
|
||||||
|
|
||||||
|
if dir == 'north':
|
||||||
|
new_dir = (0,1)
|
||||||
|
facing = 'east'
|
||||||
|
|
||||||
|
elif dir == 'south':
|
||||||
|
new_dir = (0,-1)
|
||||||
|
facing = 'west'
|
||||||
|
|
||||||
|
elif dir == 'east':
|
||||||
|
new_dir = (1,0)
|
||||||
|
facing = 'south'
|
||||||
|
|
||||||
|
elif dir == 'west':
|
||||||
|
new_dir = (-1,0)
|
||||||
|
facing = 'north'
|
||||||
|
else:
|
||||||
|
print('Something is wrong')
|
||||||
|
print(dir)
|
||||||
|
print(new_dir)
|
||||||
|
|
||||||
|
return new_dir,facing
|
||||||
|
|
||||||
|
if part == 1:
|
||||||
|
grid = toGrid(input_f)
|
||||||
|
|
||||||
|
start = getCenter(grid)
|
||||||
|
|
||||||
|
#nprint(grid)
|
||||||
|
|
||||||
|
#print(start)
|
||||||
|
end = False
|
||||||
|
dir = (-1,0)
|
||||||
|
facing = 'north'
|
||||||
|
cur = start
|
||||||
|
infect = 0
|
||||||
|
iter = 1
|
||||||
|
while not end:
|
||||||
|
#print('-----------START-----------')
|
||||||
|
#print(cur[0]-1)
|
||||||
|
if cur[0]-1 <= 0 or cur[0]+1 >= len(grid[0]) or cur[1]+1 >= len(grid) or cur[1]-1 <= 0:
|
||||||
|
#print('Expanding')
|
||||||
|
grid = expand_grid(grid)
|
||||||
|
cur = tuple(map(lambda i, j: i + j, cur, (1,1)))
|
||||||
|
|
||||||
|
#print(cur)
|
||||||
|
|
||||||
|
if get_value_in_direction(grid,cur) == '#':
|
||||||
|
#print('infected')
|
||||||
|
|
||||||
|
dir,facing = goRight(facing)
|
||||||
|
grid[cur[0]][cur[1]] = '.'
|
||||||
|
#cur = (cur[0]+dir[0],cur[1]+dir[1])
|
||||||
|
|
||||||
|
elif get_value_in_direction(grid,cur) == '.':
|
||||||
|
#print('not infected')
|
||||||
|
dir,facing = goLeft(facing)
|
||||||
|
grid[cur[0]][cur[1]] = '#'
|
||||||
|
infect += 1
|
||||||
|
#cur = (cur[0]+dir[0],cur[1]+dir[1])
|
||||||
|
|
||||||
|
|
||||||
|
cur = (cur[0]+dir[0],cur[1]+dir[1])
|
||||||
|
#print(cur,dir,facing)
|
||||||
|
#nprint(grid,cur,'X')
|
||||||
|
#print('-----------END-----------',iter,infect)
|
||||||
|
iter += 1
|
||||||
|
if iter > 10000:
|
||||||
|
end = True
|
||||||
|
#input()
|
||||||
|
print(infect)
|
||||||
|
|
||||||
|
|
||||||
|
#########################################
|
||||||
|
# #
|
||||||
|
# Part 2 #
|
||||||
|
# #
|
||||||
|
#########################################
|
||||||
|
if part == 2:
|
||||||
|
exit()
|
||||||
Binary file not shown.
@@ -9,13 +9,37 @@ def toGrid(input,parser=None):
|
|||||||
else:
|
else:
|
||||||
with open(input) as file:
|
with open(input) as file:
|
||||||
for line in file:
|
for line in file:
|
||||||
grid.append(line.rstrip())
|
grid.append(list(line.rstrip()))
|
||||||
return grid
|
return grid
|
||||||
|
|
||||||
def nprint(grid):
|
def expand_grid(grid):
|
||||||
|
num_rows = len(grid)
|
||||||
|
num_cols = len(grid[0])
|
||||||
|
|
||||||
|
expanded_grid = []
|
||||||
|
|
||||||
|
expanded_grid.append(['.'] * (num_cols + 2))
|
||||||
|
|
||||||
|
for row in grid:
|
||||||
|
expanded_grid.append(['.'] + row + ['.'])
|
||||||
|
|
||||||
|
expanded_grid.append(['.'] * (num_cols + 2))
|
||||||
|
|
||||||
|
return expanded_grid
|
||||||
|
|
||||||
|
def getCenter(grid):
|
||||||
|
return (int(len(grid)/2),int(len(grid[0])/2))
|
||||||
|
|
||||||
|
def nprint(grid,cur:set=None,sign:str=None):
|
||||||
for idx,i in enumerate(grid):
|
for idx,i in enumerate(grid):
|
||||||
for jdx,j in enumerate(i):
|
for jdx,j in enumerate(i):
|
||||||
print(grid[idx][jdx],end='')
|
if (idx,jdx) == cur:
|
||||||
|
if len(sign) > 1:
|
||||||
|
print(sign[0]+grid[idx][jdx]+sign[1],end='')
|
||||||
|
else:
|
||||||
|
print(sign,end=' ')
|
||||||
|
else:
|
||||||
|
print(grid[idx][jdx],end=' ')
|
||||||
print()
|
print()
|
||||||
|
|
||||||
def list2int(x):
|
def list2int(x):
|
||||||
|
|||||||
Reference in New Issue
Block a user