Day 14
[advent-of-code-15.git] / advent14.ipynb
diff --git a/advent14.ipynb b/advent14.ipynb
new file mode 100644 (file)
index 0000000..9d34015
--- /dev/null
@@ -0,0 +1,669 @@
+{
+ "cells": [
+  {
+   "cell_type": "code",
+   "execution_count": 2,
+   "metadata": {
+    "collapsed": false
+   },
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "[['Vixen',\n",
+       "  'can',\n",
+       "  'fly',\n",
+       "  '8',\n",
+       "  'km/s',\n",
+       "  'for',\n",
+       "  '8',\n",
+       "  'seconds,',\n",
+       "  'but',\n",
+       "  'then',\n",
+       "  'must',\n",
+       "  'rest',\n",
+       "  'for',\n",
+       "  '53',\n",
+       "  'seconds.'],\n",
+       " ['Blitzen',\n",
+       "  'can',\n",
+       "  'fly',\n",
+       "  '13',\n",
+       "  'km/s',\n",
+       "  'for',\n",
+       "  '4',\n",
+       "  'seconds,',\n",
+       "  'but',\n",
+       "  'then',\n",
+       "  'must',\n",
+       "  'rest',\n",
+       "  'for',\n",
+       "  '49',\n",
+       "  'seconds.'],\n",
+       " ['Rudolph',\n",
+       "  'can',\n",
+       "  'fly',\n",
+       "  '20',\n",
+       "  'km/s',\n",
+       "  'for',\n",
+       "  '7',\n",
+       "  'seconds,',\n",
+       "  'but',\n",
+       "  'then',\n",
+       "  'must',\n",
+       "  'rest',\n",
+       "  'for',\n",
+       "  '132',\n",
+       "  'seconds.'],\n",
+       " ['Cupid',\n",
+       "  'can',\n",
+       "  'fly',\n",
+       "  '12',\n",
+       "  'km/s',\n",
+       "  'for',\n",
+       "  '4',\n",
+       "  'seconds,',\n",
+       "  'but',\n",
+       "  'then',\n",
+       "  'must',\n",
+       "  'rest',\n",
+       "  'for',\n",
+       "  '43',\n",
+       "  'seconds.'],\n",
+       " ['Donner',\n",
+       "  'can',\n",
+       "  'fly',\n",
+       "  '9',\n",
+       "  'km/s',\n",
+       "  'for',\n",
+       "  '5',\n",
+       "  'seconds,',\n",
+       "  'but',\n",
+       "  'then',\n",
+       "  'must',\n",
+       "  'rest',\n",
+       "  'for',\n",
+       "  '38',\n",
+       "  'seconds.'],\n",
+       " ['Dasher',\n",
+       "  'can',\n",
+       "  'fly',\n",
+       "  '10',\n",
+       "  'km/s',\n",
+       "  'for',\n",
+       "  '4',\n",
+       "  'seconds,',\n",
+       "  'but',\n",
+       "  'then',\n",
+       "  'must',\n",
+       "  'rest',\n",
+       "  'for',\n",
+       "  '37',\n",
+       "  'seconds.'],\n",
+       " ['Comet',\n",
+       "  'can',\n",
+       "  'fly',\n",
+       "  '3',\n",
+       "  'km/s',\n",
+       "  'for',\n",
+       "  '37',\n",
+       "  'seconds,',\n",
+       "  'but',\n",
+       "  'then',\n",
+       "  'must',\n",
+       "  'rest',\n",
+       "  'for',\n",
+       "  '76',\n",
+       "  'seconds.'],\n",
+       " ['Prancer',\n",
+       "  'can',\n",
+       "  'fly',\n",
+       "  '9',\n",
+       "  'km/s',\n",
+       "  'for',\n",
+       "  '12',\n",
+       "  'seconds,',\n",
+       "  'but',\n",
+       "  'then',\n",
+       "  'must',\n",
+       "  'rest',\n",
+       "  'for',\n",
+       "  '97',\n",
+       "  'seconds.'],\n",
+       " ['Dancer',\n",
+       "  'can',\n",
+       "  'fly',\n",
+       "  '37',\n",
+       "  'km/s',\n",
+       "  'for',\n",
+       "  '1',\n",
+       "  'seconds,',\n",
+       "  'but',\n",
+       "  'then',\n",
+       "  'must',\n",
+       "  'rest',\n",
+       "  'for',\n",
+       "  '36',\n",
+       "  'seconds.']]"
+      ]
+     },
+     "execution_count": 2,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "pi14 = [l.strip().split() for l in open('advent14.txt').readlines()]\n",
+    "pi14"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 6,
+   "metadata": {
+    "collapsed": false
+   },
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "[('Vixen', 8, 8, 53),\n",
+       " ('Blitzen', 13, 4, 49),\n",
+       " ('Rudolph', 20, 7, 132),\n",
+       " ('Cupid', 12, 4, 43),\n",
+       " ('Donner', 9, 5, 38),\n",
+       " ('Dasher', 10, 4, 37),\n",
+       " ('Comet', 3, 37, 76),\n",
+       " ('Prancer', 9, 12, 97),\n",
+       " ('Dancer', 37, 1, 36)]"
+      ]
+     },
+     "execution_count": 6,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "speeds = [(l[0], int(l[3]), int(l[6]), int(l[13])) for l in pi14]\n",
+    "speeds"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 4,
+   "metadata": {
+    "collapsed": true
+   },
+   "outputs": [],
+   "source": [
+    "import itertools"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 23,
+   "metadata": {
+    "collapsed": false,
+    "scrolled": true
+   },
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "128"
+      ]
+     },
+     "execution_count": 23,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "vixen = itertools.cycle(itertools.chain([speeds[0][1]] * speeds[0][1], [0] * speeds[0][3]))\n",
+    "v100 = itertools.islice(itertools.accumulate(vixen), 100)\n",
+    "list(v100)[-1]"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 13,
+   "metadata": {
+    "collapsed": true
+   },
+   "outputs": [],
+   "source": [
+    "def nth(iterable, n, default=None):\n",
+    "        \"Returns the nth item or a default value\"\n",
+    "        return next(itertools.islice(iterable, n, None), default)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 15,
+   "metadata": {
+    "collapsed": false
+   },
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "128"
+      ]
+     },
+     "execution_count": 15,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "vixen = itertools.accumulate(itertools.cycle(itertools.chain([speeds[0][1]] * speeds[0][1], [0] * speeds[0][3])))\n",
+    "nth(vixen, 100)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 17,
+   "metadata": {
+    "collapsed": false
+   },
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "1120"
+      ]
+     },
+     "execution_count": 17,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "comet = itertools.accumulate(itertools.cycle(itertools.chain([14] * 10, [0] * 127)))\n",
+    "nth(comet, 1000)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 18,
+   "metadata": {
+    "collapsed": false
+   },
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "1056"
+      ]
+     },
+     "execution_count": 18,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "dancer = itertools.accumulate(itertools.cycle(itertools.chain([16] * 11, [0] * 162)))\n",
+    "nth(dancer, 1000)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 55,
+   "metadata": {
+    "collapsed": true
+   },
+   "outputs": [],
+   "source": [
+    "def reindeer_distance(spec):\n",
+    "    return itertools.accumulate(itertools.cycle(itertools.chain([spec[1]] * spec[2], \n",
+    "                                                                    [0] * spec[3])))\n",
+    "\n",
+    "def reindeer_distance_at_time(spec, time):\n",
+    "    return nth(reindeer_distance(spec), time-1)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 57,
+   "metadata": {
+    "collapsed": false
+   },
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "[('Vixen', 2640),\n",
+       " ('Blitzen', 2496),\n",
+       " ('Rudolph', 2540),\n",
+       " ('Cupid', 2592),\n",
+       " ('Donner', 2655),\n",
+       " ('Dasher', 2460),\n",
+       " ('Comet', 2493),\n",
+       " ('Prancer', 2484),\n",
+       " ('Dancer', 2516)]"
+      ]
+     },
+     "execution_count": 57,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "[(r[0], reindeer_distance_at_time(r, 2503)) for r in speeds]"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 58,
+   "metadata": {
+    "collapsed": false
+   },
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "2655"
+      ]
+     },
+     "execution_count": 58,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "max(reindeer_distance_at_time(r, 2501) for r in speeds)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 59,
+   "metadata": {
+    "collapsed": false
+   },
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "[('Vixen', 1.0491803278688525),\n",
+       " ('Blitzen', 0.9811320754716981),\n",
+       " ('Rudolph', 1.0071942446043165),\n",
+       " ('Cupid', 1.0212765957446808),\n",
+       " ('Donner', 1.0465116279069768),\n",
+       " ('Dasher', 0.975609756097561),\n",
+       " ('Comet', 0.9823008849557522),\n",
+       " ('Prancer', 0.9908256880733946),\n",
+       " ('Dancer', 1.0)]"
+      ]
+     },
+     "execution_count": 59,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "[(s[0], (s[1] * s[2]) / (s[2] + s[3])) for s in speeds]"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 48,
+   "metadata": {
+    "collapsed": true
+   },
+   "outputs": [],
+   "source": [
+    "def rd2(spec, t):\n",
+    "    return spec[1] * spec[2] * (t // (spec[2] + spec[3])) + spec[1] * min(spec[2], t % (spec[2] + spec[3]))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 49,
+   "metadata": {
+    "collapsed": false
+   },
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "[('Vixen', 2640),\n",
+       " ('Blitzen', 2496),\n",
+       " ('Rudolph', 2540),\n",
+       " ('Cupid', 2592),\n",
+       " ('Donner', 2655),\n",
+       " ('Dasher', 2460),\n",
+       " ('Comet', 2493),\n",
+       " ('Prancer', 2484),\n",
+       " ('Dancer', 2516)]"
+      ]
+     },
+     "execution_count": 49,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "[(r[0], rd2(r, 2503)) for r in speeds]"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 73,
+   "metadata": {
+    "collapsed": false
+   },
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "[(8, 13, 20, 12, 9, 10, 3, 9, 37),\n",
+       " (16, 26, 40, 24, 18, 20, 6, 18, 37),\n",
+       " (24, 39, 60, 36, 27, 30, 9, 27, 37)]"
+      ]
+     },
+     "execution_count": 73,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "list(zip(* (list(itertools.islice(reindeer_distance(r), 3)) for r in speeds)))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 78,
+   "metadata": {
+    "collapsed": true
+   },
+   "outputs": [],
+   "source": [
+    "def score(positions):\n",
+    "    return [1 if p == max(positions) else 0 for p in positions]"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 81,
+   "metadata": {
+    "collapsed": false
+   },
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "[[0, 0, 0, 0, 0, 0, 0, 0, 1],\n",
+       " [0, 0, 1, 0, 0, 0, 0, 0, 0],\n",
+       " [0, 0, 1, 0, 0, 0, 0, 0, 0]]"
+      ]
+     },
+     "execution_count": 81,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "list(score(t) for t in zip(* (list(itertools.islice(reindeer_distance(r), 3)) for r in speeds)))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 79,
+   "metadata": {
+    "collapsed": false
+   },
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "[0, 0, 0, 0, 0, 0, 0, 0, 1]"
+      ]
+     },
+     "execution_count": 79,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "score((8, 13, 20, 12, 9, 10, 3, 9, 37))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 85,
+   "metadata": {
+    "collapsed": false
+   },
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "[(0, 0, 0),\n",
+       " (0, 0, 0),\n",
+       " (0, 1, 1),\n",
+       " (0, 0, 0),\n",
+       " (0, 0, 0),\n",
+       " (0, 0, 0),\n",
+       " (0, 0, 0),\n",
+       " (0, 0, 0),\n",
+       " (1, 0, 0)]"
+      ]
+     },
+     "execution_count": 85,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "list(zip(* list(score(t) \n",
+    "                          for t in zip(* (list(itertools.islice(reindeer_distance(r), 3)) \n",
+    "                                          for r in speeds)))))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 84,
+   "metadata": {
+    "collapsed": false
+   },
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "[0, 0, 2, 0, 0, 0, 0, 0, 1]"
+      ]
+     },
+     "execution_count": 84,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "list(sum(ps) \n",
+    "     for ps in zip(* list(score(t) \n",
+    "                          for t in zip(* (list(itertools.islice(reindeer_distance(r), 3)) \n",
+    "                                          for r in speeds)))))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 86,
+   "metadata": {
+    "collapsed": false
+   },
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "[1059, 5, 887, 13, 414, 0, 22, 153, 1]"
+      ]
+     },
+     "execution_count": 86,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "list(sum(ps) \n",
+    "     for ps in zip(* list(score(t) \n",
+    "                          for t in zip(* (list(itertools.islice(reindeer_distance(r), 2503)) \n",
+    "                                          for r in speeds)))))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 87,
+   "metadata": {
+    "collapsed": false
+   },
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "1059"
+      ]
+     },
+     "execution_count": 87,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "max(list(sum(ps) \n",
+    "     for ps in zip(* list(score(t) \n",
+    "                          for t in zip(* (list(itertools.islice(reindeer_distance(r), 2503)) \n",
+    "                                          for r in speeds))))))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "collapsed": true
+   },
+   "outputs": [],
+   "source": []
+  }
+ ],
+ "metadata": {
+  "kernelspec": {
+   "display_name": "Python 3",
+   "language": "python",
+   "name": "python3"
+  },
+  "language_info": {
+   "codemirror_mode": {
+    "name": "ipython",
+    "version": 3
+   },
+   "file_extension": ".py",
+   "mimetype": "text/x-python",
+   "name": "python",
+   "nbconvert_exporter": "python",
+   "pygments_lexer": "ipython3",
+   "version": "3.4.3"
+  }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 0
+}