11 "import collections\n",
25 "Link = collections.namedtuple('Link', 'height left right')"
36 "def extract_pairs(net_string):\n",
37 " return [[int(pi) for pi in p.split(', ')] for p in net_string[1:-1].split('), (')]"
48 "def read_net_string(net_string):\n",
49 " return [Link(h, l, r) for h, (l, r) in enumerate(extract_pairs(net_string))]"
60 "def read_net(filename):\n",
61 " with open(filename) as f:\n",
62 " pairs = [re.split('\\D+', p.strip()) for p in f.readlines()]\n",
63 " lrs = [(int(lr[1]), int(lr[2])) for lr in pairs]\n",
64 " return [Link(h, l, r) \n",
65 " for h, (l, r) in enumerate(lrs)]"
76 "[Link(height=0, left=2, right=3),\n",
77 " Link(height=1, left=2, right=6),\n",
78 " Link(height=2, left=3, right=7),\n",
79 " Link(height=3, left=5, right=6),\n",
80 " Link(height=4, left=0, right=1),\n",
81 " Link(height=5, left=0, right=1),\n",
82 " Link(height=6, left=6, right=7),\n",
83 " Link(height=7, left=2, right=5),\n",
84 " Link(height=8, left=6, right=9),\n",
85 " Link(height=9, left=4, right=8),\n",
86 " Link(height=10, left=0, right=2),\n",
87 " Link(height=11, left=5, right=7),\n",
88 " Link(height=12, left=4, right=8),\n",
89 " Link(height=13, left=1, right=5),\n",
90 " Link(height=14, left=6, right=8),\n",
91 " Link(height=15, left=6, right=9),\n",
92 " Link(height=16, left=2, right=5),\n",
93 " Link(height=17, left=1, right=8),\n",
94 " Link(height=18, left=5, right=7),\n",
95 " Link(height=19, left=2, right=9)]"
100 "output_type": "execute_result"
104 "small_net = read_net('04-small.txt')\n",
110 "execution_count": 7,
119 "execution_count": 7,
121 "output_type": "execute_result"
125 "net = read_net('04-lines.txt')\n",
131 "execution_count": 8,
137 "def show_net(links, pair_sep=', '):\n",
138 " return pair_sep.join('({}, {})'.format(l.left, l.right) for l in sorted(links))"
143 "execution_count": 9,
149 "def link_ends(link):\n",
150 " return set((link.left, link.right))"
155 "execution_count": 10,
161 "def follow(initial_line, links):\n",
162 " line = initial_line\n",
163 " heights = sorted(set(l.height for l in links))\n",
164 " for h in heights:\n",
165 " for l in [l for l in links if l.height == h]:\n",
166 " if line in link_ends(l):\n",
167 " line = [e for e in link_ends(l) if e != line][0]\n",
168 "# print(l, line)\n",
174 "execution_count": 11,
181 " packed_links = []\n",
182 " line_heights = collections.defaultdict(lambda: -1)\n",
183 " for link in sorted(net):\n",
184 " link_height = max(line_heights[link.left], line_heights[link.right]) + 1\n",
185 " line_heights[link.left] = link_height\n",
186 " line_heights[link.right] = link_height\n",
187 " packed_links += [Link(link_height, link.left, link.right)]\n",
188 " return sorted(packed_links)"
193 "execution_count": 12,
202 "execution_count": 12,
204 "output_type": "execute_result"
208 "max(l.height for l in small_net)"
213 "execution_count": 13,
222 "execution_count": 13,
224 "output_type": "execute_result"
228 "max(l.height for l in pack(small_net))"
233 "execution_count": 14,
242 "execution_count": 14,
244 "output_type": "execute_result"
248 "max(l.height for l in net)"
253 "execution_count": 15,
262 "execution_count": 16,
271 "execution_count": 16,
273 "output_type": "execute_result"
277 "max(l.height for l in pnet)"
282 "execution_count": 17,
288 "def height_groups(net):\n",
289 " return {h: list(g) for h, g in itertools.groupby(pack(net), lambda l: l.height)}"
294 "execution_count": 18,
300 "def follow_many(in_sequence, net):\n",
301 " hgs = height_groups(net)\n",
302 " seq = list(in_sequence)\n",
304 " for link in hgs[h]:\n",
305 " seq[link.right], seq[link.left] = seq[link.left], seq[link.right]\n",
311 "execution_count": 19,
320 "execution_count": 19,
322 "output_type": "execute_result"
326 "''.join(follow_many('abcdefghij', small_net))"
331 "execution_count": 20,
336 "output_type": "stream",
338 "10000 loops, best of 3: 50.4 µs per loop\n"
344 "follow_many('abcdefghij', small_net)"
349 "execution_count": 21,
355 "'doqzmbishkwunvltpcexyjgfra'"
358 "execution_count": 21,
360 "output_type": "execute_result"
364 "''.join(follow_many(string.ascii_lowercase, net))"
369 "execution_count": 22,
374 "output_type": "stream",
376 "10 loops, best of 3: 21 ms per loop\n"
382 "follow_many(string.ascii_lowercase, net)"
387 "execution_count": null,
397 "display_name": "Python 3",
398 "language": "python",
406 "file_extension": ".py",
407 "mimetype": "text/x-python",
409 "nbconvert_exporter": "python",
410 "pygments_lexer": "ipython3",