Browse Source

Day 22

master
Chris Smith 7 years ago
parent
commit
c4b159dbe8
2 changed files with 1065 additions and 0 deletions
  1. 64
    0
      22.py
  2. 1001
    0
      data/22.txt

+ 64
- 0
22.py View File

@@ -0,0 +1,64 @@
1
+#!/usr/bin/python3
2
+
3
+"""Solution for day 22 of Advent of Code 2016.
4
+
5
+Part 1 is straight-forward reading of the data, generating pairs using itertools.permutations, and counting how
6
+many match the criteria.
7
+
8
+As is traditional at about this point in Advent of Code, part 2 requires you to make annoying assumptions based on
9
+the vague example in the question and some properties of your input that you have no guarantee are universal.
10
+
11
+In this case, the input needs to be partitioned in to three sets: empty nodes (of which there is just one), giant
12
+nodes (whose data can't possibly be placed anywhere else) and normal nodes (who can shift their data to the empty
13
+node, but not to any other normal node).
14
+
15
+When the nodes are printed out according to their type (as in the example), it becomes obvious that there's a "wall"
16
+of giant nodes in the way. As the only valid moves involve the empty node, you basically have to move that around and
17
+use it to move the data along the top row.
18
+
19
+For my input, it takes 34 moves to rearrange things and then move the target data left by one:
20
+
21
+..............23456789012345678901234
22
+..............1......................
23
+..............0######################
24
+..............9876543................
25
+....................2................
26
+....................1................
27
+...................._................
28
+.....................................
29
+.....................................
30
+
31
+Then for each node to the left it takes an additional five moves, as the empty space loops around our target:
32
+
33
+....45_..
34
+....321..
35
+.........
36
+
37
+It needs to move a total of 35 nodes left, so 34+35*5 total moves = 209.
38
+"""
39
+
40
+import re
41
+
42
+import itertools
43
+
44
+matcher = re.compile(r'^/dev/grid/node-x([0-9]+)-y([0-9]+)\s+([0-9]+)T\s+([0-9]+)T\s+([0-9]+)T\s+.*$')
45
+
46
+# Constants used for convenient access the groups in the matcher above
47
+locx = 0
48
+locy = 1
49
+size = 2
50
+used = 3
51
+free = 4
52
+
53
+with open('data/22.txt', 'r') as data:
54
+    discs = [tuple(map(int, matcher.match(l).groups())) for l in data.readlines() if matcher.match(l)]
55
+    pairs = sum(1 for p in itertools.permutations(discs, 2) if 0 < p[0][used] <= p[1][free])
56
+    print('Part one: %s' % pairs)
57
+
58
+    print('Part two: ...')
59
+    grid = dict((disc[:locy+1], disc) for disc in discs)
60
+    for y in range(27):
61
+        print(''.join(['X' if (x,y) not in grid
62
+                       else '_' if grid[(x, y)][used] == 0
63
+                       else '#' if grid[(x, y)][used] > 150  # Arbitrary cut-off for "normal" vs "giant" nodes
64
+                       else '.' for x in range(37)]))

+ 1001
- 0
data/22.txt
File diff suppressed because it is too large
View File


Loading…
Cancel
Save