--- /dev/null
+{
+ "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
+}