X-Git-Url: https://git.njae.me.uk/?a=blobdiff_plain;f=09-resolving-the-bill%2Fresolving-the-bill-solution.ipynb;h=dc846ae48a37dd38c6d0f608bde46ee34550e1d0;hb=7feed95175973490721236795cc7895e252965e2;hp=3d9d63f1059b62509f1f2f78c3fc30745edc1964;hpb=c78bf218fb6d75d478fef09b8067a23332d4de45;p=ou-summer-of-code-2017.git diff --git a/09-resolving-the-bill/resolving-the-bill-solution.ipynb b/09-resolving-the-bill/resolving-the-bill-solution.ipynb index 3d9d63f..dc846ae 100644 --- a/09-resolving-the-bill/resolving-the-bill-solution.ipynb +++ b/09-resolving-the-bill/resolving-the-bill-solution.ipynb @@ -78,7 +78,19 @@ }, { "cell_type": "code", - "execution_count": 1, + "execution_count": 2, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "import sys\n", + "sys.setrecursionlimit(10**6)" + ] + }, + { + "cell_type": "code", + "execution_count": 3, "metadata": {}, "outputs": [ { @@ -87,7 +99,7 @@ "148" ] }, - "execution_count": 1, + "execution_count": 3, "metadata": {}, "output_type": "execute_result" } @@ -100,7 +112,7 @@ }, { "cell_type": "code", - "execution_count": 2, + "execution_count": 4, "metadata": { "collapsed": true }, @@ -114,7 +126,7 @@ }, { "cell_type": "code", - "execution_count": 3, + "execution_count": 5, "metadata": { "collapsed": true }, @@ -134,7 +146,7 @@ }, { "cell_type": "code", - "execution_count": 4, + "execution_count": 6, "metadata": { "collapsed": true }, @@ -158,7 +170,7 @@ }, { "cell_type": "code", - "execution_count": 5, + "execution_count": 7, "metadata": { "collapsed": true }, @@ -178,7 +190,24 @@ }, { "cell_type": "code", - "execution_count": 6, + "execution_count": 8, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "def is_subseq_greedy(s1, s2):\n", + " i = j = 0\n", + " while i < len(s1) and j < len(s2):\n", + " if s1[i] == s2[j]:\n", + " i += 1\n", + " j += 1\n", + " return i == len(s1)" + ] + }, + { + "cell_type": "code", + "execution_count": 9, "metadata": { "collapsed": true }, @@ -233,7 +262,7 @@ }, { "cell_type": "code", - "execution_count": 35, + "execution_count": 10, "metadata": { "collapsed": true }, @@ -284,7 +313,7 @@ }, { "cell_type": "code", - "execution_count": 7, + "execution_count": 11, "metadata": {}, "outputs": [ { @@ -293,7 +322,7 @@ "22" ] }, - "execution_count": 7, + "execution_count": 11, "metadata": {}, "output_type": "execute_result" } @@ -306,7 +335,7 @@ }, { "cell_type": "code", - "execution_count": 36, + "execution_count": 12, "metadata": {}, "outputs": [ { @@ -315,7 +344,7 @@ "22" ] }, - "execution_count": 36, + "execution_count": 12, "metadata": {}, "output_type": "execute_result" } @@ -328,14 +357,36 @@ }, { "cell_type": "code", - "execution_count": 8, + "execution_count": 13, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "22" + ] + }, + "execution_count": 13, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "sum(1 for s in bills\n", + " if s != 0\n", + " if is_subseq_greedy(bills[0], bills[s]))" + ] + }, + { + "cell_type": "code", + "execution_count": 30, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "1 loop, best of 3: 8.02 s per loop\n" + "100 loops, best of 3: 13.1 ms per loop\n" ] } ], @@ -343,19 +394,19 @@ "%%timeit\n", "sum(1 for s in bills\n", " if s != 0\n", - " if is_subseq(bills[0], bills[s]))" + " if is_subseq_greedy(bills[0], bills[s]))" ] }, { "cell_type": "code", - "execution_count": 37, + "execution_count": 14, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "1 loop, best of 3: 3.04 s per loop\n" + "1 loop, best of 3: 7.88 s per loop\n" ] } ], @@ -363,12 +414,12 @@ "%%timeit\n", "sum(1 for s in bills\n", " if s != 0\n", - " if is_subseq_rows(bills[0], bills[s]))" + " if is_subseq(bills[0], bills[s]))" ] }, { "cell_type": "code", - "execution_count": 9, + "execution_count": 15, "metadata": { "scrolled": true }, @@ -400,7 +451,7 @@ " 146]" ] }, - "execution_count": 9, + "execution_count": 15, "metadata": {}, "output_type": "execute_result" } @@ -413,15 +464,15 @@ }, { "cell_type": "code", - "execution_count": 65, + "execution_count": 16, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "CPU times: user 168 ms, sys: 0 ns, total: 168 ms\n", - "Wall time: 166 ms\n" + "CPU times: user 148 ms, sys: 4 ms, total: 152 ms\n", + "Wall time: 150 ms\n" ] }, { @@ -430,7 +481,7 @@ "(True, False)" ] }, - "execution_count": 65, + "execution_count": 16, "metadata": {}, "output_type": "execute_result" } @@ -441,7 +492,7 @@ }, { "cell_type": "code", - "execution_count": 73, + "execution_count": 17, "metadata": { "collapsed": true }, @@ -452,7 +503,7 @@ }, { "cell_type": "code", - "execution_count": 39, + "execution_count": 18, "metadata": {}, "outputs": [ { @@ -679,7 +730,7 @@ }, { "cell_type": "code", - "execution_count": 47, + "execution_count": 31, "metadata": { "collapsed": true }, @@ -690,20 +741,24 @@ " return s2 == s3\n", " elif not s2:\n", " return s1 == s3\n", + " elif len(s1) + len(s2) != len(s3):\n", + " return False\n", " else:\n", - " if s1[-1] == s2[-1] and s1[-1] == s3[-1]:\n", - " return is_interleave_recursive(s1[:-1], s2, s3[:-1]) or is_interleave(s1, s2[:-1], s3[:-1])\n", + " if s1[-1] == s3[-1] and s2[-1] == s3[-1]:\n", + " return (is_interleave_recursive(s1[:-1], s2, s3[:-1]) \n", + " or \n", + " is_interleave_recursive(s1, s2[:-1], s3[:-1]) )\n", " elif s1[-1] == s3[-1]:\n", " return is_interleave_recursive(s1[:-1], s2, s3[:-1])\n", " elif s2[-1] == s3[-1]:\n", - " return is_interleave(s1, s2[:-1], s3[:-1])\n", + " return is_interleave_recursive(s1, s2[:-1], s3[:-1])\n", " else:\n", " return False" ] }, { "cell_type": "code", - "execution_count": 40, + "execution_count": 20, "metadata": { "collapsed": true }, @@ -779,7 +834,7 @@ }, { "cell_type": "code", - "execution_count": 40, + "execution_count": 21, "metadata": { "collapsed": true }, @@ -852,7 +907,7 @@ }, { "cell_type": "code", - "execution_count": 46, + "execution_count": 22, "metadata": { "collapsed": true }, @@ -932,7 +987,7 @@ }, { "cell_type": "code", - "execution_count": 41, + "execution_count": 23, "metadata": { "collapsed": true }, @@ -956,7 +1011,7 @@ }, { "cell_type": "code", - "execution_count": 44, + "execution_count": 24, "metadata": {}, "outputs": [ { @@ -965,7 +1020,7 @@ "[30]" ] }, - "execution_count": 44, + "execution_count": 24, "metadata": {}, "output_type": "execute_result" } @@ -977,7 +1032,7 @@ }, { "cell_type": "code", - "execution_count": 41, + "execution_count": 25, "metadata": {}, "outputs": [ { @@ -986,7 +1041,7 @@ "[30]" ] }, - "execution_count": 41, + "execution_count": 25, "metadata": {}, "output_type": "execute_result" } @@ -998,7 +1053,7 @@ }, { "cell_type": "code", - "execution_count": 48, + "execution_count": 26, "metadata": {}, "outputs": [ { @@ -1007,7 +1062,7 @@ "[30]" ] }, - "execution_count": 48, + "execution_count": 26, "metadata": {}, "output_type": "execute_result" } @@ -1019,7 +1074,29 @@ }, { "cell_type": "code", - "execution_count": 45, + "execution_count": 27, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[30]" + ] + }, + "execution_count": 27, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "[s for s in bills\n", + " if is_subseq(bills[0], bills[s])\n", + " if is_subseq(bills[1], bills[s])]" + ] + }, + { + "cell_type": "code", + "execution_count": 28, "metadata": {}, "outputs": [ { @@ -1236,7 +1313,7 @@ "True" ] }, - "execution_count": 45, + "execution_count": 28, "metadata": {}, "output_type": "execute_result" } @@ -1250,7 +1327,7 @@ }, { "cell_type": "code", - "execution_count": 48, + "execution_count": 32, "metadata": {}, "outputs": [ { @@ -1259,7 +1336,7 @@ "[30]" ] }, - "execution_count": 48, + "execution_count": 32, "metadata": {}, "output_type": "execute_result" } @@ -1271,14 +1348,14 @@ }, { "cell_type": "code", - "execution_count": 70, + "execution_count": 33, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "1 loop, best of 3: 2.68 s per loop\n" + "1 loop, best of 3: 3.12 s per loop\n" ] } ], @@ -1290,14 +1367,14 @@ }, { "cell_type": "code", - "execution_count": 42, + "execution_count": 34, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "1 loop, best of 3: 1.06 s per loop\n" + "1 loop, best of 3: 971 ms per loop\n" ] } ], @@ -1309,7 +1386,7 @@ }, { "cell_type": "code", - "execution_count": 49, + "execution_count": 35, "metadata": {}, "outputs": [ { @@ -1328,14 +1405,14 @@ }, { "cell_type": "code", - "execution_count": 71, + "execution_count": 36, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "1 loop, best of 3: 660 ms per loop\n" + "1000 loops, best of 3: 510 µs per loop\n" ] } ], @@ -1362,7 +1439,7 @@ }, { "cell_type": "code", - "execution_count": 1, + "execution_count": 37, "metadata": {}, "outputs": [ { @@ -1371,7 +1448,7 @@ "(4.223305555555555, 4, 13, 23.899999999999636)" ] }, - "execution_count": 1, + "execution_count": 37, "metadata": {}, "output_type": "execute_result" } @@ -1387,7 +1464,7 @@ }, { "cell_type": "code", - "execution_count": 2, + "execution_count": 38, "metadata": {}, "outputs": [ { @@ -1396,7 +1473,7 @@ "(11.13438888888889, 11, 8, 3.8000000000029104)" ] }, - "execution_count": 2, + "execution_count": 38, "metadata": {}, "output_type": "execute_result" } @@ -1412,7 +1489,7 @@ }, { "cell_type": "code", - "execution_count": 3, + "execution_count": 39, "metadata": {}, "outputs": [ { @@ -1421,7 +1498,7 @@ "(15.36486111111111, 15, 21, 53.5)" ] }, - "execution_count": 3, + "execution_count": 39, "metadata": {}, "output_type": "execute_result" } @@ -1435,6 +1512,194 @@ ")" ] }, + { + "cell_type": "markdown", + "metadata": { + "collapsed": true + }, + "source": [ + "# Explanations" + ] + }, + { + "cell_type": "code", + "execution_count": 40, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "starget = 'acba'\n", + "swrong = 'cdabcaca'\n", + "sinterleave = 'abcacbba'\n", + "ssubseq = 'aaccabab'" + ] + }, + { + "cell_type": "code", + "execution_count": 41, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "def show_subseq_md_table(short, long, table):\n", + " header = '| |' + '|'.join('{}
{}'.format('
'.join(str(long[:i])), i) for i in range(len(long) + 1)) + '|'\n", + " separator = '|:---:' * (len(long) + 2) + '|'\n", + " rows = []\n", + " columns = sorted(set(k[1] for k in table))\n", + " for r in range(len(short) + 1):\n", + " row = '|{}
{}|'.format(r, short[:r])\n", + " row += '|'.join('T' if table[r, c] else '.' for c in columns)\n", + " row += '|'\n", + " rows += [row]\n", + " return '\\n'.join([header] + [separator] + rows)\n", + "# return '\\n'.join(\n", + "# ' '.join('T' if table[i, j] else '.' for j in sorted(set([k[1] for k in table])))\n", + "# for i in sorted(set([k[0] for k in table]))) " + ] + }, + { + "cell_type": "code", + "execution_count": 42, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + ". . . . . . . . .\n", + ". a a c c a b a b\n", + ". . . c c a b a b\n", + ". . . . . . b a b\n", + ". . . . . . . a b\n", + "AcCaBAb\n" + ] + } + ], + "source": [ + "v, bp, t = is_subseq(starget, ssubseq, return_backpointers=True, return_table=True)\n", + "print(show_annotated_table(t, bp))\n", + "print(show_backtrace_s(bp))" + ] + }, + { + "cell_type": "code", + "execution_count": 43, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "T T T T T T T T T\n", + ". T T T T T T T T\n", + ". . . T T T T T T\n", + ". . . . . . T T T\n", + ". . . . . . . T T\n" + ] + } + ], + "source": [ + "print(show_table(t))" + ] + }, + { + "cell_type": "code", + "execution_count": 44, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "| |
0|a
1|a
a
2|a
a
c
3|a
a
c
c
4|a
a
c
c
a
5|a
a
c
c
a
b
6|a
a
c
c
a
b
a
7|a
a
c
c
a
b
a
b
8|\n", + "|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:|\n", + "|0
|T|T|T|T|T|T|T|T|T|\n", + "|1
a|.|T|T|T|T|T|T|T|T|\n", + "|2
ac|.|.|.|T|T|T|T|T|T|\n", + "|3
acb|.|.|.|.|.|.|T|T|T|\n", + "|4
acba|.|.|.|.|.|.|.|T|T|\n" + ] + } + ], + "source": [ + "print(show_subseq_md_table(starget, ssubseq, t))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "| |
0|a
1|a
a
2|a
a
c
3|a
a
c
c
4|a
a
c
c
a
5|a
a
c
c
a
b
6|a
a
c
c
a
b
a
7|a
a
c
c
a
b
a
b
8|\n", + "|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:|\n", + "|0
|T|T|T|T|T|T|T|T|T|\n", + "|1
a|.|T|T|T|T|T|T|T|T|\n", + "|2
ac|.|.|.|T|T|T|T|T|T|\n", + "|3
acb|.|.|.|.|.|.|T|T|T|\n", + "|4
acba|.|.|.|.|.|.|.|T|T|" + ] + }, + { + "cell_type": "code", + "execution_count": 45, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + ". . . . . . . . .\n", + ". . . a b c a c a\n", + ". . . . . c a c a\n", + ". . . . . . . . .\n", + ". . . . . . . . .\n", + "ACa\n" + ] + } + ], + "source": [ + "v, bp, t = is_subseq(starget, swrong, return_backpointers=True, return_table=True)\n", + "print(show_annotated_table(t, bp))\n", + "print(show_backtrace_s(bp))" + ] + }, + { + "cell_type": "code", + "execution_count": 46, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "| |
0|c
1|c
d
2|c
d
a
3|c
d
a
b
4|c
d
a
b
c
5|c
d
a
b
c
a
6|c
d
a
b
c
a
c
7|c
d
a
b
c
a
c
a
8|\n", + "|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:|\n", + "|0
|T|T|T|T|T|T|T|T|T|\n", + "|1
a|.|.|.|T|T|T|T|T|T|\n", + "|2
ac|.|.|.|.|.|T|T|T|T|\n", + "|3
acb|.|.|.|.|.|.|.|.|.|\n", + "|4
acba|.|.|.|.|.|.|.|.|.|\n" + ] + } + ], + "source": [ + "print(show_subseq_md_table(starget, swrong, t))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "| |
0|c
1|c
d
2|c
d
a
3|c
d
a
b
4|c
d
a
b
c
5|c
d
a
b
c
a
6|c
d
a
b
c
a
c
7|c
d
a
b
c
a
c
a
8|\n", + "|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:|\n", + "|0
|T|T|T|T|T|T|T|T|T|\n", + "|1
a|.|.|.|T|T|T|T|T|T|\n", + "|2
ac|.|.|.|.|.|T|T|T|T|\n", + "|3
acb|.|.|.|.|.|.|.|.|.|\n", + "|4
acba|.|.|.|.|.|.|.|.|.|" + ] + }, { "cell_type": "code", "execution_count": null,