├── .gitignore ├── resource ├── day 96 - eagle.jpg ├── day 96 - valinka.jpg └── day 96 - winter.jpg ├── README.md ├── day 05 - eratosthenes sieve.ipynb ├── day 04 - counting 1-bits.ipynb ├── day 11 - McCarthy 91.ipynb ├── day 01 - hanoi tower.ipynb ├── day 27 - spiral matrix.ipynb ├── day 33 - reservoir sampling.ipynb ├── day 38 - burrows-wheeler.ipynb ├── day 16 - no-condition swap.ipynb ├── day 37 - longest common subsequence.ipynb ├── day 41 - union-find.ipynb ├── day 09 - monte carlo - pi.ipynb ├── day 25 - conjugate gradients.ipynb ├── day 06 - postfix notation.ipynb ├── day 47 - factoradic.ipynb ├── day 43 - shuffle.ipynb ├── day 20 - linearithmic multiplication.ipynb ├── day 08 - binary search.ipynb ├── day 22 - determinant.ipynb ├── day 19 - counting inversions.ipynb ├── day 39 - 4sum.ipynb ├── day 29 - string searching.ipynb ├── day 07 - binary addition FSA.ipynb ├── day 02 - matrix chain multiplication.ipynb ├── day 14 - huffman codes.ipynb ├── day 35 - median.ipynb ├── day 03 - next permutation.ipynb ├── day 12 - roots of polynomial.ipynb ├── day 13 - extended euclidean algorithm.ipynb ├── day 57 - quicksort.ipynb ├── day 26 - karger's mincut.ipynb ├── day 74 - google interview question.ipynb ├── day 23 - sudoku.ipynb ├── day 70 - deadlock.ipynb ├── day 40 - counting ones.ipynb ├── day 36 - bulls and cows.ipynb ├── day 51 - rabin-miller.ipynb ├── day 44 - gradient approximation.ipynb ├── bonus - fast convex hull.ipynb ├── day 91 - variations.ipynb ├── day 63 - zig-zag.ipynb ├── day 42 - hamming codes.ipynb ├── day 30 - strassen multiplication.ipynb ├── day 34 - aho-corasick.ipynb ├── day 60 - bloom filter.ipynb ├── day 24 - closest pair.ipynb ├── day 58 - integer exponentation.ipynb ├── day 62 - linked-list cycle.ipynb ├── day 68 - gale-shapley.ipynb ├── day 15 - breaking OTP.ipynb ├── day 31 - timeit.ipynb ├── day 59 - colored tiling.ipynb ├── day I00 - segmented eratosthenes sieve.ipynb ├── day 56 - lzw.ipynb └── day 78 - horn-satifiability.ipynb /.gitignore: -------------------------------------------------------------------------------- 1 | .ipynb_checkpoints 2 | -------------------------------------------------------------------------------- /resource/day 96 - eagle.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ashishpatel26/100-Days-of-Algorithms/master/resource/day 96 - eagle.jpg -------------------------------------------------------------------------------- /resource/day 96 - valinka.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ashishpatel26/100-Days-of-Algorithms/master/resource/day 96 - valinka.jpg -------------------------------------------------------------------------------- /resource/day 96 - winter.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ashishpatel26/100-Days-of-Algorithms/master/resource/day 96 - winter.jpg -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ### 100 days of algorithms 2 | 3 | This repository contains notebooks with live code to accompany [100 days of algorithms](https://medium.com/100-days-of-algorithms) challenge. 4 | 5 | I set the challenge for myself to implement algorithm by algorithm, day by day, until the number reaches **100**. 6 | 7 | If you are interested, here's the [intro to the series](https://medium.com/100-days-of-algorithms/100-days-of-algorithms-challenge-41996f7e1ec8) and [all the articles](https://medium.com/100-days-of-algorithms/latest) sorted by date from the latest. 8 | 9 | The challenge was quite fun and rough, as well. Do not expect the implementations to be the best, nor fastest, nor nicest, nor bug-free. Do expect to see code written in haste. A code that contains the same amount of enthusiasm and love to algorithms as many it contains bugs. 10 | 11 | Feel free to (re)use my code in any way you wish, but bare in mind that the source code is provided "as-is". It is on your own risk and you are solely responsible for whatever happens then. 12 | 13 | #### local machine 14 | 15 | * download and install the latest version of [Anaconda](https://www.continuum.io/downloads) distribution 16 | * clone the repo: `git clone https://github.com/coells/100days.git` 17 | * open terminal and run Jupyter notebook: `jupyter notebook` 18 | * open [localhost:8888](http://localhost:8888/tree) in your browser 19 | 20 | #### notes 21 | 22 | * the codebase was developed using `Python 3.6` and `Anaconda 4.3.1` 23 | * notebooks containing [Bokeh](http://bokeh.pydata.org/en/latest/) plots are not directly supported by Github; you better clone the repo a run notebooks locally 24 | 25 | #### alternate repository 26 | 27 | [Microsoft Azure Notebooks](https://notebooks.azure.com/coells/libraries/100days) with `Python 3.5` support 28 | -------------------------------------------------------------------------------- /day 05 - eratosthenes sieve.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": 1, 6 | "metadata": { 7 | "collapsed": true 8 | }, 9 | "outputs": [], 10 | "source": [ 11 | "import numpy as np" 12 | ] 13 | }, 14 | { 15 | "cell_type": "markdown", 16 | "metadata": {}, 17 | "source": [ 18 | "## algorithm" 19 | ] 20 | }, 21 | { 22 | "cell_type": "code", 23 | "execution_count": 2, 24 | "metadata": { 25 | "collapsed": false 26 | }, 27 | "outputs": [], 28 | "source": [ 29 | "def eratosthenes(n):\n", 30 | " n = (n + 1) >> 1\n", 31 | " p = np.ones(n, dtype=np.int8)\n", 32 | " i, j = 1, 3\n", 33 | " \n", 34 | " while i < n:\n", 35 | " if p[i]:\n", 36 | " p[j * j >> 1::j] = 0\n", 37 | " i, j = i + 1, j + 2\n", 38 | "\n", 39 | " return p.sum()" 40 | ] 41 | }, 42 | { 43 | "cell_type": "markdown", 44 | "metadata": {}, 45 | "source": [ 46 | "## run" 47 | ] 48 | }, 49 | { 50 | "cell_type": "code", 51 | "execution_count": 3, 52 | "metadata": { 53 | "collapsed": false 54 | }, 55 | "outputs": [ 56 | { 57 | "name": "stdout", 58 | "output_type": "stream", 59 | "text": [ 60 | "10 4\n", 61 | "100 25\n", 62 | "1000 168\n", 63 | "10000 1229\n", 64 | "100000 9592\n", 65 | "1000000 78498\n", 66 | "10000000 664579\n" 67 | ] 68 | } 69 | ], 70 | "source": [ 71 | "for j in range(1, 8):\n", 72 | " print(10 ** j, eratosthenes(10 ** j))" 73 | ] 74 | }, 75 | { 76 | "cell_type": "code", 77 | "execution_count": null, 78 | "metadata": { 79 | "collapsed": true 80 | }, 81 | "outputs": [], 82 | "source": [] 83 | } 84 | ], 85 | "metadata": { 86 | "kernelspec": { 87 | "display_name": "Python 3", 88 | "language": "python", 89 | "name": "python3" 90 | }, 91 | "language_info": { 92 | "codemirror_mode": { 93 | "name": "ipython", 94 | "version": 3 95 | }, 96 | "file_extension": ".py", 97 | "mimetype": "text/x-python", 98 | "name": "python", 99 | "nbconvert_exporter": "python", 100 | "pygments_lexer": "ipython3", 101 | "version": "3.6.0" 102 | } 103 | }, 104 | "nbformat": 4, 105 | "nbformat_minor": 2 106 | } 107 | -------------------------------------------------------------------------------- /day 04 - counting 1-bits.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "## algorithm" 8 | ] 9 | }, 10 | { 11 | "cell_type": "code", 12 | "execution_count": 1, 13 | "metadata": { 14 | "collapsed": false 15 | }, 16 | "outputs": [], 17 | "source": [ 18 | "def count_of_1bits(value):\n", 19 | " n = 0\n", 20 | " while value:\n", 21 | " value &= value - 1\n", 22 | " n += 1\n", 23 | " return n" 24 | ] 25 | }, 26 | { 27 | "cell_type": "markdown", 28 | "metadata": {}, 29 | "source": [ 30 | "## run" 31 | ] 32 | }, 33 | { 34 | "cell_type": "code", 35 | "execution_count": 2, 36 | "metadata": { 37 | "collapsed": false 38 | }, 39 | "outputs": [ 40 | { 41 | "data": { 42 | "text/plain": [ 43 | "0" 44 | ] 45 | }, 46 | "execution_count": 2, 47 | "metadata": {}, 48 | "output_type": "execute_result" 49 | } 50 | ], 51 | "source": [ 52 | "count_of_1bits(0)" 53 | ] 54 | }, 55 | { 56 | "cell_type": "code", 57 | "execution_count": 3, 58 | "metadata": { 59 | "collapsed": false 60 | }, 61 | "outputs": [ 62 | { 63 | "data": { 64 | "text/plain": [ 65 | "1" 66 | ] 67 | }, 68 | "execution_count": 3, 69 | "metadata": {}, 70 | "output_type": "execute_result" 71 | } 72 | ], 73 | "source": [ 74 | "count_of_1bits(1)" 75 | ] 76 | }, 77 | { 78 | "cell_type": "code", 79 | "execution_count": 4, 80 | "metadata": { 81 | "collapsed": false 82 | }, 83 | "outputs": [ 84 | { 85 | "data": { 86 | "text/plain": [ 87 | "4" 88 | ] 89 | }, 90 | "execution_count": 4, 91 | "metadata": {}, 92 | "output_type": "execute_result" 93 | } 94 | ], 95 | "source": [ 96 | "count_of_1bits(0b11001100)" 97 | ] 98 | }, 99 | { 100 | "cell_type": "code", 101 | "execution_count": null, 102 | "metadata": { 103 | "collapsed": true 104 | }, 105 | "outputs": [], 106 | "source": [] 107 | } 108 | ], 109 | "metadata": { 110 | "kernelspec": { 111 | "display_name": "Python 3", 112 | "language": "python", 113 | "name": "python3" 114 | }, 115 | "language_info": { 116 | "codemirror_mode": { 117 | "name": "ipython", 118 | "version": 3 119 | }, 120 | "file_extension": ".py", 121 | "mimetype": "text/x-python", 122 | "name": "python", 123 | "nbconvert_exporter": "python", 124 | "pygments_lexer": "ipython3", 125 | "version": "3.6.0" 126 | } 127 | }, 128 | "nbformat": 4, 129 | "nbformat_minor": 2 130 | } 131 | -------------------------------------------------------------------------------- /day 11 - McCarthy 91.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "## algorithm" 8 | ] 9 | }, 10 | { 11 | "cell_type": "code", 12 | "execution_count": 1, 13 | "metadata": { 14 | "collapsed": false 15 | }, 16 | "outputs": [], 17 | "source": [ 18 | "def mccarthy91(n):\n", 19 | " k = 1\n", 20 | " while k:\n", 21 | " if n > 100:\n", 22 | " n -= 10\n", 23 | " k -= 1\n", 24 | " else:\n", 25 | " n += 11\n", 26 | " k += 1\n", 27 | " return n" 28 | ] 29 | }, 30 | { 31 | "cell_type": "markdown", 32 | "metadata": {}, 33 | "source": [ 34 | "don't forget to increase stack limit for recursive version" 35 | ] 36 | }, 37 | { 38 | "cell_type": "code", 39 | "execution_count": 2, 40 | "metadata": { 41 | "collapsed": true 42 | }, 43 | "outputs": [], 44 | "source": [ 45 | "def mccarthy91_rec(n):\n", 46 | " if n > 100:\n", 47 | " return n - 10\n", 48 | " else:\n", 49 | " return mccarthy91_rec(mccarthy91_rec(n + 11))" 50 | ] 51 | }, 52 | { 53 | "cell_type": "markdown", 54 | "metadata": {}, 55 | "source": [ 56 | "## run" 57 | ] 58 | }, 59 | { 60 | "cell_type": "code", 61 | "execution_count": 3, 62 | "metadata": { 63 | "collapsed": false 64 | }, 65 | "outputs": [ 66 | { 67 | "name": "stdout", 68 | "output_type": "stream", 69 | "text": [ 70 | "70 91\n", 71 | "71 91\n", 72 | "80 91\n", 73 | "81 91\n", 74 | "90 91\n", 75 | "91 91\n", 76 | "100 91\n", 77 | "101 91\n", 78 | "110 100\n", 79 | "111 101\n", 80 | "120 110\n", 81 | "121 111\n" 82 | ] 83 | } 84 | ], 85 | "source": [ 86 | "for i in range(70, 130, 10):\n", 87 | " print(i, mccarthy91(i))\n", 88 | " print(i + 1, mccarthy91(i + 1)) " 89 | ] 90 | }, 91 | { 92 | "cell_type": "code", 93 | "execution_count": null, 94 | "metadata": { 95 | "collapsed": true 96 | }, 97 | "outputs": [], 98 | "source": [] 99 | } 100 | ], 101 | "metadata": { 102 | "kernelspec": { 103 | "display_name": "Python 3", 104 | "language": "python", 105 | "name": "python3" 106 | }, 107 | "language_info": { 108 | "codemirror_mode": { 109 | "name": "ipython", 110 | "version": 3 111 | }, 112 | "file_extension": ".py", 113 | "mimetype": "text/x-python", 114 | "name": "python", 115 | "nbconvert_exporter": "python", 116 | "pygments_lexer": "ipython3", 117 | "version": "3.6.0" 118 | } 119 | }, 120 | "nbformat": 4, 121 | "nbformat_minor": 2 122 | } 123 | -------------------------------------------------------------------------------- /day 01 - hanoi tower.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "## algorithm" 8 | ] 9 | }, 10 | { 11 | "cell_type": "code", 12 | "execution_count": 1, 13 | "metadata": { 14 | "collapsed": false 15 | }, 16 | "outputs": [], 17 | "source": [ 18 | "def hanoi(height, left='left', right='right', middle='middle'):\n", 19 | " if height:\n", 20 | " hanoi(height - 1, left, middle, right)\n", 21 | " print(left, '=>', right)\n", 22 | " hanoi(height - 1, middle, right, left)" 23 | ] 24 | }, 25 | { 26 | "cell_type": "markdown", 27 | "metadata": {}, 28 | "source": [ 29 | "## run" 30 | ] 31 | }, 32 | { 33 | "cell_type": "code", 34 | "execution_count": 2, 35 | "metadata": { 36 | "collapsed": false 37 | }, 38 | "outputs": [ 39 | { 40 | "name": "stdout", 41 | "output_type": "stream", 42 | "text": [ 43 | "left => right\n" 44 | ] 45 | } 46 | ], 47 | "source": [ 48 | "hanoi(1)" 49 | ] 50 | }, 51 | { 52 | "cell_type": "code", 53 | "execution_count": 3, 54 | "metadata": { 55 | "collapsed": false 56 | }, 57 | "outputs": [ 58 | { 59 | "name": "stdout", 60 | "output_type": "stream", 61 | "text": [ 62 | "left => middle\n", 63 | "left => right\n", 64 | "middle => right\n" 65 | ] 66 | } 67 | ], 68 | "source": [ 69 | "hanoi(2)" 70 | ] 71 | }, 72 | { 73 | "cell_type": "code", 74 | "execution_count": 4, 75 | "metadata": { 76 | "collapsed": false 77 | }, 78 | "outputs": [ 79 | { 80 | "name": "stdout", 81 | "output_type": "stream", 82 | "text": [ 83 | "left => right\n", 84 | "left => middle\n", 85 | "right => middle\n", 86 | "left => right\n", 87 | "middle => left\n", 88 | "middle => right\n", 89 | "left => right\n" 90 | ] 91 | } 92 | ], 93 | "source": [ 94 | "hanoi(3)" 95 | ] 96 | }, 97 | { 98 | "cell_type": "code", 99 | "execution_count": null, 100 | "metadata": { 101 | "collapsed": true 102 | }, 103 | "outputs": [], 104 | "source": [] 105 | } 106 | ], 107 | "metadata": { 108 | "kernelspec": { 109 | "display_name": "Python 3", 110 | "language": "python", 111 | "name": "python3" 112 | }, 113 | "language_info": { 114 | "codemirror_mode": { 115 | "name": "ipython", 116 | "version": 3 117 | }, 118 | "file_extension": ".py", 119 | "mimetype": "text/x-python", 120 | "name": "python", 121 | "nbconvert_exporter": "python", 122 | "pygments_lexer": "ipython3", 123 | "version": "3.6.0" 124 | } 125 | }, 126 | "nbformat": 4, 127 | "nbformat_minor": 2 128 | } 129 | -------------------------------------------------------------------------------- /day 27 - spiral matrix.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": 1, 6 | "metadata": { 7 | "collapsed": true 8 | }, 9 | "outputs": [], 10 | "source": [ 11 | "from itertools import count" 12 | ] 13 | }, 14 | { 15 | "cell_type": "markdown", 16 | "metadata": {}, 17 | "source": [ 18 | "## algorithm" 19 | ] 20 | }, 21 | { 22 | "cell_type": "code", 23 | "execution_count": 2, 24 | "metadata": { 25 | "collapsed": false 26 | }, 27 | "outputs": [], 28 | "source": [ 29 | "def spiral(n):\n", 30 | " matrix = [range(i * n + n)[-n:] for i in range(n)]\n", 31 | " X, C, R = {}, count(1), matrix\n", 32 | "\n", 33 | " while R:\n", 34 | " X.update(zip(R[0], C))\n", 35 | " R = list(zip(*[i[::-1] for i in R[1:]]))\n", 36 | "\n", 37 | " return [[X[j] for j in i] for i in matrix]" 38 | ] 39 | }, 40 | { 41 | "cell_type": "markdown", 42 | "metadata": {}, 43 | "source": [ 44 | "## run" 45 | ] 46 | }, 47 | { 48 | "cell_type": "code", 49 | "execution_count": 3, 50 | "metadata": { 51 | "collapsed": false 52 | }, 53 | "outputs": [ 54 | { 55 | "name": "stdout", 56 | "output_type": "stream", 57 | "text": [ 58 | "1\t2\t3\n", 59 | "8\t9\t4\n", 60 | "7\t6\t5\n" 61 | ] 62 | } 63 | ], 64 | "source": [ 65 | "for i in spiral(3):\n", 66 | " print('\\t'.join(map(str, i)))" 67 | ] 68 | }, 69 | { 70 | "cell_type": "code", 71 | "execution_count": 4, 72 | "metadata": { 73 | "collapsed": false 74 | }, 75 | "outputs": [ 76 | { 77 | "name": "stdout", 78 | "output_type": "stream", 79 | "text": [ 80 | "1\t2\t3\t4\t5\n", 81 | "16\t17\t18\t19\t6\n", 82 | "15\t24\t25\t20\t7\n", 83 | "14\t23\t22\t21\t8\n", 84 | "13\t12\t11\t10\t9\n" 85 | ] 86 | } 87 | ], 88 | "source": [ 89 | "for i in spiral(5):\n", 90 | " print('\\t'.join(map(str, i)))" 91 | ] 92 | }, 93 | { 94 | "cell_type": "code", 95 | "execution_count": null, 96 | "metadata": { 97 | "collapsed": true 98 | }, 99 | "outputs": [], 100 | "source": [] 101 | } 102 | ], 103 | "metadata": { 104 | "kernelspec": { 105 | "display_name": "Python 3", 106 | "language": "python", 107 | "name": "python3" 108 | }, 109 | "language_info": { 110 | "codemirror_mode": { 111 | "name": "ipython", 112 | "version": 3 113 | }, 114 | "file_extension": ".py", 115 | "mimetype": "text/x-python", 116 | "name": "python", 117 | "nbconvert_exporter": "python", 118 | "pygments_lexer": "ipython3", 119 | "version": "3.6.0" 120 | } 121 | }, 122 | "nbformat": 4, 123 | "nbformat_minor": 2 124 | } 125 | -------------------------------------------------------------------------------- /day 33 - reservoir sampling.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": 1, 6 | "metadata": { 7 | "collapsed": true 8 | }, 9 | "outputs": [], 10 | "source": [ 11 | "import numpy as np" 12 | ] 13 | }, 14 | { 15 | "cell_type": "markdown", 16 | "metadata": {}, 17 | "source": [ 18 | "## algorithm" 19 | ] 20 | }, 21 | { 22 | "cell_type": "code", 23 | "execution_count": 2, 24 | "metadata": { 25 | "collapsed": true 26 | }, 27 | "outputs": [], 28 | "source": [ 29 | "def reservoir_sampling(size):\n", 30 | " i, sample = 0, []\n", 31 | "\n", 32 | " while True:\n", 33 | " item = yield i, sample\n", 34 | " \n", 35 | " i += 1\n", 36 | " k = np.random.randint(0, i)\n", 37 | "\n", 38 | " if len(sample) < size:\n", 39 | " sample.append(item)\n", 40 | " elif k < size:\n", 41 | " sample[k] = item" 42 | ] 43 | }, 44 | { 45 | "cell_type": "markdown", 46 | "metadata": {}, 47 | "source": [ 48 | "## run" 49 | ] 50 | }, 51 | { 52 | "cell_type": "code", 53 | "execution_count": 3, 54 | "metadata": { 55 | "collapsed": false 56 | }, 57 | "outputs": [ 58 | { 59 | "name": "stdout", 60 | "output_type": "stream", 61 | "text": [ 62 | "100 [15, 49, 54, 63, 60]\n", 63 | "200 [180, 49, 54, 63, 197]\n", 64 | "300 [218, 49, 54, 63, 197]\n", 65 | "400 [218, 49, 54, 63, 197]\n", 66 | "500 [218, 49, 54, 63, 197]\n", 67 | "600 [519, 49, 54, 63, 197]\n", 68 | "700 [691, 49, 54, 63, 197]\n", 69 | "800 [691, 49, 54, 63, 197]\n", 70 | "900 [691, 49, 54, 63, 197]\n", 71 | "1000 [691, 49, 54, 63, 197]\n" 72 | ] 73 | } 74 | ], 75 | "source": [ 76 | "reservoir = reservoir_sampling(5)\n", 77 | "next(reservoir)\n", 78 | "\n", 79 | "for i in range(1000):\n", 80 | " k, sample = reservoir.send(i)\n", 81 | " if k % 100 == 0:\n", 82 | " print(k, sample)" 83 | ] 84 | }, 85 | { 86 | "cell_type": "code", 87 | "execution_count": null, 88 | "metadata": { 89 | "collapsed": true 90 | }, 91 | "outputs": [], 92 | "source": [] 93 | } 94 | ], 95 | "metadata": { 96 | "kernelspec": { 97 | "display_name": "Python 3", 98 | "language": "python", 99 | "name": "python3" 100 | }, 101 | "language_info": { 102 | "codemirror_mode": { 103 | "name": "ipython", 104 | "version": 3 105 | }, 106 | "file_extension": ".py", 107 | "mimetype": "text/x-python", 108 | "name": "python", 109 | "nbconvert_exporter": "python", 110 | "pygments_lexer": "ipython3", 111 | "version": "3.6.0" 112 | } 113 | }, 114 | "nbformat": 4, 115 | "nbformat_minor": 2 116 | } 117 | -------------------------------------------------------------------------------- /day 38 - burrows-wheeler.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "## algorithm" 8 | ] 9 | }, 10 | { 11 | "cell_type": "code", 12 | "execution_count": 1, 13 | "metadata": { 14 | "collapsed": true 15 | }, 16 | "outputs": [], 17 | "source": [ 18 | "def bwt(source):\n", 19 | " aux = [source[i:] + source[:i] for i in range(len(source))]\n", 20 | " aux.sort()\n", 21 | " idx = aux.index(source)\n", 22 | " return ''.join(i[-1] for i in aux), idx" 23 | ] 24 | }, 25 | { 26 | "cell_type": "code", 27 | "execution_count": 2, 28 | "metadata": { 29 | "collapsed": false 30 | }, 31 | "outputs": [], 32 | "source": [ 33 | "def ibwt(source, idx):\n", 34 | " n = len(source)\n", 35 | " aux = [''] * n\n", 36 | " for _ in range(n):\n", 37 | " aux = sorted([i + j for i, j in zip(source, aux)])\n", 38 | " return aux[idx]" 39 | ] 40 | }, 41 | { 42 | "cell_type": "markdown", 43 | "metadata": {}, 44 | "source": [ 45 | "## run" 46 | ] 47 | }, 48 | { 49 | "cell_type": "code", 50 | "execution_count": 3, 51 | "metadata": { 52 | "collapsed": false 53 | }, 54 | "outputs": [ 55 | { 56 | "data": { 57 | "text/plain": [ 58 | "('es,de,aet wnrhrhhhhttt taeeeaer ', 30)" 59 | ] 60 | }, 61 | "execution_count": 3, 62 | "metadata": {}, 63 | "output_type": "execute_result" 64 | } 65 | ], 66 | "source": [ 67 | "target, i = bwt('the theta, there and there, was her')\n", 68 | "target, i" 69 | ] 70 | }, 71 | { 72 | "cell_type": "code", 73 | "execution_count": 4, 74 | "metadata": { 75 | "collapsed": false 76 | }, 77 | "outputs": [ 78 | { 79 | "data": { 80 | "text/plain": [ 81 | "'the theta, there and there, was her'" 82 | ] 83 | }, 84 | "execution_count": 4, 85 | "metadata": {}, 86 | "output_type": "execute_result" 87 | } 88 | ], 89 | "source": [ 90 | "ibwt(target, i)" 91 | ] 92 | }, 93 | { 94 | "cell_type": "code", 95 | "execution_count": null, 96 | "metadata": { 97 | "collapsed": true 98 | }, 99 | "outputs": [], 100 | "source": [] 101 | } 102 | ], 103 | "metadata": { 104 | "kernelspec": { 105 | "display_name": "Python 3", 106 | "language": "python", 107 | "name": "python3" 108 | }, 109 | "language_info": { 110 | "codemirror_mode": { 111 | "name": "ipython", 112 | "version": 3 113 | }, 114 | "file_extension": ".py", 115 | "mimetype": "text/x-python", 116 | "name": "python", 117 | "nbconvert_exporter": "python", 118 | "pygments_lexer": "ipython3", 119 | "version": "3.6.0" 120 | } 121 | }, 122 | "nbformat": 4, 123 | "nbformat_minor": 2 124 | } 125 | -------------------------------------------------------------------------------- /day 16 - no-condition swap.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "## algorithm" 8 | ] 9 | }, 10 | { 11 | "cell_type": "markdown", 12 | "metadata": {}, 13 | "source": [ 14 | "this is C code" 15 | ] 16 | }, 17 | { 18 | "cell_type": "markdown", 19 | "metadata": { 20 | "collapsed": false 21 | }, 22 | "source": [ 23 | "```C\n", 24 | "void swap(int *x, int *y) {\n", 25 | " int u = *x, v = *y;\n", 26 | " int s = (u - v) >> (sizeof(int) * 8 - 1);\n", 27 | " *x = v * (1 + s) - u * s;\n", 28 | " *y = u * (1 + s) - v * s;\n", 29 | "}\n", 30 | "```" 31 | ] 32 | }, 33 | { 34 | "cell_type": "markdown", 35 | "metadata": {}, 36 | "source": [ 37 | "this is Python equivalent" 38 | ] 39 | }, 40 | { 41 | "cell_type": "code", 42 | "execution_count": 1, 43 | "metadata": { 44 | "collapsed": true 45 | }, 46 | "outputs": [], 47 | "source": [ 48 | "def swap(x, y):\n", 49 | " s = x < y\n", 50 | " return x * s + y * (1 - s), y * s + x * (1 - s)" 51 | ] 52 | }, 53 | { 54 | "cell_type": "markdown", 55 | "metadata": {}, 56 | "source": [ 57 | "## run" 58 | ] 59 | }, 60 | { 61 | "cell_type": "code", 62 | "execution_count": 2, 63 | "metadata": { 64 | "collapsed": false 65 | }, 66 | "outputs": [ 67 | { 68 | "data": { 69 | "text/plain": [ 70 | "((3, 15), (3, 15))" 71 | ] 72 | }, 73 | "execution_count": 2, 74 | "metadata": {}, 75 | "output_type": "execute_result" 76 | } 77 | ], 78 | "source": [ 79 | "swap(3, 15), swap(15, 3)" 80 | ] 81 | }, 82 | { 83 | "cell_type": "code", 84 | "execution_count": 3, 85 | "metadata": { 86 | "collapsed": false 87 | }, 88 | "outputs": [ 89 | { 90 | "data": { 91 | "text/plain": [ 92 | "((-13, 5), (-13, 5))" 93 | ] 94 | }, 95 | "execution_count": 3, 96 | "metadata": {}, 97 | "output_type": "execute_result" 98 | } 99 | ], 100 | "source": [ 101 | "swap(-13, 5), swap(5, -13)" 102 | ] 103 | }, 104 | { 105 | "cell_type": "code", 106 | "execution_count": null, 107 | "metadata": { 108 | "collapsed": true 109 | }, 110 | "outputs": [], 111 | "source": [] 112 | } 113 | ], 114 | "metadata": { 115 | "kernelspec": { 116 | "display_name": "Python 3", 117 | "language": "python", 118 | "name": "python3" 119 | }, 120 | "language_info": { 121 | "codemirror_mode": { 122 | "name": "ipython", 123 | "version": 3 124 | }, 125 | "file_extension": ".py", 126 | "mimetype": "text/x-python", 127 | "name": "python", 128 | "nbconvert_exporter": "python", 129 | "pygments_lexer": "ipython3", 130 | "version": "3.6.0" 131 | } 132 | }, 133 | "nbformat": 4, 134 | "nbformat_minor": 2 135 | } 136 | -------------------------------------------------------------------------------- /day 37 - longest common subsequence.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": 1, 6 | "metadata": { 7 | "collapsed": true 8 | }, 9 | "outputs": [], 10 | "source": [ 11 | "from collections import defaultdict" 12 | ] 13 | }, 14 | { 15 | "cell_type": "markdown", 16 | "metadata": {}, 17 | "source": [ 18 | "## algorithm" 19 | ] 20 | }, 21 | { 22 | "cell_type": "code", 23 | "execution_count": 2, 24 | "metadata": { 25 | "collapsed": false 26 | }, 27 | "outputs": [], 28 | "source": [ 29 | "def lcs(X, Y):\n", 30 | " # memoize longest subsequences\n", 31 | " table = defaultdict(lambda: 0)\n", 32 | " \n", 33 | " for i in range(len(X)):\n", 34 | " for j in range(len(Y)):\n", 35 | " if X[i] == Y[j]:\n", 36 | " table[i, j] = table[i - 1, j - 1] + 1\n", 37 | " else:\n", 38 | " table[i, j] = max(table[i - 1, j], table[i, j - 1])\n", 39 | "\n", 40 | " # reconstruction\n", 41 | " sequence = ''\n", 42 | " i, j = len(X) - 1, len(Y) - 1\n", 43 | " \n", 44 | " while i >= 0 and j >= 0:\n", 45 | " if X[i] == Y[j]:\n", 46 | " sequence = X[i] + sequence\n", 47 | " i -= 1\n", 48 | " j -= 1\n", 49 | " elif table[i - 1, j] < table[i, j - 1]:\n", 50 | " j -= 1\n", 51 | " else:\n", 52 | " i -= 1\n", 53 | " \n", 54 | " # result\n", 55 | " return table[len(X) - 1, len(Y) - 1], sequence" 56 | ] 57 | }, 58 | { 59 | "cell_type": "markdown", 60 | "metadata": {}, 61 | "source": [ 62 | "## run" 63 | ] 64 | }, 65 | { 66 | "cell_type": "code", 67 | "execution_count": 3, 68 | "metadata": { 69 | "collapsed": false 70 | }, 71 | "outputs": [ 72 | { 73 | "data": { 74 | "text/plain": [ 75 | "(18, 'oest n subsequence')" 76 | ] 77 | }, 78 | "execution_count": 3, 79 | "metadata": {}, 80 | "output_type": "execute_result" 81 | } 82 | ], 83 | "source": [ 84 | "lcs('longest common sub/sequence', 'shortest unique sub-sequence')" 85 | ] 86 | }, 87 | { 88 | "cell_type": "code", 89 | "execution_count": null, 90 | "metadata": { 91 | "collapsed": true 92 | }, 93 | "outputs": [], 94 | "source": [] 95 | } 96 | ], 97 | "metadata": { 98 | "kernelspec": { 99 | "display_name": "Python 3", 100 | "language": "python", 101 | "name": "python3" 102 | }, 103 | "language_info": { 104 | "codemirror_mode": { 105 | "name": "ipython", 106 | "version": 3 107 | }, 108 | "file_extension": ".py", 109 | "mimetype": "text/x-python", 110 | "name": "python", 111 | "nbconvert_exporter": "python", 112 | "pygments_lexer": "ipython3", 113 | "version": "3.6.0" 114 | } 115 | }, 116 | "nbformat": 4, 117 | "nbformat_minor": 2 118 | } 119 | -------------------------------------------------------------------------------- /day 41 - union-find.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "## algorithm" 8 | ] 9 | }, 10 | { 11 | "cell_type": "code", 12 | "execution_count": 1, 13 | "metadata": { 14 | "collapsed": true 15 | }, 16 | "outputs": [], 17 | "source": [ 18 | "def find(data, i):\n", 19 | " if i != data[i]:\n", 20 | " data[i] = find(data, data[i])\n", 21 | " return data[i]" 22 | ] 23 | }, 24 | { 25 | "cell_type": "code", 26 | "execution_count": 2, 27 | "metadata": { 28 | "collapsed": true 29 | }, 30 | "outputs": [], 31 | "source": [ 32 | "def union(data, i, j):\n", 33 | " pi, pj = find(data, i), find(data, j)\n", 34 | " if pi != pj:\n", 35 | " data[pi] = pj" 36 | ] 37 | }, 38 | { 39 | "cell_type": "code", 40 | "execution_count": 3, 41 | "metadata": { 42 | "collapsed": true 43 | }, 44 | "outputs": [], 45 | "source": [ 46 | "def connected(data, i, j):\n", 47 | " return find(data, i) == find(data, j)" 48 | ] 49 | }, 50 | { 51 | "cell_type": "markdown", 52 | "metadata": {}, 53 | "source": [ 54 | "## run" 55 | ] 56 | }, 57 | { 58 | "cell_type": "code", 59 | "execution_count": 4, 60 | "metadata": { 61 | "collapsed": false 62 | }, 63 | "outputs": [ 64 | { 65 | "name": "stdout", 66 | "output_type": "stream", 67 | "text": [ 68 | "item 0 -> component 9\n", 69 | "item 1 -> component 9\n", 70 | "item 2 -> component 9\n", 71 | "item 3 -> component 3\n", 72 | "item 4 -> component 9\n", 73 | "item 5 -> component 9\n", 74 | "item 6 -> component 9\n", 75 | "item 7 -> component 7\n", 76 | "item 8 -> component 8\n", 77 | "item 9 -> component 9\n" 78 | ] 79 | } 80 | ], 81 | "source": [ 82 | "n = 10\n", 83 | "data = [i for i in range(n)]\n", 84 | "connections = [(0, 1), (1, 2), (0, 9), (5, 6), (6, 4), (5, 9)]\n", 85 | "\n", 86 | "# union\n", 87 | "for i, j in connections:\n", 88 | " union(data, i, j)\n", 89 | "\n", 90 | "# find\n", 91 | "for i in range(n):\n", 92 | " print('item', i, '-> component', find(data, i))" 93 | ] 94 | }, 95 | { 96 | "cell_type": "code", 97 | "execution_count": null, 98 | "metadata": { 99 | "collapsed": true 100 | }, 101 | "outputs": [], 102 | "source": [] 103 | } 104 | ], 105 | "metadata": { 106 | "kernelspec": { 107 | "display_name": "Python 3", 108 | "language": "python", 109 | "name": "python3" 110 | }, 111 | "language_info": { 112 | "codemirror_mode": { 113 | "name": "ipython", 114 | "version": 3 115 | }, 116 | "file_extension": ".py", 117 | "mimetype": "text/x-python", 118 | "name": "python", 119 | "nbconvert_exporter": "python", 120 | "pygments_lexer": "ipython3", 121 | "version": "3.6.0" 122 | } 123 | }, 124 | "nbformat": 4, 125 | "nbformat_minor": 2 126 | } 127 | -------------------------------------------------------------------------------- /day 09 - monte carlo - pi.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": 1, 6 | "metadata": { 7 | "collapsed": true 8 | }, 9 | "outputs": [], 10 | "source": [ 11 | "import numpy as np" 12 | ] 13 | }, 14 | { 15 | "cell_type": "markdown", 16 | "metadata": {}, 17 | "source": [ 18 | "## algorithm" 19 | ] 20 | }, 21 | { 22 | "cell_type": "code", 23 | "execution_count": 2, 24 | "metadata": { 25 | "collapsed": false 26 | }, 27 | "outputs": [], 28 | "source": [ 29 | "def pi(n, batch=1000):\n", 30 | " t = 0\n", 31 | " for i in range(n // batch):\n", 32 | " p = np.random.rand(batch, 2)\n", 33 | " p = (p * p).sum(axis=1)\n", 34 | " t += (p <= 1).sum()\n", 35 | " return 4 * t / n" 36 | ] 37 | }, 38 | { 39 | "cell_type": "markdown", 40 | "metadata": {}, 41 | "source": [ 42 | "## run" 43 | ] 44 | }, 45 | { 46 | "cell_type": "code", 47 | "execution_count": 3, 48 | "metadata": { 49 | "collapsed": false 50 | }, 51 | "outputs": [ 52 | { 53 | "data": { 54 | "text/plain": [ 55 | "3.1400000000000001" 56 | ] 57 | }, 58 | "execution_count": 3, 59 | "metadata": {}, 60 | "output_type": "execute_result" 61 | } 62 | ], 63 | "source": [ 64 | "pi(10 ** 3)" 65 | ] 66 | }, 67 | { 68 | "cell_type": "code", 69 | "execution_count": 4, 70 | "metadata": { 71 | "collapsed": false 72 | }, 73 | "outputs": [ 74 | { 75 | "data": { 76 | "text/plain": [ 77 | "3.1418360000000001" 78 | ] 79 | }, 80 | "execution_count": 4, 81 | "metadata": {}, 82 | "output_type": "execute_result" 83 | } 84 | ], 85 | "source": [ 86 | "pi(10 ** 6)" 87 | ] 88 | }, 89 | { 90 | "cell_type": "code", 91 | "execution_count": 5, 92 | "metadata": { 93 | "collapsed": false 94 | }, 95 | "outputs": [ 96 | { 97 | "data": { 98 | "text/plain": [ 99 | "3.14145728" 100 | ] 101 | }, 102 | "execution_count": 5, 103 | "metadata": {}, 104 | "output_type": "execute_result" 105 | } 106 | ], 107 | "source": [ 108 | "pi(10 ** 8)" 109 | ] 110 | }, 111 | { 112 | "cell_type": "code", 113 | "execution_count": null, 114 | "metadata": { 115 | "collapsed": true 116 | }, 117 | "outputs": [], 118 | "source": [] 119 | } 120 | ], 121 | "metadata": { 122 | "kernelspec": { 123 | "display_name": "Python 3", 124 | "language": "python", 125 | "name": "python3" 126 | }, 127 | "language_info": { 128 | "codemirror_mode": { 129 | "name": "ipython", 130 | "version": 3 131 | }, 132 | "file_extension": ".py", 133 | "mimetype": "text/x-python", 134 | "name": "python", 135 | "nbconvert_exporter": "python", 136 | "pygments_lexer": "ipython3", 137 | "version": "3.6.0" 138 | } 139 | }, 140 | "nbformat": 4, 141 | "nbformat_minor": 2 142 | } 143 | -------------------------------------------------------------------------------- /day 25 - conjugate gradients.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": 1, 6 | "metadata": { 7 | "collapsed": true 8 | }, 9 | "outputs": [], 10 | "source": [ 11 | "import numpy as np" 12 | ] 13 | }, 14 | { 15 | "cell_type": "markdown", 16 | "metadata": {}, 17 | "source": [ 18 | "## algorithm" 19 | ] 20 | }, 21 | { 22 | "cell_type": "code", 23 | "execution_count": 2, 24 | "metadata": { 25 | "collapsed": true 26 | }, 27 | "outputs": [], 28 | "source": [ 29 | "def conjugate_gradients(A, b):\n", 30 | " x = np.zeros(A.shape[1])\n", 31 | " residuals = b - A @ x\n", 32 | " direction = residuals\n", 33 | " error = residuals.T @ residuals\n", 34 | "\n", 35 | " # step along conjugate directions\n", 36 | " while error > 1e-8:\n", 37 | " x += direction * error / (direction.T @ A @ direction)\n", 38 | " residuals = b - A @ x\n", 39 | " error1 = error\n", 40 | " error = residuals.T @ residuals\n", 41 | " direction = residuals + error / error1 * direction\n", 42 | "\n", 43 | " return x" 44 | ] 45 | }, 46 | { 47 | "cell_type": "markdown", 48 | "metadata": {}, 49 | "source": [ 50 | "## run" 51 | ] 52 | }, 53 | { 54 | "cell_type": "code", 55 | "execution_count": 3, 56 | "metadata": { 57 | "collapsed": false 58 | }, 59 | "outputs": [ 60 | { 61 | "name": "stdout", 62 | "output_type": "stream", 63 | "text": [ 64 | "A\n", 65 | "[[ 0.72202644 0.70073834 0.09483571]\n", 66 | " [ 0.97657699 0.41447392 0.96942563]\n", 67 | " [ 0.35596098 0.91433461 0.52105508]\n", 68 | " [ 0.66857021 0.48664146 0.46385892]\n", 69 | " [ 0.65044125 0.98123656 0.55633599]]\n", 70 | "b\n", 71 | "[ 0.97013697 0.76971217 0.92539487 0.10820739 0.98406079]\n", 72 | "x\n", 73 | "[ 0.26730959 0.87199275 -0.04536451]\n" 74 | ] 75 | } 76 | ], 77 | "source": [ 78 | "A = np.random.rand(5, 3)\n", 79 | "b = np.random.rand(5)\n", 80 | "\n", 81 | "print('A')\n", 82 | "print(A)\n", 83 | "print('b')\n", 84 | "print(b)\n", 85 | "print('x')\n", 86 | "\n", 87 | "# make system positive semidefinite\n", 88 | "print(conjugate_gradients(A.T @ A, A.T @ b))" 89 | ] 90 | }, 91 | { 92 | "cell_type": "code", 93 | "execution_count": null, 94 | "metadata": { 95 | "collapsed": true 96 | }, 97 | "outputs": [], 98 | "source": [] 99 | } 100 | ], 101 | "metadata": { 102 | "kernelspec": { 103 | "display_name": "Python 3", 104 | "language": "python", 105 | "name": "python3" 106 | }, 107 | "language_info": { 108 | "codemirror_mode": { 109 | "name": "ipython", 110 | "version": 3 111 | }, 112 | "file_extension": ".py", 113 | "mimetype": "text/x-python", 114 | "name": "python", 115 | "nbconvert_exporter": "python", 116 | "pygments_lexer": "ipython3", 117 | "version": "3.6.0" 118 | } 119 | }, 120 | "nbformat": 4, 121 | "nbformat_minor": 2 122 | } 123 | -------------------------------------------------------------------------------- /day 06 - postfix notation.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "## algorithm" 8 | ] 9 | }, 10 | { 11 | "cell_type": "code", 12 | "execution_count": 1, 13 | "metadata": { 14 | "collapsed": false 15 | }, 16 | "outputs": [], 17 | "source": [ 18 | "ops = {\n", 19 | " '+': float.__add__,\n", 20 | " '-': float.__sub__,\n", 21 | " '*': float.__mul__,\n", 22 | " '/': float.__truediv__,\n", 23 | " '^': float.__pow__,\n", 24 | "}\n", 25 | "\n", 26 | "def postfix(expression):\n", 27 | " stack = []\n", 28 | " \n", 29 | " for x in expression.split():\n", 30 | " if x in ops:\n", 31 | " x = ops[x](stack.pop(-2), stack.pop(-1))\n", 32 | " else:\n", 33 | " x = float(x)\n", 34 | " stack.append(x)\n", 35 | " \n", 36 | " return stack.pop()" 37 | ] 38 | }, 39 | { 40 | "cell_type": "markdown", 41 | "metadata": {}, 42 | "source": [ 43 | "## run" 44 | ] 45 | }, 46 | { 47 | "cell_type": "code", 48 | "execution_count": 2, 49 | "metadata": { 50 | "collapsed": false 51 | }, 52 | "outputs": [ 53 | { 54 | "data": { 55 | "text/plain": [ 56 | "8.0" 57 | ] 58 | }, 59 | "execution_count": 2, 60 | "metadata": {}, 61 | "output_type": "execute_result" 62 | } 63 | ], 64 | "source": [ 65 | "postfix('1 2 + 4 3 - + 10 5 / *')" 66 | ] 67 | }, 68 | { 69 | "cell_type": "code", 70 | "execution_count": 3, 71 | "metadata": { 72 | "collapsed": false 73 | }, 74 | "outputs": [ 75 | { 76 | "data": { 77 | "text/plain": [ 78 | "25.0" 79 | ] 80 | }, 81 | "execution_count": 3, 82 | "metadata": {}, 83 | "output_type": "execute_result" 84 | } 85 | ], 86 | "source": [ 87 | "postfix('1 2 * 6 2 / + 9 7 - ^')" 88 | ] 89 | }, 90 | { 91 | "cell_type": "code", 92 | "execution_count": 4, 93 | "metadata": { 94 | "collapsed": false 95 | }, 96 | "outputs": [ 97 | { 98 | "data": { 99 | "text/plain": [ 100 | "15.0" 101 | ] 102 | }, 103 | "execution_count": 4, 104 | "metadata": {}, 105 | "output_type": "execute_result" 106 | } 107 | ], 108 | "source": [ 109 | "postfix('1 2 3 4 5 + + + +')" 110 | ] 111 | }, 112 | { 113 | "cell_type": "code", 114 | "execution_count": null, 115 | "metadata": { 116 | "collapsed": true 117 | }, 118 | "outputs": [], 119 | "source": [] 120 | } 121 | ], 122 | "metadata": { 123 | "kernelspec": { 124 | "display_name": "Python 3", 125 | "language": "python", 126 | "name": "python3" 127 | }, 128 | "language_info": { 129 | "codemirror_mode": { 130 | "name": "ipython", 131 | "version": 3 132 | }, 133 | "file_extension": ".py", 134 | "mimetype": "text/x-python", 135 | "name": "python", 136 | "nbconvert_exporter": "python", 137 | "pygments_lexer": "ipython3", 138 | "version": "3.6.0" 139 | } 140 | }, 141 | "nbformat": 4, 142 | "nbformat_minor": 2 143 | } 144 | -------------------------------------------------------------------------------- /day 47 - factoradic.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "## algorithm" 8 | ] 9 | }, 10 | { 11 | "cell_type": "code", 12 | "execution_count": 1, 13 | "metadata": { 14 | "collapsed": true 15 | }, 16 | "outputs": [], 17 | "source": [ 18 | "fac = lambda i, *j: i and fac(*divmod(i, len(j) + 1), *j) or j or (i,)" 19 | ] 20 | }, 21 | { 22 | "cell_type": "code", 23 | "execution_count": 2, 24 | "metadata": { 25 | "collapsed": true 26 | }, 27 | "outputs": [], 28 | "source": [ 29 | "dec = lambda i, k=0, *j: j and dec(i * len(j) + i + k, *j) or i" 30 | ] 31 | }, 32 | { 33 | "cell_type": "markdown", 34 | "metadata": {}, 35 | "source": [ 36 | "## run" 37 | ] 38 | }, 39 | { 40 | "cell_type": "code", 41 | "execution_count": 3, 42 | "metadata": { 43 | "collapsed": false 44 | }, 45 | "outputs": [ 46 | { 47 | "name": "stdout", 48 | "output_type": "stream", 49 | "text": [ 50 | "0 <-> 0\n", 51 | "1 <-> 1 0\n", 52 | "8 <-> 1 1 0 0\n", 53 | "27 <-> 1 0 1 1 0\n", 54 | "64 <-> 2 2 2 0 0\n", 55 | "125 <-> 1 0 0 2 1 0\n", 56 | "216 <-> 1 4 0 0 0 0\n", 57 | "343 <-> 2 4 1 0 1 0\n", 58 | "512 <-> 4 1 1 1 0 0\n", 59 | "729 <-> 1 0 0 1 1 1 0\n", 60 | "1000 <-> 1 2 1 2 2 0 0\n" 61 | ] 62 | } 63 | ], 64 | "source": [ 65 | "for i in range(0, 11):\n", 66 | " f = fac(i ** 3)\n", 67 | " d = dec(*f)\n", 68 | " print(d, '<->', ' '.join(map(str, f)))" 69 | ] 70 | }, 71 | { 72 | "cell_type": "code", 73 | "execution_count": 4, 74 | "metadata": { 75 | "collapsed": false 76 | }, 77 | "outputs": [ 78 | { 79 | "data": { 80 | "text/plain": [ 81 | "(1, 1, 4, 1, 2, 2, 1, 0)" 82 | ] 83 | }, 84 | "execution_count": 4, 85 | "metadata": {}, 86 | "output_type": "execute_result" 87 | } 88 | ], 89 | "source": [ 90 | "fac(6281)" 91 | ] 92 | }, 93 | { 94 | "cell_type": "code", 95 | "execution_count": 5, 96 | "metadata": { 97 | "collapsed": false 98 | }, 99 | "outputs": [ 100 | { 101 | "data": { 102 | "text/plain": [ 103 | "6281" 104 | ] 105 | }, 106 | "execution_count": 5, 107 | "metadata": {}, 108 | "output_type": "execute_result" 109 | } 110 | ], 111 | "source": [ 112 | "dec(*(1, 1, 4, 1, 2, 2, 1, 0))" 113 | ] 114 | }, 115 | { 116 | "cell_type": "code", 117 | "execution_count": null, 118 | "metadata": { 119 | "collapsed": true 120 | }, 121 | "outputs": [], 122 | "source": [] 123 | } 124 | ], 125 | "metadata": { 126 | "kernelspec": { 127 | "display_name": "Python 3", 128 | "language": "python", 129 | "name": "python3" 130 | }, 131 | "language_info": { 132 | "codemirror_mode": { 133 | "name": "ipython", 134 | "version": 3 135 | }, 136 | "file_extension": ".py", 137 | "mimetype": "text/x-python", 138 | "name": "python", 139 | "nbconvert_exporter": "python", 140 | "pygments_lexer": "ipython3", 141 | "version": "3.6.0" 142 | } 143 | }, 144 | "nbformat": 4, 145 | "nbformat_minor": 2 146 | } 147 | -------------------------------------------------------------------------------- /day 43 - shuffle.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": 1, 6 | "metadata": { 7 | "collapsed": true 8 | }, 9 | "outputs": [], 10 | "source": [ 11 | "import numpy as np" 12 | ] 13 | }, 14 | { 15 | "cell_type": "markdown", 16 | "metadata": {}, 17 | "source": [ 18 | "## algorithm" 19 | ] 20 | }, 21 | { 22 | "cell_type": "code", 23 | "execution_count": 2, 24 | "metadata": { 25 | "collapsed": true 26 | }, 27 | "outputs": [], 28 | "source": [ 29 | "def shuffle(data):\n", 30 | " n = len(data)\n", 31 | " for i in range(n):\n", 32 | " k = np.random.randint(i, n)\n", 33 | " data[i], data[k] = data[k], data[i]\n", 34 | " \n", 35 | " return data" 36 | ] 37 | }, 38 | { 39 | "cell_type": "markdown", 40 | "metadata": {}, 41 | "source": [ 42 | "## shuffle" 43 | ] 44 | }, 45 | { 46 | "cell_type": "code", 47 | "execution_count": 3, 48 | "metadata": { 49 | "collapsed": true 50 | }, 51 | "outputs": [], 52 | "source": [ 53 | "data = list(range(10))" 54 | ] 55 | }, 56 | { 57 | "cell_type": "code", 58 | "execution_count": 4, 59 | "metadata": { 60 | "collapsed": false 61 | }, 62 | "outputs": [ 63 | { 64 | "data": { 65 | "text/plain": [ 66 | "[3, 8, 6, 4, 1, 5, 0, 7, 2, 9]" 67 | ] 68 | }, 69 | "execution_count": 4, 70 | "metadata": {}, 71 | "output_type": "execute_result" 72 | } 73 | ], 74 | "source": [ 75 | "shuffle(data)" 76 | ] 77 | }, 78 | { 79 | "cell_type": "code", 80 | "execution_count": 5, 81 | "metadata": { 82 | "collapsed": false 83 | }, 84 | "outputs": [ 85 | { 86 | "data": { 87 | "text/plain": [ 88 | "[3, 8, 9, 7, 6, 2, 4, 5, 0, 1]" 89 | ] 90 | }, 91 | "execution_count": 5, 92 | "metadata": {}, 93 | "output_type": "execute_result" 94 | } 95 | ], 96 | "source": [ 97 | "shuffle(data)" 98 | ] 99 | }, 100 | { 101 | "cell_type": "code", 102 | "execution_count": 6, 103 | "metadata": { 104 | "collapsed": false 105 | }, 106 | "outputs": [ 107 | { 108 | "data": { 109 | "text/plain": [ 110 | "[7, 6, 4, 2, 1, 9, 3, 8, 5, 0]" 111 | ] 112 | }, 113 | "execution_count": 6, 114 | "metadata": {}, 115 | "output_type": "execute_result" 116 | } 117 | ], 118 | "source": [ 119 | "shuffle(data)" 120 | ] 121 | }, 122 | { 123 | "cell_type": "code", 124 | "execution_count": null, 125 | "metadata": { 126 | "collapsed": true 127 | }, 128 | "outputs": [], 129 | "source": [] 130 | } 131 | ], 132 | "metadata": { 133 | "kernelspec": { 134 | "display_name": "Python 3", 135 | "language": "python", 136 | "name": "python3" 137 | }, 138 | "language_info": { 139 | "codemirror_mode": { 140 | "name": "ipython", 141 | "version": 3 142 | }, 143 | "file_extension": ".py", 144 | "mimetype": "text/x-python", 145 | "name": "python", 146 | "nbconvert_exporter": "python", 147 | "pygments_lexer": "ipython3", 148 | "version": "3.6.0" 149 | } 150 | }, 151 | "nbformat": 4, 152 | "nbformat_minor": 2 153 | } 154 | -------------------------------------------------------------------------------- /day 20 - linearithmic multiplication.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": 1, 6 | "metadata": { 7 | "collapsed": true 8 | }, 9 | "outputs": [], 10 | "source": [ 11 | "import numpy as np" 12 | ] 13 | }, 14 | { 15 | "cell_type": "markdown", 16 | "metadata": {}, 17 | "source": [ 18 | "## algorithm" 19 | ] 20 | }, 21 | { 22 | "cell_type": "code", 23 | "execution_count": 2, 24 | "metadata": { 25 | "collapsed": false 26 | }, 27 | "outputs": [], 28 | "source": [ 29 | "def mult(x, y):\n", 30 | " nx, ny = len(x), len(y)\n", 31 | "\n", 32 | " # auxiliary x\n", 33 | " fx = np.zeros(nx + ny, dtype=np.float64)\n", 34 | " fx[:nx] = list(map(int, reversed(x)))\n", 35 | "\n", 36 | " # auxiliary y\n", 37 | " fy = np.zeros(nx + ny, np.float64)\n", 38 | " fy[:ny] += list(map(int, reversed(y)))\n", 39 | "\n", 40 | " # convolution via FFT\n", 41 | " fx = np.fft.fft(fx)\n", 42 | " fy = np.fft.fft(fy)\n", 43 | " z = np.fft.ifft(fx * fy).real.round().astype(int)\n", 44 | "\n", 45 | " # carry over\n", 46 | " for i in range(nx + ny - 1):\n", 47 | " z[i + 1] += z[i] // 10\n", 48 | " z[i] %= 10\n", 49 | "\n", 50 | " return ''.join(map(str, reversed(z)))" 51 | ] 52 | }, 53 | { 54 | "cell_type": "markdown", 55 | "metadata": {}, 56 | "source": [ 57 | "## run" 58 | ] 59 | }, 60 | { 61 | "cell_type": "code", 62 | "execution_count": 3, 63 | "metadata": { 64 | "collapsed": false 65 | }, 66 | "outputs": [ 67 | { 68 | "name": "stdout", 69 | "output_type": "stream", 70 | "text": [ 71 | "2092214183 * 2448001885 = 05121744263807734955\n", 72 | "7122461902 * 9593715983 = 68330876587525979666\n", 73 | "8617908461 * 3158102416 = 27216237531550941776\n", 74 | "3655867966 * 9064788350 = 33139669347334996100\n", 75 | "6622180692 * 4377254226 = 28986968419392604392\n", 76 | "6147274168 * 3384584963 = 20805971712451135784\n", 77 | "4714353304 * 5151447888 = 24285745371176621952\n", 78 | "9370611380 * 145283374 = 1361394037729196120\n", 79 | "2465911620 * 2801092645 = 06907246902002034900\n", 80 | "7836421288 * 8791219244 = 68891697631156866272\n" 81 | ] 82 | } 83 | ], 84 | "source": [ 85 | "for _ in range(10):\n", 86 | " x, y = np.random.randint(1e+3, 1e+10, 2)\n", 87 | " print(x, '*', y, '=', mult(str(x), str(y)))" 88 | ] 89 | }, 90 | { 91 | "cell_type": "code", 92 | "execution_count": null, 93 | "metadata": { 94 | "collapsed": true 95 | }, 96 | "outputs": [], 97 | "source": [] 98 | } 99 | ], 100 | "metadata": { 101 | "kernelspec": { 102 | "display_name": "Python 3", 103 | "language": "python", 104 | "name": "python3" 105 | }, 106 | "language_info": { 107 | "codemirror_mode": { 108 | "name": "ipython", 109 | "version": 3 110 | }, 111 | "file_extension": ".py", 112 | "mimetype": "text/x-python", 113 | "name": "python", 114 | "nbconvert_exporter": "python", 115 | "pygments_lexer": "ipython3", 116 | "version": "3.6.0" 117 | } 118 | }, 119 | "nbformat": 4, 120 | "nbformat_minor": 2 121 | } 122 | -------------------------------------------------------------------------------- /day 08 - binary search.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "## algorithm" 8 | ] 9 | }, 10 | { 11 | "cell_type": "code", 12 | "execution_count": 1, 13 | "metadata": { 14 | "collapsed": false 15 | }, 16 | "outputs": [], 17 | "source": [ 18 | "def search(data, item):\n", 19 | " left, right = 0, len(data) - 1\n", 20 | " \n", 21 | " while left <= right:\n", 22 | " middle = (left + right) // 2\n", 23 | " \n", 24 | " if item < data[middle]:\n", 25 | " right = middle - 1\n", 26 | " elif item > data[middle]:\n", 27 | " left = middle + 1\n", 28 | " else:\n", 29 | " return middle\n", 30 | " \n", 31 | " return -1" 32 | ] 33 | }, 34 | { 35 | "cell_type": "markdown", 36 | "metadata": {}, 37 | "source": [ 38 | "## run" 39 | ] 40 | }, 41 | { 42 | "cell_type": "code", 43 | "execution_count": 2, 44 | "metadata": { 45 | "collapsed": false 46 | }, 47 | "outputs": [], 48 | "source": [ 49 | "data = [2, 3, 4, 8, 22, 23, 24, 25, 26, 28, 31, 39, 40, 43, 45, 49, 54, 58, 59, 60, 72, 73, 76, 87, 95, 97, 98]\n", 50 | "data = sorted(data)" 51 | ] 52 | }, 53 | { 54 | "cell_type": "code", 55 | "execution_count": 3, 56 | "metadata": { 57 | "collapsed": false 58 | }, 59 | "outputs": [ 60 | { 61 | "data": { 62 | "text/plain": [ 63 | "2" 64 | ] 65 | }, 66 | "execution_count": 3, 67 | "metadata": {}, 68 | "output_type": "execute_result" 69 | } 70 | ], 71 | "source": [ 72 | "search(data, 4)" 73 | ] 74 | }, 75 | { 76 | "cell_type": "code", 77 | "execution_count": 4, 78 | "metadata": { 79 | "collapsed": false 80 | }, 81 | "outputs": [ 82 | { 83 | "data": { 84 | "text/plain": [ 85 | "-1" 86 | ] 87 | }, 88 | "execution_count": 4, 89 | "metadata": {}, 90 | "output_type": "execute_result" 91 | } 92 | ], 93 | "source": [ 94 | "search(data, 74)" 95 | ] 96 | }, 97 | { 98 | "cell_type": "code", 99 | "execution_count": 5, 100 | "metadata": { 101 | "collapsed": false 102 | }, 103 | "outputs": [ 104 | { 105 | "data": { 106 | "text/plain": [ 107 | "-1" 108 | ] 109 | }, 110 | "execution_count": 5, 111 | "metadata": {}, 112 | "output_type": "execute_result" 113 | } 114 | ], 115 | "source": [ 116 | "search(data, 0)" 117 | ] 118 | }, 119 | { 120 | "cell_type": "code", 121 | "execution_count": null, 122 | "metadata": { 123 | "collapsed": true 124 | }, 125 | "outputs": [], 126 | "source": [] 127 | } 128 | ], 129 | "metadata": { 130 | "kernelspec": { 131 | "display_name": "Python 3", 132 | "language": "python", 133 | "name": "python3" 134 | }, 135 | "language_info": { 136 | "codemirror_mode": { 137 | "name": "ipython", 138 | "version": 3 139 | }, 140 | "file_extension": ".py", 141 | "mimetype": "text/x-python", 142 | "name": "python", 143 | "nbconvert_exporter": "python", 144 | "pygments_lexer": "ipython3", 145 | "version": "3.6.0" 146 | } 147 | }, 148 | "nbformat": 4, 149 | "nbformat_minor": 2 150 | } 151 | -------------------------------------------------------------------------------- /day 22 - determinant.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": 1, 6 | "metadata": { 7 | "collapsed": true 8 | }, 9 | "outputs": [], 10 | "source": [ 11 | "import numpy as np" 12 | ] 13 | }, 14 | { 15 | "cell_type": "markdown", 16 | "metadata": {}, 17 | "source": [ 18 | "## algorithm" 19 | ] 20 | }, 21 | { 22 | "cell_type": "code", 23 | "execution_count": 2, 24 | "metadata": { 25 | "collapsed": false 26 | }, 27 | "outputs": [], 28 | "source": [ 29 | "def determinant(x):\n", 30 | " if x.size == 1:\n", 31 | " return x[0, 0]\n", 32 | " \n", 33 | " # pivot\n", 34 | " i = np.abs(x[:, 0]).argmax()\n", 35 | " pivot = x[i, 0]\n", 36 | " if np.abs(pivot) < 1e-15:\n", 37 | " return 0\n", 38 | " \n", 39 | " # gauss elimination\n", 40 | " n = len(x)\n", 41 | " y = x - x[:, 0].reshape(n, 1) @ (x[i, :] / x[i, 0]).reshape(1, n)\n", 42 | " y = y[np.arange(n) != i, 1:]\n", 43 | "\n", 44 | " # recursion\n", 45 | " return pivot * (-1) ** (i % 2) * determinant(y)" 46 | ] 47 | }, 48 | { 49 | "cell_type": "markdown", 50 | "metadata": {}, 51 | "source": [ 52 | "## run" 53 | ] 54 | }, 55 | { 56 | "cell_type": "code", 57 | "execution_count": 3, 58 | "metadata": { 59 | "collapsed": false 60 | }, 61 | "outputs": [ 62 | { 63 | "data": { 64 | "text/plain": [ 65 | "array([[ 0.86407152, -0.48119607, -0.60195809, -0.15813597, -0.25164858],\n", 66 | " [-0.45656693, -0.86405085, -0.26996402, 0.00863821, -0.42482759],\n", 67 | " [ 0.62699481, -0.15693623, 0.88928594, -0.59483779, 0.45047394],\n", 68 | " [ 0.27561899, 0.08707643, -0.63000059, 0.19882408, 0.17816101],\n", 69 | " [-0.36012304, -0.47399834, 0.17859948, 0.23234741, 0.65332936]])" 70 | ] 71 | }, 72 | "execution_count": 3, 73 | "metadata": {}, 74 | "output_type": "execute_result" 75 | } 76 | ], 77 | "source": [ 78 | "X = np.random.rand(5, 5) * 2 - 1\n", 79 | "X" 80 | ] 81 | }, 82 | { 83 | "cell_type": "code", 84 | "execution_count": 4, 85 | "metadata": { 86 | "collapsed": false 87 | }, 88 | "outputs": [ 89 | { 90 | "data": { 91 | "text/plain": [ 92 | "0.14322328293127826" 93 | ] 94 | }, 95 | "execution_count": 4, 96 | "metadata": {}, 97 | "output_type": "execute_result" 98 | } 99 | ], 100 | "source": [ 101 | "determinant(X)" 102 | ] 103 | }, 104 | { 105 | "cell_type": "code", 106 | "execution_count": null, 107 | "metadata": { 108 | "collapsed": true 109 | }, 110 | "outputs": [], 111 | "source": [] 112 | } 113 | ], 114 | "metadata": { 115 | "kernelspec": { 116 | "display_name": "Python 3", 117 | "language": "python", 118 | "name": "python3" 119 | }, 120 | "language_info": { 121 | "codemirror_mode": { 122 | "name": "ipython", 123 | "version": 3 124 | }, 125 | "file_extension": ".py", 126 | "mimetype": "text/x-python", 127 | "name": "python", 128 | "nbconvert_exporter": "python", 129 | "pygments_lexer": "ipython3", 130 | "version": "3.6.0" 131 | } 132 | }, 133 | "nbformat": 4, 134 | "nbformat_minor": 2 135 | } 136 | -------------------------------------------------------------------------------- /day 19 - counting inversions.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": 1, 6 | "metadata": { 7 | "collapsed": true 8 | }, 9 | "outputs": [], 10 | "source": [ 11 | "import numpy as np" 12 | ] 13 | }, 14 | { 15 | "cell_type": "markdown", 16 | "metadata": {}, 17 | "source": [ 18 | "## algorithm" 19 | ] 20 | }, 21 | { 22 | "cell_type": "code", 23 | "execution_count": 2, 24 | "metadata": { 25 | "collapsed": true 26 | }, 27 | "outputs": [], 28 | "source": [ 29 | "def inversions(items):\n", 30 | " n = len(items)\n", 31 | " if n <= 1:\n", 32 | " return items, 0\n", 33 | "\n", 34 | " # number of inversions in partitions\n", 35 | " left, linv = inversions(items[:n // 2])\n", 36 | " right, rinv = inversions(items[n // 2:])\n", 37 | "\n", 38 | " inv = linv + rinv\n", 39 | " llen, rlen = len(left), len(right)\n", 40 | " i, j, aux = 0, 0, []\n", 41 | "\n", 42 | " # merge and count inversions\n", 43 | " for k in range(n):\n", 44 | " if i < llen and j < rlen and left[i] > right[j]:\n", 45 | " inv += llen - i\n", 46 | " aux.append(right[j])\n", 47 | " j += 1\n", 48 | " elif i < llen:\n", 49 | " aux.append(left[i])\n", 50 | " i += 1\n", 51 | " else:\n", 52 | " aux.append(right[j])\n", 53 | " j += 1\n", 54 | " \n", 55 | " return aux, inv" 56 | ] 57 | }, 58 | { 59 | "cell_type": "markdown", 60 | "metadata": {}, 61 | "source": [ 62 | "## run" 63 | ] 64 | }, 65 | { 66 | "cell_type": "code", 67 | "execution_count": 3, 68 | "metadata": { 69 | "collapsed": false 70 | }, 71 | "outputs": [ 72 | { 73 | "data": { 74 | "text/plain": [ 75 | "[29, 25, 17, 15, 6, 8, 11, 15, 7, 5]" 76 | ] 77 | }, 78 | "execution_count": 3, 79 | "metadata": {}, 80 | "output_type": "execute_result" 81 | } 82 | ], 83 | "source": [ 84 | "items = list(np.random.randint(0, 30, 10))\n", 85 | "items" 86 | ] 87 | }, 88 | { 89 | "cell_type": "code", 90 | "execution_count": 4, 91 | "metadata": { 92 | "collapsed": false 93 | }, 94 | "outputs": [ 95 | { 96 | "data": { 97 | "text/plain": [ 98 | "([5, 6, 7, 8, 11, 15, 15, 17, 25, 29], 37)" 99 | ] 100 | }, 101 | "execution_count": 4, 102 | "metadata": {}, 103 | "output_type": "execute_result" 104 | } 105 | ], 106 | "source": [ 107 | "inversions(items)" 108 | ] 109 | }, 110 | { 111 | "cell_type": "code", 112 | "execution_count": null, 113 | "metadata": { 114 | "collapsed": true 115 | }, 116 | "outputs": [], 117 | "source": [] 118 | } 119 | ], 120 | "metadata": { 121 | "kernelspec": { 122 | "display_name": "Python 3", 123 | "language": "python", 124 | "name": "python3" 125 | }, 126 | "language_info": { 127 | "codemirror_mode": { 128 | "name": "ipython", 129 | "version": 3 130 | }, 131 | "file_extension": ".py", 132 | "mimetype": "text/x-python", 133 | "name": "python", 134 | "nbconvert_exporter": "python", 135 | "pygments_lexer": "ipython3", 136 | "version": "3.6.0" 137 | } 138 | }, 139 | "nbformat": 4, 140 | "nbformat_minor": 2 141 | } 142 | -------------------------------------------------------------------------------- /day 39 - 4sum.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": 1, 6 | "metadata": { 7 | "collapsed": false 8 | }, 9 | "outputs": [], 10 | "source": [ 11 | "import numpy as np\n", 12 | "from itertools import combinations, product\n", 13 | "from collections import defaultdict" 14 | ] 15 | }, 16 | { 17 | "cell_type": "markdown", 18 | "metadata": {}, 19 | "source": [ 20 | "## algorithm" 21 | ] 22 | }, 23 | { 24 | "cell_type": "code", 25 | "execution_count": 2, 26 | "metadata": { 27 | "collapsed": true 28 | }, 29 | "outputs": [], 30 | "source": [ 31 | "def sum4(data):\n", 32 | " # store 2-sums\n", 33 | " sum_of_2 = defaultdict(list)\n", 34 | " for i, j in combinations(range(len(data)), 2):\n", 35 | " k = data[i] + data[j]\n", 36 | " sum_of_2[k].append((i, j))\n", 37 | "\n", 38 | " # match pairs of 2-sums\n", 39 | " sum_of_4 = set()\n", 40 | " for k in sum_of_2:\n", 41 | " if k >= 0 and -k in sum_of_2:\n", 42 | " for i, j in product(sum_of_2[k], sum_of_2[-k]):\n", 43 | " index = tuple(sorted(set(i + j)))\n", 44 | " if len(index) == 4:\n", 45 | " sum_of_4.add(index)\n", 46 | "\n", 47 | " return sum_of_4" 48 | ] 49 | }, 50 | { 51 | "cell_type": "markdown", 52 | "metadata": {}, 53 | "source": [ 54 | "## run" 55 | ] 56 | }, 57 | { 58 | "cell_type": "code", 59 | "execution_count": 3, 60 | "metadata": { 61 | "collapsed": false 62 | }, 63 | "outputs": [ 64 | { 65 | "data": { 66 | "text/plain": [ 67 | "array([ 5, 1, -9, -6, 4, -4, 7, 1, -10, -6])" 68 | ] 69 | }, 70 | "execution_count": 3, 71 | "metadata": {}, 72 | "output_type": "execute_result" 73 | } 74 | ], 75 | "source": [ 76 | "n = 10\n", 77 | "data = np.random.randint(-n, n, n)\n", 78 | "data" 79 | ] 80 | }, 81 | { 82 | "cell_type": "code", 83 | "execution_count": 4, 84 | "metadata": { 85 | "collapsed": false 86 | }, 87 | "outputs": [ 88 | { 89 | "name": "stdout", 90 | "output_type": "stream", 91 | "text": [ 92 | "(0, 1, 4, 8) [ 5 1 4 -10]\n", 93 | "(1, 2, 6, 7) [ 1 -9 7 1]\n", 94 | "(1, 3, 4, 7) [ 1 -6 4 1]\n", 95 | "(0, 3, 6, 9) [ 5 -6 7 -6]\n", 96 | "(0, 4, 7, 8) [ 5 4 1 -10]\n", 97 | "(1, 4, 7, 9) [ 1 4 1 -6]\n" 98 | ] 99 | } 100 | ], 101 | "source": [ 102 | "for index in sum4(data):\n", 103 | " print(index, data[list(index)])" 104 | ] 105 | }, 106 | { 107 | "cell_type": "code", 108 | "execution_count": null, 109 | "metadata": { 110 | "collapsed": true 111 | }, 112 | "outputs": [], 113 | "source": [] 114 | } 115 | ], 116 | "metadata": { 117 | "kernelspec": { 118 | "display_name": "Python 3", 119 | "language": "python", 120 | "name": "python3" 121 | }, 122 | "language_info": { 123 | "codemirror_mode": { 124 | "name": "ipython", 125 | "version": 3 126 | }, 127 | "file_extension": ".py", 128 | "mimetype": "text/x-python", 129 | "name": "python", 130 | "nbconvert_exporter": "python", 131 | "pygments_lexer": "ipython3", 132 | "version": "3.6.0" 133 | } 134 | }, 135 | "nbformat": 4, 136 | "nbformat_minor": 2 137 | } 138 | -------------------------------------------------------------------------------- /day 29 - string searching.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "## algorithm" 8 | ] 9 | }, 10 | { 11 | "cell_type": "code", 12 | "execution_count": 1, 13 | "metadata": { 14 | "collapsed": true 15 | }, 16 | "outputs": [], 17 | "source": [ 18 | "def search(text, pattern):\n", 19 | " i, k = 0, len(pattern)\n", 20 | " table = {c: k - i for i, c in enumerate(pattern)}\n", 21 | "\n", 22 | " while True:\n", 23 | " print(f'search @ {i}')\n", 24 | " if text[i:i + k] == pattern:\n", 25 | " print(f'FOUND @ {i}')\n", 26 | " if i + k < len(text):\n", 27 | " i += table.get(text[i + k], k + 1)\n", 28 | " else:\n", 29 | " break" 30 | ] 31 | }, 32 | { 33 | "cell_type": "markdown", 34 | "metadata": {}, 35 | "source": [ 36 | "## run" 37 | ] 38 | }, 39 | { 40 | "cell_type": "code", 41 | "execution_count": 2, 42 | "metadata": { 43 | "collapsed": false 44 | }, 45 | "outputs": [ 46 | { 47 | "data": { 48 | "text/plain": [ 49 | "73" 50 | ] 51 | }, 52 | "execution_count": 2, 53 | "metadata": {}, 54 | "output_type": "execute_result" 55 | } 56 | ], 57 | "source": [ 58 | "text = 'A parabolic (or paraboloid or paraboloidal) reflector (or dish or mirror)'\n", 59 | "len(text)" 60 | ] 61 | }, 62 | { 63 | "cell_type": "code", 64 | "execution_count": 3, 65 | "metadata": { 66 | "collapsed": false 67 | }, 68 | "outputs": [ 69 | { 70 | "name": "stdout", 71 | "output_type": "stream", 72 | "text": [ 73 | "search @ 0\n", 74 | "search @ 10\n", 75 | "search @ 20\n", 76 | "search @ 30\n", 77 | "search @ 40\n", 78 | "search @ 44\n", 79 | "FOUND @ 44\n", 80 | "search @ 54\n", 81 | "search @ 56\n", 82 | "search @ 66\n" 83 | ] 84 | } 85 | ], 86 | "source": [ 87 | "search(text, 'reflector')" 88 | ] 89 | }, 90 | { 91 | "cell_type": "code", 92 | "execution_count": 4, 93 | "metadata": { 94 | "collapsed": false 95 | }, 96 | "outputs": [ 97 | { 98 | "name": "stdout", 99 | "output_type": "stream", 100 | "text": [ 101 | "search @ 0\n", 102 | "search @ 6\n", 103 | "search @ 10\n", 104 | "search @ 11\n", 105 | "search @ 17\n", 106 | "search @ 33\n", 107 | "search @ 40\n", 108 | "search @ 44\n", 109 | "search @ 60\n" 110 | ] 111 | } 112 | ], 113 | "source": [ 114 | "search(text, 'not to be found')" 115 | ] 116 | }, 117 | { 118 | "cell_type": "code", 119 | "execution_count": null, 120 | "metadata": { 121 | "collapsed": true 122 | }, 123 | "outputs": [], 124 | "source": [] 125 | } 126 | ], 127 | "metadata": { 128 | "kernelspec": { 129 | "display_name": "Python 3", 130 | "language": "python", 131 | "name": "python3" 132 | }, 133 | "language_info": { 134 | "codemirror_mode": { 135 | "name": "ipython", 136 | "version": 3 137 | }, 138 | "file_extension": ".py", 139 | "mimetype": "text/x-python", 140 | "name": "python", 141 | "nbconvert_exporter": "python", 142 | "pygments_lexer": "ipython3", 143 | "version": "3.6.0" 144 | } 145 | }, 146 | "nbformat": 4, 147 | "nbformat_minor": 2 148 | } 149 | -------------------------------------------------------------------------------- /day 07 - binary addition FSA.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": 1, 6 | "metadata": { 7 | "collapsed": true 8 | }, 9 | "outputs": [], 10 | "source": [ 11 | "from itertools import zip_longest" 12 | ] 13 | }, 14 | { 15 | "cell_type": "markdown", 16 | "metadata": {}, 17 | "source": [ 18 | "## algorithm" 19 | ] 20 | }, 21 | { 22 | "cell_type": "code", 23 | "execution_count": 2, 24 | "metadata": { 25 | "collapsed": false 26 | }, 27 | "outputs": [], 28 | "source": [ 29 | "# states\n", 30 | "p0c0 = 0, {}\n", 31 | "p1c0 = 1, {}\n", 32 | "p0c1 = 0, {}\n", 33 | "p1c1 = 1, {}\n", 34 | "\n", 35 | "# transitions between states\n", 36 | "p0c0[1].update({(0, 0): p0c0, (1, 0): p1c0, (0, 1): p1c0, (1, 1): p0c1})\n", 37 | "p1c0[1].update({(0, 0): p0c0, (1, 0): p1c0, (0, 1): p1c0, (1, 1): p0c1})\n", 38 | "p0c1[1].update({(0, 0): p1c0, (1, 0): p0c1, (0, 1): p0c1, (1, 1): p1c1})\n", 39 | "p1c1[1].update({(0, 0): p1c0, (1, 0): p0c1, (0, 1): p0c1, (1, 1): p1c1})\n", 40 | "\n", 41 | "def add(x, y):\n", 42 | " x = map(int, reversed(x))\n", 43 | " y = map(int, reversed(y))\n", 44 | " z = []\n", 45 | "\n", 46 | " # simulate automaton\n", 47 | " value, transition = p0c0\n", 48 | " for r, s in zip_longest(x, y, fillvalue=0):\n", 49 | " value, transition = transition[r, s]\n", 50 | " z.append(value)\n", 51 | "\n", 52 | " # handle carry\n", 53 | " z.append(transition[0, 0][0])\n", 54 | " \n", 55 | " return ''.join(map(str, reversed(z)))" 56 | ] 57 | }, 58 | { 59 | "cell_type": "markdown", 60 | "metadata": {}, 61 | "source": [ 62 | "## run" 63 | ] 64 | }, 65 | { 66 | "cell_type": "code", 67 | "execution_count": 3, 68 | "metadata": { 69 | "collapsed": false 70 | }, 71 | "outputs": [ 72 | { 73 | "data": { 74 | "text/plain": [ 75 | "'10001000111100'" 76 | ] 77 | }, 78 | "execution_count": 3, 79 | "metadata": {}, 80 | "output_type": "execute_result" 81 | } 82 | ], 83 | "source": [ 84 | "add('1100100100100', '100100011000')" 85 | ] 86 | }, 87 | { 88 | "cell_type": "code", 89 | "execution_count": 4, 90 | "metadata": { 91 | "collapsed": false 92 | }, 93 | "outputs": [ 94 | { 95 | "data": { 96 | "text/plain": [ 97 | "'0b10001000111100'" 98 | ] 99 | }, 100 | "execution_count": 4, 101 | "metadata": {}, 102 | "output_type": "execute_result" 103 | } 104 | ], 105 | "source": [ 106 | "bin(0b1100100100100 + 0b100100011000)" 107 | ] 108 | }, 109 | { 110 | "cell_type": "code", 111 | "execution_count": null, 112 | "metadata": { 113 | "collapsed": true 114 | }, 115 | "outputs": [], 116 | "source": [] 117 | } 118 | ], 119 | "metadata": { 120 | "kernelspec": { 121 | "display_name": "Python 3", 122 | "language": "python", 123 | "name": "python3" 124 | }, 125 | "language_info": { 126 | "codemirror_mode": { 127 | "name": "ipython", 128 | "version": 3 129 | }, 130 | "file_extension": ".py", 131 | "mimetype": "text/x-python", 132 | "name": "python", 133 | "nbconvert_exporter": "python", 134 | "pygments_lexer": "ipython3", 135 | "version": "3.6.0" 136 | } 137 | }, 138 | "nbformat": 4, 139 | "nbformat_minor": 2 140 | } 141 | -------------------------------------------------------------------------------- /day 02 - matrix chain multiplication.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "## algorithm" 8 | ] 9 | }, 10 | { 11 | "cell_type": "code", 12 | "execution_count": 1, 13 | "metadata": { 14 | "collapsed": false 15 | }, 16 | "outputs": [], 17 | "source": [ 18 | "def mult(chain):\n", 19 | " n = len(chain)\n", 20 | " \n", 21 | " # single matrix chain has zero cost\n", 22 | " aux = {(i, i): (0,) + chain[i] for i in range(n)}\n", 23 | "\n", 24 | " # i: length of subchain\n", 25 | " for i in range(1, n):\n", 26 | " # j: starting index of subchain\n", 27 | " for j in range(0, n - i):\n", 28 | " best = float('inf')\n", 29 | "\n", 30 | " # k: splitting point of subchain\n", 31 | " for k in range(j, j + i):\n", 32 | " # multiply subchains at splitting point\n", 33 | " lcost, lname, lrow, lcol = aux[j, k]\n", 34 | " rcost, rname, rrow, rcol = aux[k + 1, j + i]\n", 35 | " cost = lcost + rcost + lrow * lcol * rcol\n", 36 | " var = '(%s%s)' % (lname, rname)\n", 37 | "\n", 38 | " # pick the best one\n", 39 | " if cost < best:\n", 40 | " best = cost\n", 41 | " aux[j, j + i] = cost, var, lrow, rcol\n", 42 | "\n", 43 | " return dict(zip(['cost', 'order', 'rows', 'cols'], aux[0, n - 1]))" 44 | ] 45 | }, 46 | { 47 | "cell_type": "markdown", 48 | "metadata": {}, 49 | "source": [ 50 | "## run" 51 | ] 52 | }, 53 | { 54 | "cell_type": "code", 55 | "execution_count": 2, 56 | "metadata": { 57 | "collapsed": false 58 | }, 59 | "outputs": [ 60 | { 61 | "data": { 62 | "text/plain": [ 63 | "{'cols': 40, 'cost': 18000, 'order': '((AB)C)', 'rows': 10}" 64 | ] 65 | }, 66 | "execution_count": 2, 67 | "metadata": {}, 68 | "output_type": "execute_result" 69 | } 70 | ], 71 | "source": [ 72 | "mult([('A', 10, 20), ('B', 20, 30), ('C', 30, 40)])" 73 | ] 74 | }, 75 | { 76 | "cell_type": "code", 77 | "execution_count": 3, 78 | "metadata": { 79 | "collapsed": false 80 | }, 81 | "outputs": [ 82 | { 83 | "data": { 84 | "text/plain": [ 85 | "{'cols': 1, 'cost': 110, 'order': '(A(B(C(DE))))', 'rows': 10}" 86 | ] 87 | }, 88 | "execution_count": 3, 89 | "metadata": {}, 90 | "output_type": "execute_result" 91 | } 92 | ], 93 | "source": [ 94 | "mult([('A', 10, 5), ('B', 5, 1), ('C', 1, 5), ('D', 5, 10), ('E', 10, 1)])" 95 | ] 96 | }, 97 | { 98 | "cell_type": "code", 99 | "execution_count": null, 100 | "metadata": { 101 | "collapsed": true 102 | }, 103 | "outputs": [], 104 | "source": [] 105 | } 106 | ], 107 | "metadata": { 108 | "kernelspec": { 109 | "display_name": "Python 3", 110 | "language": "python", 111 | "name": "python3" 112 | }, 113 | "language_info": { 114 | "codemirror_mode": { 115 | "name": "ipython", 116 | "version": 3 117 | }, 118 | "file_extension": ".py", 119 | "mimetype": "text/x-python", 120 | "name": "python", 121 | "nbconvert_exporter": "python", 122 | "pygments_lexer": "ipython3", 123 | "version": "3.6.0" 124 | } 125 | }, 126 | "nbformat": 4, 127 | "nbformat_minor": 2 128 | } 129 | -------------------------------------------------------------------------------- /day 14 - huffman codes.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": 1, 6 | "metadata": { 7 | "collapsed": true 8 | }, 9 | "outputs": [], 10 | "source": [ 11 | "from collections import Counter" 12 | ] 13 | }, 14 | { 15 | "cell_type": "markdown", 16 | "metadata": {}, 17 | "source": [ 18 | "## algorithm" 19 | ] 20 | }, 21 | { 22 | "cell_type": "code", 23 | "execution_count": 2, 24 | "metadata": { 25 | "collapsed": true 26 | }, 27 | "outputs": [], 28 | "source": [ 29 | "def find_min(freq):\n", 30 | " item = min(freq, key=lambda i: i[0])\n", 31 | " freq.remove(item)\n", 32 | " return item" 33 | ] 34 | }, 35 | { 36 | "cell_type": "code", 37 | "execution_count": 3, 38 | "metadata": { 39 | "collapsed": false 40 | }, 41 | "outputs": [], 42 | "source": [ 43 | "def huffman_codes(text):\n", 44 | " freq = [(i, x) for x, i in Counter(text).items()]\n", 45 | "\n", 46 | " while len(freq) > 1:\n", 47 | " li, lx = find_min(freq)\n", 48 | " ri, rx = find_min(freq)\n", 49 | " freq.append((li + ri, (lx, rx)))\n", 50 | "\n", 51 | " print_codes(freq.pop()[1])" 52 | ] 53 | }, 54 | { 55 | "cell_type": "code", 56 | "execution_count": 4, 57 | "metadata": { 58 | "collapsed": true 59 | }, 60 | "outputs": [], 61 | "source": [ 62 | "def print_codes(tree, prefix=''):\n", 63 | " if isinstance(tree, tuple):\n", 64 | " print_codes(tree[0], prefix + '0')\n", 65 | " print_codes(tree[1], prefix + '1')\n", 66 | " else:\n", 67 | " print(tree, prefix)" 68 | ] 69 | }, 70 | { 71 | "cell_type": "markdown", 72 | "metadata": {}, 73 | "source": [ 74 | "## run" 75 | ] 76 | }, 77 | { 78 | "cell_type": "code", 79 | "execution_count": 5, 80 | "metadata": { 81 | "collapsed": false 82 | }, 83 | "outputs": [ 84 | { 85 | "name": "stdout", 86 | "output_type": "stream", 87 | "text": [ 88 | "a 0\n", 89 | "b 10\n", 90 | "c 11\n" 91 | ] 92 | } 93 | ], 94 | "source": [ 95 | "huffman_codes('abca')" 96 | ] 97 | }, 98 | { 99 | "cell_type": "code", 100 | "execution_count": 6, 101 | "metadata": { 102 | "collapsed": false 103 | }, 104 | "outputs": [ 105 | { 106 | "name": "stdout", 107 | "output_type": "stream", 108 | "text": [ 109 | "i 000\n", 110 | " 001\n", 111 | "t 01\n", 112 | "l 1000\n", 113 | "v 1001\n", 114 | "s 101\n", 115 | "a 11\n" 116 | ] 117 | } 118 | ], 119 | "source": [ 120 | "huffman_codes('astala vista tasta')" 121 | ] 122 | }, 123 | { 124 | "cell_type": "code", 125 | "execution_count": null, 126 | "metadata": { 127 | "collapsed": true 128 | }, 129 | "outputs": [], 130 | "source": [] 131 | } 132 | ], 133 | "metadata": { 134 | "kernelspec": { 135 | "display_name": "Python 3", 136 | "language": "python", 137 | "name": "python3" 138 | }, 139 | "language_info": { 140 | "codemirror_mode": { 141 | "name": "ipython", 142 | "version": 3 143 | }, 144 | "file_extension": ".py", 145 | "mimetype": "text/x-python", 146 | "name": "python", 147 | "nbconvert_exporter": "python", 148 | "pygments_lexer": "ipython3", 149 | "version": "3.6.0" 150 | } 151 | }, 152 | "nbformat": 4, 153 | "nbformat_minor": 2 154 | } 155 | -------------------------------------------------------------------------------- /day 35 - median.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": 1, 6 | "metadata": { 7 | "collapsed": true 8 | }, 9 | "outputs": [], 10 | "source": [ 11 | "import numpy as np" 12 | ] 13 | }, 14 | { 15 | "cell_type": "markdown", 16 | "metadata": {}, 17 | "source": [ 18 | "## algorithm" 19 | ] 20 | }, 21 | { 22 | "cell_type": "code", 23 | "execution_count": 2, 24 | "metadata": { 25 | "collapsed": false 26 | }, 27 | "outputs": [], 28 | "source": [ 29 | "def kth(items, k, depth=1):\n", 30 | " if len(items) == 1:\n", 31 | " return items[0], depth\n", 32 | "\n", 33 | " # randomize on pivot\n", 34 | " pivot = np.random.choice(items)\n", 35 | " split = np.sum(items <= pivot)\n", 36 | " \n", 37 | " # search partition\n", 38 | " if k < split:\n", 39 | " return kth(items[items <= pivot], k, depth + 1)\n", 40 | " else:\n", 41 | " return kth(items[items > pivot], k - split, depth + 1)" 42 | ] 43 | }, 44 | { 45 | "cell_type": "markdown", 46 | "metadata": {}, 47 | "source": [ 48 | "## run" 49 | ] 50 | }, 51 | { 52 | "cell_type": "code", 53 | "execution_count": 3, 54 | "metadata": { 55 | "collapsed": true 56 | }, 57 | "outputs": [], 58 | "source": [ 59 | "items = np.arange(1000000)\n", 60 | "np.random.shuffle(items)" 61 | ] 62 | }, 63 | { 64 | "cell_type": "code", 65 | "execution_count": 4, 66 | "metadata": { 67 | "collapsed": false 68 | }, 69 | "outputs": [ 70 | { 71 | "data": { 72 | "text/plain": [ 73 | "(500000, 29)" 74 | ] 75 | }, 76 | "execution_count": 4, 77 | "metadata": {}, 78 | "output_type": "execute_result" 79 | } 80 | ], 81 | "source": [ 82 | "kth(items, len(items) // 2)" 83 | ] 84 | }, 85 | { 86 | "cell_type": "code", 87 | "execution_count": 5, 88 | "metadata": { 89 | "collapsed": false 90 | }, 91 | "outputs": [ 92 | { 93 | "data": { 94 | "text/plain": [ 95 | "(0, 14)" 96 | ] 97 | }, 98 | "execution_count": 5, 99 | "metadata": {}, 100 | "output_type": "execute_result" 101 | } 102 | ], 103 | "source": [ 104 | "kth(items, 0)" 105 | ] 106 | }, 107 | { 108 | "cell_type": "code", 109 | "execution_count": 6, 110 | "metadata": { 111 | "collapsed": false 112 | }, 113 | "outputs": [ 114 | { 115 | "data": { 116 | "text/plain": [ 117 | "(999999, 16)" 118 | ] 119 | }, 120 | "execution_count": 6, 121 | "metadata": {}, 122 | "output_type": "execute_result" 123 | } 124 | ], 125 | "source": [ 126 | "kth(items, len(items) - 1)" 127 | ] 128 | }, 129 | { 130 | "cell_type": "code", 131 | "execution_count": null, 132 | "metadata": { 133 | "collapsed": true 134 | }, 135 | "outputs": [], 136 | "source": [] 137 | } 138 | ], 139 | "metadata": { 140 | "kernelspec": { 141 | "display_name": "Python 3", 142 | "language": "python", 143 | "name": "python3" 144 | }, 145 | "language_info": { 146 | "codemirror_mode": { 147 | "name": "ipython", 148 | "version": 3 149 | }, 150 | "file_extension": ".py", 151 | "mimetype": "text/x-python", 152 | "name": "python", 153 | "nbconvert_exporter": "python", 154 | "pygments_lexer": "ipython3", 155 | "version": "3.6.0" 156 | } 157 | }, 158 | "nbformat": 4, 159 | "nbformat_minor": 2 160 | } 161 | -------------------------------------------------------------------------------- /day 03 - next permutation.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "## algorithm" 8 | ] 9 | }, 10 | { 11 | "cell_type": "code", 12 | "execution_count": 1, 13 | "metadata": { 14 | "collapsed": false 15 | }, 16 | "outputs": [], 17 | "source": [ 18 | "def permute(values):\n", 19 | " n = len(values)\n", 20 | " \n", 21 | " # i: position of pivot\n", 22 | " for i in reversed(range(n - 1)):\n", 23 | " if values[i] < values[i + 1]:\n", 24 | " break\n", 25 | " else:\n", 26 | " # very last permutation\n", 27 | " values[:] = reversed(values[:])\n", 28 | " return values\n", 29 | " \n", 30 | " # j: position of the next candidate\n", 31 | " for j in reversed(range(i, n)):\n", 32 | " if values[i] < values[j]:\n", 33 | " # swap pivot and reverse the tail\n", 34 | " values[i], values[j] = values[j], values[i]\n", 35 | " values[i + 1:] = reversed(values[i + 1:])\n", 36 | " break\n", 37 | " \n", 38 | " return values" 39 | ] 40 | }, 41 | { 42 | "cell_type": "markdown", 43 | "metadata": {}, 44 | "source": [ 45 | "## run" 46 | ] 47 | }, 48 | { 49 | "cell_type": "code", 50 | "execution_count": 2, 51 | "metadata": { 52 | "collapsed": false 53 | }, 54 | "outputs": [ 55 | { 56 | "name": "stdout", 57 | "output_type": "stream", 58 | "text": [ 59 | "[1, 2, 3, 4]\n", 60 | "[1, 2, 4, 3]\n", 61 | "[1, 3, 2, 4]\n", 62 | "[1, 3, 4, 2]\n", 63 | "[1, 4, 2, 3]\n", 64 | "[1, 4, 3, 2]\n", 65 | "[2, 1, 3, 4]\n", 66 | "[2, 1, 4, 3]\n", 67 | "[2, 3, 1, 4]\n", 68 | "[2, 3, 4, 1]\n", 69 | "[2, 4, 1, 3]\n", 70 | "[2, 4, 3, 1]\n", 71 | "[3, 1, 2, 4]\n", 72 | "[3, 1, 4, 2]\n", 73 | "[3, 2, 1, 4]\n", 74 | "[3, 2, 4, 1]\n", 75 | "[3, 4, 1, 2]\n", 76 | "[3, 4, 2, 1]\n", 77 | "[4, 1, 2, 3]\n", 78 | "[4, 1, 3, 2]\n", 79 | "[4, 2, 1, 3]\n", 80 | "[4, 2, 3, 1]\n", 81 | "[4, 3, 1, 2]\n", 82 | "[4, 3, 2, 1]\n", 83 | "[1, 2, 3, 4]\n" 84 | ] 85 | } 86 | ], 87 | "source": [ 88 | "x = [4, 3, 2, 1]\n", 89 | "for i in range(25):\n", 90 | " print(permute(x))" 91 | ] 92 | }, 93 | { 94 | "cell_type": "code", 95 | "execution_count": 3, 96 | "metadata": { 97 | "collapsed": false 98 | }, 99 | "outputs": [ 100 | { 101 | "data": { 102 | "text/plain": [ 103 | "['F', 'A', 'E', 'D']" 104 | ] 105 | }, 106 | "execution_count": 3, 107 | "metadata": {}, 108 | "output_type": "execute_result" 109 | } 110 | ], 111 | "source": [ 112 | "permute(list('FADE'))" 113 | ] 114 | }, 115 | { 116 | "cell_type": "code", 117 | "execution_count": null, 118 | "metadata": { 119 | "collapsed": true 120 | }, 121 | "outputs": [], 122 | "source": [] 123 | } 124 | ], 125 | "metadata": { 126 | "kernelspec": { 127 | "display_name": "Python 3", 128 | "language": "python", 129 | "name": "python3" 130 | }, 131 | "language_info": { 132 | "codemirror_mode": { 133 | "name": "ipython", 134 | "version": 3 135 | }, 136 | "file_extension": ".py", 137 | "mimetype": "text/x-python", 138 | "name": "python", 139 | "nbconvert_exporter": "python", 140 | "pygments_lexer": "ipython3", 141 | "version": "3.6.0" 142 | } 143 | }, 144 | "nbformat": 4, 145 | "nbformat_minor": 2 146 | } 147 | -------------------------------------------------------------------------------- /day 12 - roots of polynomial.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": 1, 6 | "metadata": { 7 | "collapsed": true 8 | }, 9 | "outputs": [], 10 | "source": [ 11 | "import numpy as np" 12 | ] 13 | }, 14 | { 15 | "cell_type": "markdown", 16 | "metadata": {}, 17 | "source": [ 18 | "## algorithm" 19 | ] 20 | }, 21 | { 22 | "cell_type": "code", 23 | "execution_count": 2, 24 | "metadata": { 25 | "collapsed": false 26 | }, 27 | "outputs": [], 28 | "source": [ 29 | "def roots(*coeffs):\n", 30 | " matrix = np.eye(len(coeffs) - 1, k=-1)\n", 31 | " matrix[:,-1] = np.array(coeffs[:0:-1]) / -coeffs[0]\n", 32 | " return np.linalg.eigvals(matrix)" 33 | ] 34 | }, 35 | { 36 | "cell_type": "markdown", 37 | "metadata": {}, 38 | "source": [ 39 | "## run" 40 | ] 41 | }, 42 | { 43 | "cell_type": "code", 44 | "execution_count": 3, 45 | "metadata": { 46 | "collapsed": false 47 | }, 48 | "outputs": [ 49 | { 50 | "data": { 51 | "text/plain": [ 52 | "array([ 0.1])" 53 | ] 54 | }, 55 | "execution_count": 3, 56 | "metadata": {}, 57 | "output_type": "execute_result" 58 | } 59 | ], 60 | "source": [ 61 | "# 10x - 1 = 0\n", 62 | "roots(10, -1)" 63 | ] 64 | }, 65 | { 66 | "cell_type": "code", 67 | "execution_count": 4, 68 | "metadata": { 69 | "collapsed": false 70 | }, 71 | "outputs": [ 72 | { 73 | "data": { 74 | "text/plain": [ 75 | "array([ 1., 1.])" 76 | ] 77 | }, 78 | "execution_count": 4, 79 | "metadata": {}, 80 | "output_type": "execute_result" 81 | } 82 | ], 83 | "source": [ 84 | "# x^2 - 2x + 1 = 0\n", 85 | "roots(1, -2, 1)" 86 | ] 87 | }, 88 | { 89 | "cell_type": "code", 90 | "execution_count": 5, 91 | "metadata": { 92 | "collapsed": false 93 | }, 94 | "outputs": [ 95 | { 96 | "data": { 97 | "text/plain": [ 98 | "array([ 3., -3.])" 99 | ] 100 | }, 101 | "execution_count": 5, 102 | "metadata": {}, 103 | "output_type": "execute_result" 104 | } 105 | ], 106 | "source": [ 107 | "# 2x^2 - 18 = 0\n", 108 | "roots(2, 0, -18)" 109 | ] 110 | }, 111 | { 112 | "cell_type": "code", 113 | "execution_count": 6, 114 | "metadata": { 115 | "collapsed": false 116 | }, 117 | "outputs": [ 118 | { 119 | "data": { 120 | "text/plain": [ 121 | "array([ 0.5+0.8660254j, 0.5-0.8660254j, -1.0+0.j , -0.5+0.8660254j,\n", 122 | " -0.5-0.8660254j])" 123 | ] 124 | }, 125 | "execution_count": 6, 126 | "metadata": {}, 127 | "output_type": "execute_result" 128 | } 129 | ], 130 | "source": [ 131 | "# x^5 + x^4 + x^3 + x^2 + x + 1 = 0\n", 132 | "roots(1, 1, 1, 1, 1, 1)" 133 | ] 134 | }, 135 | { 136 | "cell_type": "code", 137 | "execution_count": null, 138 | "metadata": { 139 | "collapsed": true 140 | }, 141 | "outputs": [], 142 | "source": [] 143 | } 144 | ], 145 | "metadata": { 146 | "kernelspec": { 147 | "display_name": "Python 3", 148 | "language": "python", 149 | "name": "python3" 150 | }, 151 | "language_info": { 152 | "codemirror_mode": { 153 | "name": "ipython", 154 | "version": 3 155 | }, 156 | "file_extension": ".py", 157 | "mimetype": "text/x-python", 158 | "name": "python", 159 | "nbconvert_exporter": "python", 160 | "pygments_lexer": "ipython3", 161 | "version": "3.6.0" 162 | } 163 | }, 164 | "nbformat": 4, 165 | "nbformat_minor": 2 166 | } 167 | -------------------------------------------------------------------------------- /day 13 - extended euclidean algorithm.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "## algorithm" 8 | ] 9 | }, 10 | { 11 | "cell_type": "code", 12 | "execution_count": 1, 13 | "metadata": { 14 | "collapsed": false 15 | }, 16 | "outputs": [], 17 | "source": [ 18 | "def gcd(x, y):\n", 19 | " u0, v0 = 1, 0\n", 20 | " u1, v1 = 0, 1\n", 21 | " while y:\n", 22 | " q = x // y\n", 23 | " u0, u1 = u1, u0 - q * u1\n", 24 | " v0, v1 = v1, v0 - q * v1\n", 25 | " x, y = y, x % y\n", 26 | " return x, u0, v0" 27 | ] 28 | }, 29 | { 30 | "cell_type": "markdown", 31 | "metadata": {}, 32 | "source": [ 33 | "## run" 34 | ] 35 | }, 36 | { 37 | "cell_type": "code", 38 | "execution_count": 2, 39 | "metadata": { 40 | "collapsed": false 41 | }, 42 | "outputs": [ 43 | { 44 | "data": { 45 | "text/plain": [ 46 | "(1, 3, -2)" 47 | ] 48 | }, 49 | "execution_count": 2, 50 | "metadata": {}, 51 | "output_type": "execute_result" 52 | } 53 | ], 54 | "source": [ 55 | "gcd(5, 7)" 56 | ] 57 | }, 58 | { 59 | "cell_type": "code", 60 | "execution_count": 3, 61 | "metadata": { 62 | "collapsed": false 63 | }, 64 | "outputs": [ 65 | { 66 | "data": { 67 | "text/plain": [ 68 | "(18, -9, 40)" 69 | ] 70 | }, 71 | "execution_count": 3, 72 | "metadata": {}, 73 | "output_type": "execute_result" 74 | } 75 | ], 76 | "source": [ 77 | "gcd(2*3*7*9*11, 6*12*13)" 78 | ] 79 | }, 80 | { 81 | "cell_type": "code", 82 | "execution_count": 4, 83 | "metadata": { 84 | "collapsed": false 85 | }, 86 | "outputs": [ 87 | { 88 | "data": { 89 | "text/plain": [ 90 | "(6, -1351389, 189739)" 91 | ] 92 | }, 93 | "execution_count": 4, 94 | "metadata": {}, 95 | "output_type": "execute_result" 96 | } 97 | ], 98 | "source": [ 99 | "gcd(32423940, 230934894)" 100 | ] 101 | }, 102 | { 103 | "cell_type": "code", 104 | "execution_count": 5, 105 | "metadata": { 106 | "collapsed": false 107 | }, 108 | "outputs": [ 109 | { 110 | "data": { 111 | "text/plain": [ 112 | "(50, 1, -1)" 113 | ] 114 | }, 115 | "execution_count": 5, 116 | "metadata": {}, 117 | "output_type": "execute_result" 118 | } 119 | ], 120 | "source": [ 121 | "gcd(150, 100)" 122 | ] 123 | }, 124 | { 125 | "cell_type": "code", 126 | "execution_count": 6, 127 | "metadata": { 128 | "collapsed": false 129 | }, 130 | "outputs": [ 131 | { 132 | "data": { 133 | "text/plain": [ 134 | "(1, -49, 74)" 135 | ] 136 | }, 137 | "execution_count": 6, 138 | "metadata": {}, 139 | "output_type": "execute_result" 140 | } 141 | ], 142 | "source": [ 143 | "gcd(151, 100)" 144 | ] 145 | }, 146 | { 147 | "cell_type": "code", 148 | "execution_count": null, 149 | "metadata": { 150 | "collapsed": true 151 | }, 152 | "outputs": [], 153 | "source": [] 154 | } 155 | ], 156 | "metadata": { 157 | "kernelspec": { 158 | "display_name": "Python 3", 159 | "language": "python", 160 | "name": "python3" 161 | }, 162 | "language_info": { 163 | "codemirror_mode": { 164 | "name": "ipython", 165 | "version": 3 166 | }, 167 | "file_extension": ".py", 168 | "mimetype": "text/x-python", 169 | "name": "python", 170 | "nbconvert_exporter": "python", 171 | "pygments_lexer": "ipython3", 172 | "version": "3.6.0" 173 | } 174 | }, 175 | "nbformat": 4, 176 | "nbformat_minor": 2 177 | } 178 | -------------------------------------------------------------------------------- /day 57 - quicksort.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": 1, 6 | "metadata": { 7 | "collapsed": true 8 | }, 9 | "outputs": [], 10 | "source": [ 11 | "import numpy as np" 12 | ] 13 | }, 14 | { 15 | "cell_type": "markdown", 16 | "metadata": {}, 17 | "source": [ 18 | "## algorithm" 19 | ] 20 | }, 21 | { 22 | "cell_type": "code", 23 | "execution_count": 2, 24 | "metadata": { 25 | "collapsed": true 26 | }, 27 | "outputs": [], 28 | "source": [ 29 | "def swap(data, i, j):\n", 30 | " data[i], data[j] = data[j], data[i]" 31 | ] 32 | }, 33 | { 34 | "cell_type": "code", 35 | "execution_count": 3, 36 | "metadata": { 37 | "collapsed": true 38 | }, 39 | "outputs": [], 40 | "source": [ 41 | "def qsort3(data, left, right):\n", 42 | " # sorted\n", 43 | " if left >= right:\n", 44 | " return\n", 45 | "\n", 46 | " # select pivot\n", 47 | " i = np.random.randint(left, right + 1)\n", 48 | " swap(data, left, i)\n", 49 | " pivot = data[left]\n", 50 | "\n", 51 | " # i ~ points behind left partition\n", 52 | " # j ~ points ahead of right partition\n", 53 | " # k ~ current element\n", 54 | " i, j, k = left, right, left + 1\n", 55 | "\n", 56 | " # split to [left] + [pivot] + [right]\n", 57 | " while k <= j:\n", 58 | " if data[k] < pivot:\n", 59 | " swap(data, i, k)\n", 60 | " i += 1\n", 61 | " elif data[k] > pivot:\n", 62 | " swap(data, j, k)\n", 63 | " j -= 1\n", 64 | " k -= 1\n", 65 | " k += 1\n", 66 | "\n", 67 | " # recursion\n", 68 | " qsort3(data, left, i - 1)\n", 69 | " qsort3(data, j + 1, right)" 70 | ] 71 | }, 72 | { 73 | "cell_type": "code", 74 | "execution_count": 4, 75 | "metadata": { 76 | "collapsed": true 77 | }, 78 | "outputs": [], 79 | "source": [ 80 | "def qsort(data):\n", 81 | " qsort3(data, 0, len(data) - 1)" 82 | ] 83 | }, 84 | { 85 | "cell_type": "markdown", 86 | "metadata": {}, 87 | "source": [ 88 | "## run" 89 | ] 90 | }, 91 | { 92 | "cell_type": "code", 93 | "execution_count": 5, 94 | "metadata": { 95 | "collapsed": false 96 | }, 97 | "outputs": [ 98 | { 99 | "name": "stdout", 100 | "output_type": "stream", 101 | "text": [ 102 | "[6 1 7 9 9 9 9 8 7 6 9 9 6 3 5 4 1 8 1 7 0 1 9 3 1 0 3 2 4 3 1 7 6 0 2 7 0\n", 103 | " 7 9 1 0 4 9 2 3 4 5 9 5 8 9 1 8 2 0 5 4 9 5 3 1 0 1 1 2 3 8 1 4 2 2 4 7 9\n", 104 | " 3 0 0 4 9 3 0 7 0 8 5 8 3 5 9 6 7 6 5 9 3 4 0 1 0 7]\n" 105 | ] 106 | } 107 | ], 108 | "source": [ 109 | "data = np.random.randint(0, 10, 100)\n", 110 | "print(data)" 111 | ] 112 | }, 113 | { 114 | "cell_type": "code", 115 | "execution_count": 6, 116 | "metadata": { 117 | "collapsed": false 118 | }, 119 | "outputs": [ 120 | { 121 | "name": "stdout", 122 | "output_type": "stream", 123 | "text": [ 124 | "[0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 3 3 3 3\n", 125 | " 3 3 3 3 3 3 3 4 4 4 4 4 4 4 4 4 5 5 5 5 5 5 5 5 6 6 6 6 6 6 7 7 7 7 7 7 7\n", 126 | " 7 7 7 8 8 8 8 8 8 8 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9]\n" 127 | ] 128 | } 129 | ], 130 | "source": [ 131 | "qsort(data)\n", 132 | "print(data)" 133 | ] 134 | }, 135 | { 136 | "cell_type": "code", 137 | "execution_count": null, 138 | "metadata": { 139 | "collapsed": true 140 | }, 141 | "outputs": [], 142 | "source": [] 143 | } 144 | ], 145 | "metadata": { 146 | "kernelspec": { 147 | "display_name": "Python 3", 148 | "language": "python", 149 | "name": "python3" 150 | }, 151 | "language_info": { 152 | "codemirror_mode": { 153 | "name": "ipython", 154 | "version": 3 155 | }, 156 | "file_extension": ".py", 157 | "mimetype": "text/x-python", 158 | "name": "python", 159 | "nbconvert_exporter": "python", 160 | "pygments_lexer": "ipython3", 161 | "version": "3.6.0" 162 | } 163 | }, 164 | "nbformat": 4, 165 | "nbformat_minor": 2 166 | } 167 | -------------------------------------------------------------------------------- /day 26 - karger's mincut.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": 1, 6 | "metadata": { 7 | "collapsed": true 8 | }, 9 | "outputs": [], 10 | "source": [ 11 | "from random import choice\n", 12 | "from itertools import combinations" 13 | ] 14 | }, 15 | { 16 | "cell_type": "markdown", 17 | "metadata": {}, 18 | "source": [ 19 | "## algorithm" 20 | ] 21 | }, 22 | { 23 | "cell_type": "code", 24 | "execution_count": 2, 25 | "metadata": { 26 | "collapsed": false 27 | }, 28 | "outputs": [], 29 | "source": [ 30 | "def contract(graph, u, v):\n", 31 | " aux, w = [], f'{u},{v}'\n", 32 | " for x, y in graph:\n", 33 | " x = w if x in [u, v] else x\n", 34 | " y = w if y in [u, v] else y\n", 35 | " if x < y:\n", 36 | " aux.append((x, y))\n", 37 | " elif x > y:\n", 38 | " aux.append((y, x))\n", 39 | " return aux" 40 | ] 41 | }, 42 | { 43 | "cell_type": "code", 44 | "execution_count": 3, 45 | "metadata": { 46 | "collapsed": false 47 | }, 48 | "outputs": [], 49 | "source": [ 50 | "def mincut(graph, n):\n", 51 | " components, cost = ['', ''], float('inf')\n", 52 | " \n", 53 | " # n^2 attempts\n", 54 | " for i in range(n * n):\n", 55 | " aux = graph\n", 56 | " \n", 57 | " # remove edges one by one\n", 58 | " while len(set(aux)) > 1:\n", 59 | " aux = contract(aux, *choice(aux))\n", 60 | " \n", 61 | " # min cut so far\n", 62 | " if len(aux) < cost:\n", 63 | " components, cost = aux[0], len(aux)\n", 64 | " \n", 65 | " return components, cost" 66 | ] 67 | }, 68 | { 69 | "cell_type": "markdown", 70 | "metadata": {}, 71 | "source": [ 72 | "## generate graph" 73 | ] 74 | }, 75 | { 76 | "cell_type": "code", 77 | "execution_count": 4, 78 | "metadata": { 79 | "collapsed": false 80 | }, 81 | "outputs": [], 82 | "source": [ 83 | "# fully connected\n", 84 | "nodes_a = [f'A{i}' for i in range(20)]\n", 85 | "graph_a = [(u, v) for u, v in combinations(nodes_a, 2)]\n", 86 | "\n", 87 | "# fully connected\n", 88 | "nodes_b = [f'B{i}' for i in range(20)]\n", 89 | "graph_b = [(u, v) for u, v in combinations(nodes_b, 2)]\n", 90 | "\n", 91 | "# interconnections\n", 92 | "graph_c = [(choice(nodes_a), choice(nodes_b)) for i in range(10)]\n", 93 | "\n", 94 | "graph = graph_a + graph_b + graph_c" 95 | ] 96 | }, 97 | { 98 | "cell_type": "markdown", 99 | "metadata": {}, 100 | "source": [ 101 | "## run" 102 | ] 103 | }, 104 | { 105 | "cell_type": "code", 106 | "execution_count": 5, 107 | "metadata": { 108 | "collapsed": false 109 | }, 110 | "outputs": [ 111 | { 112 | "name": "stdout", 113 | "output_type": "stream", 114 | "text": [ 115 | "best cut: 10\n", 116 | "component #1: A0,A3,A4,A7,A9,A16,A19,A2,A1,A5,A12,A18,A17,A8,A15,A13,A6,A10,A11,A14\n", 117 | "component #2: B0,B1,B16,B12,B15,B4,B17,B19,B9,B3,B5,B14,B18,B2,B11,B8,B10,B7,B6,B13\n" 118 | ] 119 | } 120 | ], 121 | "source": [ 122 | "components, cost = mincut(graph, 40)\n", 123 | "print('best cut:', cost)\n", 124 | "print('component #1:', components[0])\n", 125 | "print('component #2:', components[1])" 126 | ] 127 | }, 128 | { 129 | "cell_type": "code", 130 | "execution_count": null, 131 | "metadata": { 132 | "collapsed": true 133 | }, 134 | "outputs": [], 135 | "source": [] 136 | } 137 | ], 138 | "metadata": { 139 | "kernelspec": { 140 | "display_name": "Python 3", 141 | "language": "python", 142 | "name": "python3" 143 | }, 144 | "language_info": { 145 | "codemirror_mode": { 146 | "name": "ipython", 147 | "version": 3 148 | }, 149 | "file_extension": ".py", 150 | "mimetype": "text/x-python", 151 | "name": "python", 152 | "nbconvert_exporter": "python", 153 | "pygments_lexer": "ipython3", 154 | "version": "3.6.0" 155 | } 156 | }, 157 | "nbformat": 4, 158 | "nbformat_minor": 2 159 | } 160 | -------------------------------------------------------------------------------- /day 74 - google interview question.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": 1, 6 | "metadata": { 7 | "collapsed": true 8 | }, 9 | "outputs": [], 10 | "source": [ 11 | "import numpy as np" 12 | ] 13 | }, 14 | { 15 | "cell_type": "markdown", 16 | "metadata": {}, 17 | "source": [ 18 | "## algorithm" 19 | ] 20 | }, 21 | { 22 | "cell_type": "code", 23 | "execution_count": 2, 24 | "metadata": { 25 | "collapsed": true 26 | }, 27 | "outputs": [], 28 | "source": [ 29 | "def solve_question(trials):\n", 30 | " # range to search in\n", 31 | " probability_range = np.array([0., 1.])\n", 32 | "\n", 33 | " while True:\n", 34 | " # prob. to see car in 10 minutes\n", 35 | " probability_10min = probability_range.mean()\n", 36 | " \n", 37 | " # simulate three 10-minute intervals\n", 38 | " events = np.random.rand(trials, 3) < probability_10min\n", 39 | " events = np.sum(events, axis=1) > 0\n", 40 | "\n", 41 | " # prob. to see car in 30 minutes\n", 42 | " probability_30min = np.mean(events)\n", 43 | " if abs(probability_30min - .95) < 1e-4:\n", 44 | " return probability_10min\n", 45 | "\n", 46 | " # bisection\n", 47 | " i = 0 if probability_30min < .95 else 1\n", 48 | " probability_range[i] = probability_10min" 49 | ] 50 | }, 51 | { 52 | "cell_type": "markdown", 53 | "metadata": {}, 54 | "source": [ 55 | "## run" 56 | ] 57 | }, 58 | { 59 | "cell_type": "code", 60 | "execution_count": 3, 61 | "metadata": { 62 | "collapsed": false 63 | }, 64 | "outputs": [ 65 | { 66 | "data": { 67 | "text/plain": [ 68 | "0.6318359375" 69 | ] 70 | }, 71 | "execution_count": 3, 72 | "metadata": {}, 73 | "output_type": "execute_result" 74 | } 75 | ], 76 | "source": [ 77 | "solve_question(10**6)" 78 | ] 79 | }, 80 | { 81 | "cell_type": "code", 82 | "execution_count": 4, 83 | "metadata": { 84 | "collapsed": false 85 | }, 86 | "outputs": [ 87 | { 88 | "data": { 89 | "text/plain": [ 90 | "0.6328125" 91 | ] 92 | }, 93 | "execution_count": 4, 94 | "metadata": {}, 95 | "output_type": "execute_result" 96 | } 97 | ], 98 | "source": [ 99 | "solve_question(10**6)" 100 | ] 101 | }, 102 | { 103 | "cell_type": "code", 104 | "execution_count": 5, 105 | "metadata": { 106 | "collapsed": false 107 | }, 108 | "outputs": [ 109 | { 110 | "data": { 111 | "text/plain": [ 112 | "0.63142514228820801" 113 | ] 114 | }, 115 | "execution_count": 5, 116 | "metadata": {}, 117 | "output_type": "execute_result" 118 | } 119 | ], 120 | "source": [ 121 | "solve_question(10**6)" 122 | ] 123 | }, 124 | { 125 | "cell_type": "markdown", 126 | "metadata": {}, 127 | "source": [ 128 | "expected result" 129 | ] 130 | }, 131 | { 132 | "cell_type": "code", 133 | "execution_count": 6, 134 | "metadata": { 135 | "collapsed": false 136 | }, 137 | "outputs": [ 138 | { 139 | "data": { 140 | "text/plain": [ 141 | "0.6315968501359612" 142 | ] 143 | }, 144 | "execution_count": 6, 145 | "metadata": {}, 146 | "output_type": "execute_result" 147 | } 148 | ], 149 | "source": [ 150 | "1 - pow(0.05, 1/3)" 151 | ] 152 | }, 153 | { 154 | "cell_type": "code", 155 | "execution_count": null, 156 | "metadata": { 157 | "collapsed": true 158 | }, 159 | "outputs": [], 160 | "source": [] 161 | } 162 | ], 163 | "metadata": { 164 | "kernelspec": { 165 | "display_name": "Python 3", 166 | "language": "python", 167 | "name": "python3" 168 | }, 169 | "language_info": { 170 | "codemirror_mode": { 171 | "name": "ipython", 172 | "version": 3 173 | }, 174 | "file_extension": ".py", 175 | "mimetype": "text/x-python", 176 | "name": "python", 177 | "nbconvert_exporter": "python", 178 | "pygments_lexer": "ipython3", 179 | "version": "3.6.0" 180 | } 181 | }, 182 | "nbformat": 4, 183 | "nbformat_minor": 2 184 | } 185 | -------------------------------------------------------------------------------- /day 23 - sudoku.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": 1, 6 | "metadata": { 7 | "collapsed": true 8 | }, 9 | "outputs": [], 10 | "source": [ 11 | "import numpy as np" 12 | ] 13 | }, 14 | { 15 | "cell_type": "markdown", 16 | "metadata": {}, 17 | "source": [ 18 | "## algorithm" 19 | ] 20 | }, 21 | { 22 | "cell_type": "code", 23 | "execution_count": 2, 24 | "metadata": { 25 | "collapsed": true 26 | }, 27 | "outputs": [], 28 | "source": [ 29 | "def sudoku(matrix, n=0):\n", 30 | " if n >= 81:\n", 31 | " return matrix\n", 32 | " if matrix.A1[n]:\n", 33 | " return sudoku(matrix, n + 1)\n", 34 | "\n", 35 | " i, j, k, l = n // 9, n % 9, n // 27 * 3, (n % 9) // 3 * 3\n", 36 | "\n", 37 | " # get viable values\n", 38 | " x = set(range(1, 10)) - (\n", 39 | " set(matrix[i].A1) |\n", 40 | " set(matrix.T[j].A1) |\n", 41 | " set(matrix[k:k + 3, l:l + 3].A1)\n", 42 | " )\n", 43 | "\n", 44 | " # backtracking\n", 45 | " for value in x:\n", 46 | " matrix[i, j] = value\n", 47 | " if sudoku(matrix, n + 1) is not None:\n", 48 | " return matrix\n", 49 | " else:\n", 50 | " matrix[i, j] = 0" 51 | ] 52 | }, 53 | { 54 | "cell_type": "markdown", 55 | "metadata": {}, 56 | "source": [ 57 | "## run" 58 | ] 59 | }, 60 | { 61 | "cell_type": "code", 62 | "execution_count": 3, 63 | "metadata": { 64 | "collapsed": false 65 | }, 66 | "outputs": [ 67 | { 68 | "data": { 69 | "text/plain": [ 70 | "matrix([[8, 2, 4, 1, 3, 9, 5, 7, 6],\n", 71 | " [6, 9, 1, 5, 2, 7, 8, 3, 4],\n", 72 | " [5, 7, 3, 6, 4, 8, 2, 1, 9],\n", 73 | " [4, 6, 5, 3, 8, 1, 7, 9, 2],\n", 74 | " [9, 1, 7, 2, 6, 5, 3, 4, 8],\n", 75 | " [2, 3, 8, 9, 7, 4, 1, 6, 5],\n", 76 | " [3, 8, 2, 7, 9, 6, 4, 5, 1],\n", 77 | " [1, 4, 6, 8, 5, 3, 9, 2, 7],\n", 78 | " [7, 5, 9, 4, 1, 2, 6, 8, 3]])" 79 | ] 80 | }, 81 | "execution_count": 3, 82 | "metadata": {}, 83 | "output_type": "execute_result" 84 | } 85 | ], 86 | "source": [ 87 | "sudoku(np.matrix(\"\"\"\n", 88 | " 8 0 0 1 0 9 0 7 0;\n", 89 | " 0 9 0 0 0 0 8 0 0;\n", 90 | " 5 0 3 0 4 0 0 0 0;\n", 91 | " 0 0 0 0 0 0 7 9 0;\n", 92 | " 0 0 7 2 6 5 3 0 0;\n", 93 | " 0 3 8 0 0 0 0 0 0;\n", 94 | " 0 0 0 0 9 0 4 0 1;\n", 95 | " 0 0 6 0 0 0 0 2 0;\n", 96 | " 0 5 0 4 0 2 0 0 3\n", 97 | "\"\"\"))" 98 | ] 99 | }, 100 | { 101 | "cell_type": "code", 102 | "execution_count": 4, 103 | "metadata": { 104 | "collapsed": false 105 | }, 106 | "outputs": [ 107 | { 108 | "data": { 109 | "text/plain": [ 110 | "matrix([[1, 2, 3, 4, 5, 8, 9, 6, 7],\n", 111 | " [4, 5, 8, 6, 7, 9, 1, 2, 3],\n", 112 | " [9, 6, 7, 1, 2, 3, 8, 4, 5],\n", 113 | " [2, 1, 9, 8, 3, 4, 5, 7, 6],\n", 114 | " [3, 8, 4, 5, 6, 7, 2, 1, 9],\n", 115 | " [5, 7, 6, 9, 1, 2, 3, 8, 4],\n", 116 | " [8, 9, 1, 3, 4, 6, 7, 5, 2],\n", 117 | " [6, 3, 2, 7, 8, 5, 4, 9, 1],\n", 118 | " [7, 4, 5, 2, 9, 1, 6, 3, 8]])" 119 | ] 120 | }, 121 | "execution_count": 4, 122 | "metadata": {}, 123 | "output_type": "execute_result" 124 | } 125 | ], 126 | "source": [ 127 | "sudoku(np.matrix(np.zeros((9, 9), dtype=int)))" 128 | ] 129 | }, 130 | { 131 | "cell_type": "code", 132 | "execution_count": null, 133 | "metadata": { 134 | "collapsed": true 135 | }, 136 | "outputs": [], 137 | "source": [] 138 | } 139 | ], 140 | "metadata": { 141 | "kernelspec": { 142 | "display_name": "Python 3", 143 | "language": "python", 144 | "name": "python3" 145 | }, 146 | "language_info": { 147 | "codemirror_mode": { 148 | "name": "ipython", 149 | "version": 3 150 | }, 151 | "file_extension": ".py", 152 | "mimetype": "text/x-python", 153 | "name": "python", 154 | "nbconvert_exporter": "python", 155 | "pygments_lexer": "ipython3", 156 | "version": "3.6.0" 157 | } 158 | }, 159 | "nbformat": 4, 160 | "nbformat_minor": 2 161 | } 162 | -------------------------------------------------------------------------------- /day 70 - deadlock.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": 1, 6 | "metadata": { 7 | "collapsed": true 8 | }, 9 | "outputs": [], 10 | "source": [ 11 | "from collections import defaultdict\n", 12 | "from time import sleep\n", 13 | "from threading import Thread, Lock" 14 | ] 15 | }, 16 | { 17 | "cell_type": "markdown", 18 | "metadata": {}, 19 | "source": [ 20 | "## algorithm" 21 | ] 22 | }, 23 | { 24 | "cell_type": "code", 25 | "execution_count": 2, 26 | "metadata": { 27 | "collapsed": true 28 | }, 29 | "outputs": [], 30 | "source": [ 31 | "class SharedState:\n", 32 | "\n", 33 | " def __init__(self, n):\n", 34 | " self._lock = Lock()\n", 35 | " self._state = defaultdict(int)\n", 36 | " self._resources = [Lock() for _ in range(n)]\n", 37 | "\n", 38 | " def atomic(self, key, value=0):\n", 39 | " with self._lock:\n", 40 | " self._state[key] += value\n", 41 | " return self._state[key]\n", 42 | "\n", 43 | " def resource(self, i):\n", 44 | " return self._resources[i]\n", 45 | "\n", 46 | " def kill(self):\n", 47 | " resources = self._resources\n", 48 | " self._resources = None\n", 49 | " for i in resources:\n", 50 | " i.release()" 51 | ] 52 | }, 53 | { 54 | "cell_type": "code", 55 | "execution_count": 3, 56 | "metadata": { 57 | "collapsed": true 58 | }, 59 | "outputs": [], 60 | "source": [ 61 | "def worker(pid, state):\n", 62 | " try:\n", 63 | " while True:\n", 64 | " state.atomic('waiting', 1)\n", 65 | " with state.resource(pid):\n", 66 | " state.atomic('waiting', 1)\n", 67 | " with state.resource(pid - 1):\n", 68 | " state.atomic('waiting', -2)\n", 69 | " state.atomic('tasks', 1)\n", 70 | "\n", 71 | " except RuntimeError:\n", 72 | " pass" 73 | ] 74 | }, 75 | { 76 | "cell_type": "code", 77 | "execution_count": 4, 78 | "metadata": { 79 | "collapsed": true 80 | }, 81 | "outputs": [], 82 | "source": [ 83 | "def deadlock(n):\n", 84 | " state = SharedState(n)\n", 85 | "\n", 86 | " for i in range(n):\n", 87 | " Thread(target=worker, args=(i, state)).start()\n", 88 | "\n", 89 | " while state.atomic('waiting') < 2 * n:\n", 90 | " sleep(1)\n", 91 | "\n", 92 | " print(n, 'workers; deadlock after', state.atomic('tasks'), 'tasks')\n", 93 | " state.kill()" 94 | ] 95 | }, 96 | { 97 | "cell_type": "markdown", 98 | "metadata": {}, 99 | "source": [ 100 | "## run" 101 | ] 102 | }, 103 | { 104 | "cell_type": "code", 105 | "execution_count": 5, 106 | "metadata": { 107 | "collapsed": false 108 | }, 109 | "outputs": [ 110 | { 111 | "name": "stdout", 112 | "output_type": "stream", 113 | "text": [ 114 | "10 workers; deadlock after 19935 tasks\n", 115 | "20 workers; deadlock after 36262 tasks\n", 116 | "30 workers; deadlock after 77059 tasks\n", 117 | "40 workers; deadlock after 15107 tasks\n", 118 | "50 workers; deadlock after 43405 tasks\n", 119 | "60 workers; deadlock after 9465 tasks\n", 120 | "70 workers; deadlock after 78949 tasks\n", 121 | "80 workers; deadlock after 10051 tasks\n", 122 | "90 workers; deadlock after 14169 tasks\n" 123 | ] 124 | } 125 | ], 126 | "source": [ 127 | "for i in range(1, 10):\n", 128 | " deadlock(10 * i)" 129 | ] 130 | }, 131 | { 132 | "cell_type": "code", 133 | "execution_count": null, 134 | "metadata": { 135 | "collapsed": true 136 | }, 137 | "outputs": [], 138 | "source": [] 139 | } 140 | ], 141 | "metadata": { 142 | "kernelspec": { 143 | "display_name": "Python 3", 144 | "language": "python", 145 | "name": "python3" 146 | }, 147 | "language_info": { 148 | "codemirror_mode": { 149 | "name": "ipython", 150 | "version": 3 151 | }, 152 | "file_extension": ".py", 153 | "mimetype": "text/x-python", 154 | "name": "python", 155 | "nbconvert_exporter": "python", 156 | "pygments_lexer": "ipython3", 157 | "version": "3.6.0" 158 | } 159 | }, 160 | "nbformat": 4, 161 | "nbformat_minor": 2 162 | } 163 | -------------------------------------------------------------------------------- /day 40 - counting ones.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": 1, 6 | "metadata": { 7 | "collapsed": true 8 | }, 9 | "outputs": [], 10 | "source": [ 11 | "import numpy as np\n", 12 | "from collections import defaultdict\n", 13 | "from itertools import count" 14 | ] 15 | }, 16 | { 17 | "cell_type": "markdown", 18 | "metadata": {}, 19 | "source": [ 20 | "## algorithm" 21 | ] 22 | }, 23 | { 24 | "cell_type": "code", 25 | "execution_count": 2, 26 | "metadata": { 27 | "collapsed": true 28 | }, 29 | "outputs": [], 30 | "source": [ 31 | "def stream_counter():\n", 32 | " bucket = defaultdict(list)\n", 33 | " timestamp = count(1)\n", 34 | " estimate = None\n", 35 | "\n", 36 | " while True:\n", 37 | " code = yield estimate\n", 38 | " estimate = None\n", 39 | "\n", 40 | " # update buckets\n", 41 | " if code is True:\n", 42 | " bucket[1].append(next(timestamp))\n", 43 | "\n", 44 | " i = 1\n", 45 | " while len(bucket[i]) == 3:\n", 46 | " bucket[2 * i].append(bucket[i][1])\n", 47 | " del bucket[i][:2]\n", 48 | " i *= 2\n", 49 | "\n", 50 | " elif code is False:\n", 51 | " next(timestamp)\n", 52 | "\n", 53 | " # estimate count\n", 54 | " elif isinstance(code, int):\n", 55 | " counts = [i for i in bucket for t in bucket[i] if code < t] or [0]\n", 56 | " estimate = sum(counts) - counts[-1] // 2\n", 57 | " \n", 58 | " # debug\n", 59 | " elif code == 'debug':\n", 60 | " for i in bucket:\n", 61 | " print(i, bucket[i])" 62 | ] 63 | }, 64 | { 65 | "cell_type": "markdown", 66 | "metadata": {}, 67 | "source": [ 68 | "## run" 69 | ] 70 | }, 71 | { 72 | "cell_type": "code", 73 | "execution_count": 3, 74 | "metadata": { 75 | "collapsed": false 76 | }, 77 | "outputs": [ 78 | { 79 | "name": "stdout", 80 | "output_type": "stream", 81 | "text": [ 82 | "last 10000 bits: 6932\n", 83 | "last 257501 bits: 140052\n", 84 | "last 505000 bits: 303892\n", 85 | "last 752500 bits: 434964\n", 86 | "last 1000000 bits: 434964\n" 87 | ] 88 | } 89 | ], 90 | "source": [ 91 | "n = 10 ** 6\n", 92 | "ctr = stream_counter()\n", 93 | "next(ctr)\n", 94 | "for i in range(n):\n", 95 | " ctr.send(np.random.rand() >= .5)\n", 96 | "\n", 97 | "for i in np.linspace(.99, 0, 5):\n", 98 | " k = int(i * n)\n", 99 | " print(f'last {n - k} bits: {ctr.send(k)}')" 100 | ] 101 | }, 102 | { 103 | "cell_type": "code", 104 | "execution_count": 4, 105 | "metadata": { 106 | "collapsed": false 107 | }, 108 | "outputs": [ 109 | { 110 | "name": "stdout", 111 | "output_type": "stream", 112 | "text": [ 113 | "1 [999999, 1000000]\n", 114 | "2 [999998]\n", 115 | "4 [999989, 999995]\n", 116 | "8 [999984]\n", 117 | "16 [999944, 999970]\n", 118 | "32 [999910]\n", 119 | "64 [999850]\n", 120 | "128 [999732]\n", 121 | "256 [998922, 999481]\n", 122 | "512 [997478, 998417]\n", 123 | "1024 [996449]\n", 124 | "2048 [994456]\n", 125 | "4096 [990348]\n", 126 | "8192 [965868, 982223]\n", 127 | "16384 [949681]\n", 128 | "32768 [851510, 916898]\n", 129 | "65536 [655300, 785917]\n", 130 | "131072 [261942, 524040]\n" 131 | ] 132 | } 133 | ], 134 | "source": [ 135 | "ctr.send('debug')" 136 | ] 137 | }, 138 | { 139 | "cell_type": "code", 140 | "execution_count": null, 141 | "metadata": { 142 | "collapsed": true 143 | }, 144 | "outputs": [], 145 | "source": [] 146 | } 147 | ], 148 | "metadata": { 149 | "kernelspec": { 150 | "display_name": "Python 3", 151 | "language": "python", 152 | "name": "python3" 153 | }, 154 | "language_info": { 155 | "codemirror_mode": { 156 | "name": "ipython", 157 | "version": 3 158 | }, 159 | "file_extension": ".py", 160 | "mimetype": "text/x-python", 161 | "name": "python", 162 | "nbconvert_exporter": "python", 163 | "pygments_lexer": "ipython3", 164 | "version": "3.6.0" 165 | } 166 | }, 167 | "nbformat": 4, 168 | "nbformat_minor": 2 169 | } 170 | -------------------------------------------------------------------------------- /day 36 - bulls and cows.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": 1, 6 | "metadata": { 7 | "collapsed": true 8 | }, 9 | "outputs": [], 10 | "source": [ 11 | "from random import choice, sample\n", 12 | "from itertools import permutations" 13 | ] 14 | }, 15 | { 16 | "cell_type": "markdown", 17 | "metadata": {}, 18 | "source": [ 19 | "## common" 20 | ] 21 | }, 22 | { 23 | "cell_type": "code", 24 | "execution_count": 2, 25 | "metadata": { 26 | "collapsed": true 27 | }, 28 | "outputs": [], 29 | "source": [ 30 | "def score(x, y):\n", 31 | " bulls = sum(i == j for i, j in zip(x, y))\n", 32 | " cows = len(set(x) & set(y)) - bulls\n", 33 | " return bulls, cows" 34 | ] 35 | }, 36 | { 37 | "cell_type": "markdown", 38 | "metadata": {}, 39 | "source": [ 40 | "## player 1" 41 | ] 42 | }, 43 | { 44 | "cell_type": "code", 45 | "execution_count": 3, 46 | "metadata": { 47 | "collapsed": false 48 | }, 49 | "outputs": [], 50 | "source": [ 51 | "def player1(player2):\n", 52 | " secret = sample(range(10), 4)\n", 53 | " \n", 54 | " tip = next(player2)\n", 55 | " while True:\n", 56 | " b, c = score(secret, tip)\n", 57 | " if b < 4:\n", 58 | " print(b, 'bulls', c, 'cows')\n", 59 | " tip = player2.send((b, c))\n", 60 | " else:\n", 61 | " print('you won')\n", 62 | " break" 63 | ] 64 | }, 65 | { 66 | "cell_type": "markdown", 67 | "metadata": {}, 68 | "source": [ 69 | "## player 2" 70 | ] 71 | }, 72 | { 73 | "cell_type": "code", 74 | "execution_count": 4, 75 | "metadata": { 76 | "collapsed": true 77 | }, 78 | "outputs": [], 79 | "source": [ 80 | "def player2():\n", 81 | " tips = list(permutations(range(10), 4))\n", 82 | " \n", 83 | " while True:\n", 84 | " tip = choice(tips)\n", 85 | " print(tip, '?')\n", 86 | " bc = yield tip\n", 87 | " tips = [i for i in tips if score(i, tip) == bc]" 88 | ] 89 | }, 90 | { 91 | "cell_type": "markdown", 92 | "metadata": {}, 93 | "source": [ 94 | "## game" 95 | ] 96 | }, 97 | { 98 | "cell_type": "code", 99 | "execution_count": 5, 100 | "metadata": { 101 | "collapsed": false 102 | }, 103 | "outputs": [ 104 | { 105 | "name": "stdout", 106 | "output_type": "stream", 107 | "text": [ 108 | "(5, 8, 3, 9) ?\n", 109 | "1 bulls 1 cows\n", 110 | "(9, 1, 3, 0) ?\n", 111 | "1 bulls 1 cows\n", 112 | "(5, 9, 7, 0) ?\n", 113 | "1 bulls 1 cows\n", 114 | "(6, 9, 3, 7) ?\n", 115 | "3 bulls 0 cows\n", 116 | "(2, 9, 3, 7) ?\n", 117 | "3 bulls 0 cows\n", 118 | "(4, 9, 3, 7) ?\n", 119 | "you won\n" 120 | ] 121 | } 122 | ], 123 | "source": [ 124 | "player1(player2())" 125 | ] 126 | }, 127 | { 128 | "cell_type": "code", 129 | "execution_count": 6, 130 | "metadata": { 131 | "collapsed": false 132 | }, 133 | "outputs": [ 134 | { 135 | "name": "stdout", 136 | "output_type": "stream", 137 | "text": [ 138 | "(3, 6, 2, 8) ?\n", 139 | "0 bulls 1 cows\n", 140 | "(7, 0, 8, 4) ?\n", 141 | "0 bulls 2 cows\n", 142 | "(2, 7, 5, 0) ?\n", 143 | "0 bulls 1 cows\n", 144 | "(8, 5, 4, 9) ?\n", 145 | "1 bulls 1 cows\n", 146 | "(4, 3, 7, 9) ?\n", 147 | "0 bulls 3 cows\n", 148 | "(6, 9, 4, 7) ?\n", 149 | "2 bulls 0 cows\n", 150 | "(0, 9, 4, 3) ?\n", 151 | "you won\n" 152 | ] 153 | } 154 | ], 155 | "source": [ 156 | "player1(player2())" 157 | ] 158 | }, 159 | { 160 | "cell_type": "code", 161 | "execution_count": null, 162 | "metadata": { 163 | "collapsed": true 164 | }, 165 | "outputs": [], 166 | "source": [] 167 | } 168 | ], 169 | "metadata": { 170 | "kernelspec": { 171 | "display_name": "Python 3", 172 | "language": "python", 173 | "name": "python3" 174 | }, 175 | "language_info": { 176 | "codemirror_mode": { 177 | "name": "ipython", 178 | "version": 3 179 | }, 180 | "file_extension": ".py", 181 | "mimetype": "text/x-python", 182 | "name": "python", 183 | "nbconvert_exporter": "python", 184 | "pygments_lexer": "ipython3", 185 | "version": "3.6.0" 186 | } 187 | }, 188 | "nbformat": 4, 189 | "nbformat_minor": 2 190 | } 191 | -------------------------------------------------------------------------------- /day 51 - rabin-miller.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": 1, 6 | "metadata": { 7 | "collapsed": true 8 | }, 9 | "outputs": [], 10 | "source": [ 11 | "from random import randrange" 12 | ] 13 | }, 14 | { 15 | "cell_type": "markdown", 16 | "metadata": {}, 17 | "source": [ 18 | "## algorithm" 19 | ] 20 | }, 21 | { 22 | "cell_type": "code", 23 | "execution_count": 2, 24 | "metadata": { 25 | "collapsed": false 26 | }, 27 | "outputs": [], 28 | "source": [ 29 | "def rabin_miller(prime, tests):\n", 30 | " if prime < 5:\n", 31 | " return prime in [2, 3]\n", 32 | " \n", 33 | " # set: prime = q * 2**r + 1\n", 34 | " q, r = prime - 1, 0\n", 35 | " while not q & 1:\n", 36 | " q >>= 1\n", 37 | " r += 1\n", 38 | "\n", 39 | " # test repeatedly\n", 40 | " for _ in range(tests):\n", 41 | " a = randrange(2, prime - 1)\n", 42 | "\n", 43 | " # pass if: a**q == 1\n", 44 | " x = pow(a, q, prime)\n", 45 | " if x in [1, prime - 1]:\n", 46 | " continue\n", 47 | "\n", 48 | " # pass if: a**(q * 2**s) == -1, s < r\n", 49 | " for _ in range(r - 1):\n", 50 | " x = pow(x, 2, prime)\n", 51 | " if x == prime - 1:\n", 52 | " break\n", 53 | " else:\n", 54 | " return False\n", 55 | "\n", 56 | " return True" 57 | ] 58 | }, 59 | { 60 | "cell_type": "code", 61 | "execution_count": 3, 62 | "metadata": { 63 | "collapsed": true 64 | }, 65 | "outputs": [], 66 | "source": [ 67 | "def prime(bits, tests):\n", 68 | " while True:\n", 69 | " # random number in [2**bits .. 2**(bits+1)-1]\n", 70 | " prime = (1 << bits) | randrange(1 << bits) | 1\n", 71 | "\n", 72 | " # primality test\n", 73 | " if rabin_miller(prime, tests):\n", 74 | " return prime" 75 | ] 76 | }, 77 | { 78 | "cell_type": "markdown", 79 | "metadata": {}, 80 | "source": [ 81 | "## primes" 82 | ] 83 | }, 84 | { 85 | "cell_type": "code", 86 | "execution_count": 4, 87 | "metadata": { 88 | "collapsed": false 89 | }, 90 | "outputs": [ 91 | { 92 | "data": { 93 | "text/plain": [ 94 | "491" 95 | ] 96 | }, 97 | "execution_count": 4, 98 | "metadata": {}, 99 | "output_type": "execute_result" 100 | } 101 | ], 102 | "source": [ 103 | "prime(8, 32)" 104 | ] 105 | }, 106 | { 107 | "cell_type": "code", 108 | "execution_count": 5, 109 | "metadata": { 110 | "collapsed": false 111 | }, 112 | "outputs": [ 113 | { 114 | "data": { 115 | "text/plain": [ 116 | "167539476446412633052018914179671756072742261642391296029084943606975058499651" 117 | ] 118 | }, 119 | "execution_count": 5, 120 | "metadata": {}, 121 | "output_type": "execute_result" 122 | } 123 | ], 124 | "source": [ 125 | "prime(256, 32)" 126 | ] 127 | }, 128 | { 129 | "cell_type": "code", 130 | "execution_count": 6, 131 | "metadata": { 132 | "collapsed": false 133 | }, 134 | "outputs": [ 135 | { 136 | "data": { 137 | "text/plain": [ 138 | "327629758798678908807612458298442202698722670823449712916355625086421084819056655501101117430544648756451802433910857072317916389191167555508482465929724915679965943104133398992501561113977009936622055728794693540394304838984423959080924829552190406356895643910247318370440605397978334769846807883781807340317" 139 | ] 140 | }, 141 | "execution_count": 6, 142 | "metadata": {}, 143 | "output_type": "execute_result" 144 | } 145 | ], 146 | "source": [ 147 | "prime(1024, 32)" 148 | ] 149 | }, 150 | { 151 | "cell_type": "code", 152 | "execution_count": null, 153 | "metadata": { 154 | "collapsed": true 155 | }, 156 | "outputs": [], 157 | "source": [] 158 | } 159 | ], 160 | "metadata": { 161 | "kernelspec": { 162 | "display_name": "Python 3", 163 | "language": "python", 164 | "name": "python3" 165 | }, 166 | "language_info": { 167 | "codemirror_mode": { 168 | "name": "ipython", 169 | "version": 3 170 | }, 171 | "file_extension": ".py", 172 | "mimetype": "text/x-python", 173 | "name": "python", 174 | "nbconvert_exporter": "python", 175 | "pygments_lexer": "ipython3", 176 | "version": "3.6.0" 177 | } 178 | }, 179 | "nbformat": 4, 180 | "nbformat_minor": 2 181 | } 182 | -------------------------------------------------------------------------------- /day 44 - gradient approximation.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": 1, 6 | "metadata": { 7 | "collapsed": true 8 | }, 9 | "outputs": [], 10 | "source": [ 11 | "import numpy as np" 12 | ] 13 | }, 14 | { 15 | "cell_type": "markdown", 16 | "metadata": {}, 17 | "source": [ 18 | "## algorithm" 19 | ] 20 | }, 21 | { 22 | "cell_type": "code", 23 | "execution_count": 2, 24 | "metadata": { 25 | "collapsed": true 26 | }, 27 | "outputs": [], 28 | "source": [ 29 | "def gradient(fun, x, delta=1e-4):\n", 30 | " x = np.asfarray(x)\n", 31 | " grad = np.zeros(x.shape, dtype=x.dtype)\n", 32 | "\n", 33 | " for i, t in np.ndenumerate(x):\n", 34 | " x[i] = t + delta\n", 35 | " grad[i] = fun(x)\n", 36 | " x[i] = t - delta\n", 37 | " grad[i] -= fun(x)\n", 38 | " x[i] = t\n", 39 | "\n", 40 | " return grad / (2 * delta)" 41 | ] 42 | }, 43 | { 44 | "cell_type": "markdown", 45 | "metadata": {}, 46 | "source": [ 47 | "## quadratic form" 48 | ] 49 | }, 50 | { 51 | "cell_type": "code", 52 | "execution_count": 3, 53 | "metadata": { 54 | "collapsed": false 55 | }, 56 | "outputs": [ 57 | { 58 | "name": "stdout", 59 | "output_type": "stream", 60 | "text": [ 61 | "x= -1 grad= [-4.]\n", 62 | "x= 0 grad= [ 2.]\n", 63 | "x= 1 grad= [ 8.]\n" 64 | ] 65 | } 66 | ], 67 | "source": [ 68 | "def function(x):\n", 69 | " return 3 * x**2 + 2 * x + 1\n", 70 | "\n", 71 | "for x in [-1, 0, 1]:\n", 72 | " print('x=', x, 'grad=', gradient(function, [x]))" 73 | ] 74 | }, 75 | { 76 | "cell_type": "markdown", 77 | "metadata": {}, 78 | "source": [ 79 | "## transcendental function" 80 | ] 81 | }, 82 | { 83 | "cell_type": "code", 84 | "execution_count": 4, 85 | "metadata": { 86 | "collapsed": false 87 | }, 88 | "outputs": [ 89 | { 90 | "name": "stdout", 91 | "output_type": "stream", 92 | "text": [ 93 | "x= [0, 0, 0] grad= [ 0. 1. 1.]\n", 94 | "x= [0, 0, 1] grad= [ 1.84147099 1.54030231 1. ]\n", 95 | "x= [0, 1, 1] grad= [ 3.55975282 3.25858414 1.87681085]\n", 96 | "x= [1, 1, 1] grad= [ 8.2305271 7.92935842 7.08788742]\n" 97 | ] 98 | } 99 | ], 100 | "source": [ 101 | "def function(X):\n", 102 | " x, y, z = X\n", 103 | " return x * np.sin(z) + y * np.cos(z) + z * np.exp(x + y)\n", 104 | "\n", 105 | "for x in [[0, 0, 0], [0, 0, 1], [0, 1, 1], [1, 1, 1]]:\n", 106 | " print('x=', x, 'grad=', gradient(function, x))" 107 | ] 108 | }, 109 | { 110 | "cell_type": "markdown", 111 | "metadata": { 112 | "collapsed": true 113 | }, 114 | "source": [ 115 | "## determinant" 116 | ] 117 | }, 118 | { 119 | "cell_type": "code", 120 | "execution_count": 5, 121 | "metadata": { 122 | "collapsed": false 123 | }, 124 | "outputs": [ 125 | { 126 | "name": "stdout", 127 | "output_type": "stream", 128 | "text": [ 129 | "x=\n", 130 | "[[1, 2, 3], [2, 3, 1], [3, 1, 2]]\n", 131 | "grad=\n", 132 | "[[ 5. -1. -7.]\n", 133 | " [-1. -7. 5.]\n", 134 | " [-7. 5. -1.]]\n", 135 | "x=\n", 136 | "[[1, 1, 1], [1, 1, 1], [1, 1, 1]]\n", 137 | "grad=\n", 138 | "[[ 0. 0. 0.]\n", 139 | " [ 0. 0. 0.]\n", 140 | " [ 0. 0. 0.]]\n", 141 | "x=\n", 142 | "[[1, 1], [1, 1]]\n", 143 | "grad=\n", 144 | "[[ 1. -1.]\n", 145 | " [-1. 1.]]\n" 146 | ] 147 | } 148 | ], 149 | "source": [ 150 | "function = np.linalg.det\n", 151 | "\n", 152 | "for x in [\n", 153 | " [[1, 2, 3], [2, 3, 1], [3, 1, 2]],\n", 154 | " [[1, 1, 1], [1, 1, 1], [1, 1, 1]],\n", 155 | " [[1, 1], [1, 1]],\n", 156 | "]:\n", 157 | " print('x=')\n", 158 | " print(x)\n", 159 | " print('grad=')\n", 160 | " print(gradient(function, x))" 161 | ] 162 | }, 163 | { 164 | "cell_type": "code", 165 | "execution_count": null, 166 | "metadata": { 167 | "collapsed": true 168 | }, 169 | "outputs": [], 170 | "source": [] 171 | } 172 | ], 173 | "metadata": { 174 | "kernelspec": { 175 | "display_name": "Python 3", 176 | "language": "python", 177 | "name": "python3" 178 | }, 179 | "language_info": { 180 | "codemirror_mode": { 181 | "name": "ipython", 182 | "version": 3 183 | }, 184 | "file_extension": ".py", 185 | "mimetype": "text/x-python", 186 | "name": "python", 187 | "nbconvert_exporter": "python", 188 | "pygments_lexer": "ipython3", 189 | "version": "3.6.0" 190 | } 191 | }, 192 | "nbformat": 4, 193 | "nbformat_minor": 2 194 | } 195 | -------------------------------------------------------------------------------- /bonus - fast convex hull.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": 1, 6 | "metadata": { 7 | "collapsed": true 8 | }, 9 | "outputs": [], 10 | "source": [ 11 | "import numpy as np" 12 | ] 13 | }, 14 | { 15 | "cell_type": "markdown", 16 | "metadata": {}, 17 | "source": [ 18 | "## original algorithm: [day 28 - convex hull](https://github.com/coells/100days/blob/master/day 28 - convex hull.ipynb)" 19 | ] 20 | }, 21 | { 22 | "cell_type": "markdown", 23 | "metadata": {}, 24 | "source": [ 25 | "## refactored algorithm" 26 | ] 27 | }, 28 | { 29 | "cell_type": "code", 30 | "execution_count": 2, 31 | "metadata": { 32 | "collapsed": true 33 | }, 34 | "outputs": [], 35 | "source": [ 36 | "def extend(points, u, v, hull):\n", 37 | " if not len(points):\n", 38 | " return\n", 39 | "\n", 40 | " # find W as the furthest point from U-V\n", 41 | " w = points[np.argmin(np.cross(points - u, v - u))]\n", 42 | " p = points - w\n", 43 | "\n", 44 | " # extend hull for U-W and V-W\n", 45 | " extend(points[np.cross(p, v - w) < 0], w, v, hull)\n", 46 | " hull.append(w)\n", 47 | " extend(points[np.cross(p, u - w) > 0], u, w, hull)" 48 | ] 49 | }, 50 | { 51 | "cell_type": "code", 52 | "execution_count": 3, 53 | "metadata": { 54 | "collapsed": true 55 | }, 56 | "outputs": [], 57 | "source": [ 58 | "def convex_hull(points):\n", 59 | " # U is left-most hull point, V is right-most hull point\n", 60 | " u = points[np.argmin(points[:, 0])]\n", 61 | " v = points[np.argmax(points[:, 0])]\n", 62 | " w = np.cross(points - u, v - u)\n", 63 | "\n", 64 | " # recurse on hull construction\n", 65 | " hull = [v]\n", 66 | " extend(points[w < 0], u, v, hull)\n", 67 | " hull.append(u)\n", 68 | " extend(points[w > 0], v, u, hull)\n", 69 | " hull.append(v)\n", 70 | "\n", 71 | " return hull" 72 | ] 73 | }, 74 | { 75 | "cell_type": "markdown", 76 | "metadata": {}, 77 | "source": [ 78 | "## benchmark" 79 | ] 80 | }, 81 | { 82 | "cell_type": "code", 83 | "execution_count": 4, 84 | "metadata": {}, 85 | "outputs": [ 86 | { 87 | "name": "stdout", 88 | "output_type": "stream", 89 | "text": [ 90 | "1000 loops, best of 3: 987 µs per loop\n" 91 | ] 92 | } 93 | ], 94 | "source": [ 95 | "%timeit convex_hull(np.random.rand(10**3, 2))" 96 | ] 97 | }, 98 | { 99 | "cell_type": "code", 100 | "execution_count": 5, 101 | "metadata": {}, 102 | "outputs": [ 103 | { 104 | "name": "stdout", 105 | "output_type": "stream", 106 | "text": [ 107 | "100 loops, best of 3: 2.35 ms per loop\n" 108 | ] 109 | } 110 | ], 111 | "source": [ 112 | "%timeit convex_hull(np.random.rand(10**4, 2))" 113 | ] 114 | }, 115 | { 116 | "cell_type": "code", 117 | "execution_count": 6, 118 | "metadata": {}, 119 | "outputs": [ 120 | { 121 | "name": "stdout", 122 | "output_type": "stream", 123 | "text": [ 124 | "100 loops, best of 3: 13.8 ms per loop\n" 125 | ] 126 | } 127 | ], 128 | "source": [ 129 | "%timeit convex_hull(np.random.rand(10**5, 2))" 130 | ] 131 | }, 132 | { 133 | "cell_type": "code", 134 | "execution_count": 7, 135 | "metadata": {}, 136 | "outputs": [ 137 | { 138 | "name": "stdout", 139 | "output_type": "stream", 140 | "text": [ 141 | "10 loops, best of 3: 167 ms per loop\n" 142 | ] 143 | } 144 | ], 145 | "source": [ 146 | "%timeit convex_hull(np.random.rand(10**6, 2))" 147 | ] 148 | }, 149 | { 150 | "cell_type": "code", 151 | "execution_count": 8, 152 | "metadata": {}, 153 | "outputs": [ 154 | { 155 | "name": "stdout", 156 | "output_type": "stream", 157 | "text": [ 158 | "1 loop, best of 3: 1.98 s per loop\n" 159 | ] 160 | } 161 | ], 162 | "source": [ 163 | "%timeit convex_hull(np.random.rand(10**7, 2))" 164 | ] 165 | }, 166 | { 167 | "cell_type": "code", 168 | "execution_count": null, 169 | "metadata": { 170 | "collapsed": true 171 | }, 172 | "outputs": [], 173 | "source": [] 174 | } 175 | ], 176 | "metadata": { 177 | "kernelspec": { 178 | "display_name": "Python 3", 179 | "language": "python", 180 | "name": "python3" 181 | }, 182 | "language_info": { 183 | "codemirror_mode": { 184 | "name": "ipython", 185 | "version": 3 186 | }, 187 | "file_extension": ".py", 188 | "mimetype": "text/x-python", 189 | "name": "python", 190 | "nbconvert_exporter": "python", 191 | "pygments_lexer": "ipython3", 192 | "version": "3.6.1" 193 | } 194 | }, 195 | "nbformat": 4, 196 | "nbformat_minor": 2 197 | } 198 | -------------------------------------------------------------------------------- /day 91 - variations.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": 1, 6 | "metadata": { 7 | "collapsed": true 8 | }, 9 | "outputs": [], 10 | "source": [ 11 | "from random import randrange" 12 | ] 13 | }, 14 | { 15 | "cell_type": "markdown", 16 | "metadata": {}, 17 | "source": [ 18 | "## algorithm" 19 | ] 20 | }, 21 | { 22 | "cell_type": "code", 23 | "execution_count": 2, 24 | "metadata": { 25 | "collapsed": true 26 | }, 27 | "outputs": [], 28 | "source": [ 29 | "def ffact(n, k, _cache={}):\n", 30 | " if (n, k) not in _cache:\n", 31 | " f = 1\n", 32 | " for i in range(k):\n", 33 | " f *= n - i\n", 34 | " \n", 35 | " _cache[n, k] = f\n", 36 | " \n", 37 | " return _cache[n, k]" 38 | ] 39 | }, 40 | { 41 | "cell_type": "code", 42 | "execution_count": 3, 43 | "metadata": { 44 | "collapsed": true 45 | }, 46 | "outputs": [], 47 | "source": [ 48 | "def variation_to_order(variation):\n", 49 | " alphabet = list('0123456789')\n", 50 | " n = len(variation)\n", 51 | "\n", 52 | " order = 1\n", 53 | " order -= ffact(9, n - 1)\n", 54 | " for i in range(1, n):\n", 55 | " order += ffact(10, i) - ffact(9, i - 1)\n", 56 | "\n", 57 | " for i in range(n):\n", 58 | " index = alphabet.index(variation[i])\n", 59 | " order += index * ffact(9 - i, n - i - 1)\n", 60 | " del alphabet[index]\n", 61 | "\n", 62 | " return order" 63 | ] 64 | }, 65 | { 66 | "cell_type": "code", 67 | "execution_count": 4, 68 | "metadata": { 69 | "collapsed": true 70 | }, 71 | "outputs": [], 72 | "source": [ 73 | "def order_to_variation(order):\n", 74 | " for n in range(1, 11):\n", 75 | " k = ffact(10, n) - ffact(9, n - 1)\n", 76 | " if k >= order:\n", 77 | " break\n", 78 | " order -= k\n", 79 | "\n", 80 | " order -= (n != 1)\n", 81 | " alphabet = list('0123456789')\n", 82 | " variation = ''\n", 83 | "\n", 84 | " for i in range(n):\n", 85 | " k = ffact(9 - i, n - i - 1)\n", 86 | " index = order // k + (i == 0) - (n == 1)\n", 87 | " order %= k\n", 88 | " variation += alphabet[index]\n", 89 | " del alphabet[index]\n", 90 | "\n", 91 | " return variation" 92 | ] 93 | }, 94 | { 95 | "cell_type": "markdown", 96 | "metadata": {}, 97 | "source": [ 98 | "## run" 99 | ] 100 | }, 101 | { 102 | "cell_type": "code", 103 | "execution_count": 5, 104 | "metadata": { 105 | "collapsed": false 106 | }, 107 | "outputs": [ 108 | { 109 | "data": { 110 | "text/plain": [ 111 | "8877690" 112 | ] 113 | }, 114 | "execution_count": 5, 115 | "metadata": {}, 116 | "output_type": "execute_result" 117 | } 118 | ], 119 | "source": [ 120 | "variation_to_order('9876543210')" 121 | ] 122 | }, 123 | { 124 | "cell_type": "code", 125 | "execution_count": 6, 126 | "metadata": { 127 | "collapsed": false 128 | }, 129 | "outputs": [ 130 | { 131 | "name": "stdout", 132 | "output_type": "stream", 133 | "text": [ 134 | " variation order\n", 135 | " 598604732 ## 4158906\n", 136 | " 594216380 ## 4141709\n", 137 | " 63270914 ## 1687099\n", 138 | "2486703591 ## 6129220\n", 139 | " 948073165 ## 5446104\n", 140 | " 72149586 ## 1845426\n", 141 | "5647981230 ## 7288636\n", 142 | "3249076158 ## 6432655\n", 143 | "2768310954 ## 6245640\n", 144 | "9312078654 ## 8641626\n" 145 | ] 146 | } 147 | ], 148 | "source": [ 149 | "print(' variation order')\n", 150 | "for _ in range(10):\n", 151 | " i = randrange(8877691)\n", 152 | " variation = order_to_variation(i)\n", 153 | " order = variation_to_order(variation)\n", 154 | " assert i == order\n", 155 | " print('%10s ## %d' % (variation, order))" 156 | ] 157 | }, 158 | { 159 | "cell_type": "code", 160 | "execution_count": null, 161 | "metadata": { 162 | "collapsed": true 163 | }, 164 | "outputs": [], 165 | "source": [] 166 | } 167 | ], 168 | "metadata": { 169 | "kernelspec": { 170 | "display_name": "Python 3", 171 | "language": "python", 172 | "name": "python3" 173 | }, 174 | "language_info": { 175 | "codemirror_mode": { 176 | "name": "ipython", 177 | "version": 3 178 | }, 179 | "file_extension": ".py", 180 | "mimetype": "text/x-python", 181 | "name": "python", 182 | "nbconvert_exporter": "python", 183 | "pygments_lexer": "ipython3", 184 | "version": "3.6.0" 185 | } 186 | }, 187 | "nbformat": 4, 188 | "nbformat_minor": 2 189 | } 190 | -------------------------------------------------------------------------------- /day 63 - zig-zag.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": 1, 6 | "metadata": { 7 | "collapsed": true 8 | }, 9 | "outputs": [], 10 | "source": [ 11 | "import numpy as np" 12 | ] 13 | }, 14 | { 15 | "cell_type": "markdown", 16 | "metadata": {}, 17 | "source": [ 18 | "## algorithm" 19 | ] 20 | }, 21 | { 22 | "cell_type": "code", 23 | "execution_count": 2, 24 | "metadata": { 25 | "collapsed": true 26 | }, 27 | "outputs": [], 28 | "source": [ 29 | "def zig_zag_index(k, n):\n", 30 | " # upper side of interval\n", 31 | " if k >= n * (n + 1) // 2:\n", 32 | " i, j = zig_zag_index(n * n - 1 - k, n)\n", 33 | " return n - 1 - i, n - 1 - j\n", 34 | "\n", 35 | " # lower side of interval\n", 36 | " i = int((np.sqrt(1 + 8 * k) - 1) / 2)\n", 37 | " j = k - i * (i + 1) // 2\n", 38 | " return (j, i - j) if i & 1 else (i - j, j)" 39 | ] 40 | }, 41 | { 42 | "cell_type": "code", 43 | "execution_count": 3, 44 | "metadata": { 45 | "collapsed": true 46 | }, 47 | "outputs": [], 48 | "source": [ 49 | "def zig_zag_value(i, j, n):\n", 50 | " # upper side of interval\n", 51 | " if i + j >= n:\n", 52 | " return n * n - 1 - zig_zag_value(n - 1 - i, n - 1 - j, n)\n", 53 | "\n", 54 | " # lower side of interval\n", 55 | " k = (i + j) * (i + j + 1) // 2\n", 56 | " return k + i if (i + j) & 1 else k + j" 57 | ] 58 | }, 59 | { 60 | "cell_type": "markdown", 61 | "metadata": {}, 62 | "source": [ 63 | "## run" 64 | ] 65 | }, 66 | { 67 | "cell_type": "code", 68 | "execution_count": 4, 69 | "metadata": { 70 | "collapsed": true 71 | }, 72 | "outputs": [], 73 | "source": [ 74 | "n = 10" 75 | ] 76 | }, 77 | { 78 | "cell_type": "code", 79 | "execution_count": 5, 80 | "metadata": { 81 | "collapsed": false 82 | }, 83 | "outputs": [ 84 | { 85 | "data": { 86 | "text/plain": [ 87 | "array([[ 0, 1, 5, 6, 14, 15, 27, 28, 44, 45],\n", 88 | " [ 2, 4, 7, 13, 16, 26, 29, 43, 46, 63],\n", 89 | " [ 3, 8, 12, 17, 25, 30, 42, 47, 62, 64],\n", 90 | " [ 9, 11, 18, 24, 31, 41, 48, 61, 65, 78],\n", 91 | " [10, 19, 23, 32, 40, 49, 60, 66, 77, 79],\n", 92 | " [20, 22, 33, 39, 50, 59, 67, 76, 80, 89],\n", 93 | " [21, 34, 38, 51, 58, 68, 75, 81, 88, 90],\n", 94 | " [35, 37, 52, 57, 69, 74, 82, 87, 91, 96],\n", 95 | " [36, 53, 56, 70, 73, 83, 86, 92, 95, 97],\n", 96 | " [54, 55, 71, 72, 84, 85, 93, 94, 98, 99]])" 97 | ] 98 | }, 99 | "execution_count": 5, 100 | "metadata": {}, 101 | "output_type": "execute_result" 102 | } 103 | ], 104 | "source": [ 105 | "M = np.zeros((n, n), dtype=int)\n", 106 | "for i in range(n):\n", 107 | " for j in range(n):\n", 108 | " M[i, j] = zig_zag_value(i, j, n)\n", 109 | "M" 110 | ] 111 | }, 112 | { 113 | "cell_type": "code", 114 | "execution_count": 6, 115 | "metadata": { 116 | "collapsed": false 117 | }, 118 | "outputs": [ 119 | { 120 | "data": { 121 | "text/plain": [ 122 | "array([[ 0, 1, 5, 6, 14, 15, 27, 28, 44, 45],\n", 123 | " [ 2, 4, 7, 13, 16, 26, 29, 43, 46, 63],\n", 124 | " [ 3, 8, 12, 17, 25, 30, 42, 47, 62, 64],\n", 125 | " [ 9, 11, 18, 24, 31, 41, 48, 61, 65, 78],\n", 126 | " [10, 19, 23, 32, 40, 49, 60, 66, 77, 79],\n", 127 | " [20, 22, 33, 39, 50, 59, 67, 76, 80, 89],\n", 128 | " [21, 34, 38, 51, 58, 68, 75, 81, 88, 90],\n", 129 | " [35, 37, 52, 57, 69, 74, 82, 87, 91, 96],\n", 130 | " [36, 53, 56, 70, 73, 83, 86, 92, 95, 97],\n", 131 | " [54, 55, 71, 72, 84, 85, 93, 94, 98, 99]])" 132 | ] 133 | }, 134 | "execution_count": 6, 135 | "metadata": {}, 136 | "output_type": "execute_result" 137 | } 138 | ], 139 | "source": [ 140 | "M = np.zeros((n, n), dtype=int)\n", 141 | "for k in range(n * n):\n", 142 | " M[zig_zag_index(k, n)] = k\n", 143 | "M" 144 | ] 145 | }, 146 | { 147 | "cell_type": "code", 148 | "execution_count": null, 149 | "metadata": { 150 | "collapsed": true 151 | }, 152 | "outputs": [], 153 | "source": [] 154 | } 155 | ], 156 | "metadata": { 157 | "kernelspec": { 158 | "display_name": "Python 3", 159 | "language": "python", 160 | "name": "python3" 161 | }, 162 | "language_info": { 163 | "codemirror_mode": { 164 | "name": "ipython", 165 | "version": 3 166 | }, 167 | "file_extension": ".py", 168 | "mimetype": "text/x-python", 169 | "name": "python", 170 | "nbconvert_exporter": "python", 171 | "pygments_lexer": "ipython3", 172 | "version": "3.6.0" 173 | } 174 | }, 175 | "nbformat": 4, 176 | "nbformat_minor": 2 177 | } 178 | -------------------------------------------------------------------------------- /day 42 - hamming codes.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": 1, 6 | "metadata": { 7 | "collapsed": true 8 | }, 9 | "outputs": [], 10 | "source": [ 11 | "import numpy as np" 12 | ] 13 | }, 14 | { 15 | "cell_type": "markdown", 16 | "metadata": {}, 17 | "source": [ 18 | "## algorithm" 19 | ] 20 | }, 21 | { 22 | "cell_type": "code", 23 | "execution_count": 2, 24 | "metadata": { 25 | "collapsed": true 26 | }, 27 | "outputs": [], 28 | "source": [ 29 | "def encode(parity_bits, data):\n", 30 | " n = len(data) + parity_bits\n", 31 | " assert 2 ** parity_bits == n + 1\n", 32 | "\n", 33 | " # copy data to code\n", 34 | " code = np.zeros(n, dtype=int)\n", 35 | " code[np.arange(n) & np.arange(n) + 1 > 0] = data\n", 36 | "\n", 37 | " # parity mask\n", 38 | " mask = np.zeros(n, dtype=int)\n", 39 | " mask[::2] = 1\n", 40 | "\n", 41 | " # compute parity\n", 42 | " i = 0\n", 43 | " while i < n:\n", 44 | " code[i] = code[i:][mask == 1].sum() & 1\n", 45 | " i += i + 1\n", 46 | " mask = np.repeat(mask, 2)[:n - i]\n", 47 | "\n", 48 | " # result\n", 49 | " return code" 50 | ] 51 | }, 52 | { 53 | "cell_type": "code", 54 | "execution_count": 3, 55 | "metadata": { 56 | "collapsed": true 57 | }, 58 | "outputs": [], 59 | "source": [ 60 | "def decode(code):\n", 61 | " n = len(code)\n", 62 | "\n", 63 | " # parity mask\n", 64 | " mask = np.zeros(n, dtype=int)\n", 65 | " mask[::2] = 1\n", 66 | "\n", 67 | " # compute parity\n", 68 | " error, i = -1, 0\n", 69 | " while i < n:\n", 70 | " error += (i + 1) * (code[i:][mask == 1].sum() & 1)\n", 71 | " i += i + 1\n", 72 | " mask = np.repeat(mask, 2)[:n - i]\n", 73 | "\n", 74 | " # fix error\n", 75 | " if error >= 0:\n", 76 | " code[error] ^= 1\n", 77 | "\n", 78 | " # get data from code\n", 79 | " data = code[np.arange(n) & np.arange(n) + 1 > 0]\n", 80 | "\n", 81 | " # result\n", 82 | " return error, data" 83 | ] 84 | }, 85 | { 86 | "cell_type": "markdown", 87 | "metadata": {}, 88 | "source": [ 89 | "## encoding" 90 | ] 91 | }, 92 | { 93 | "cell_type": "code", 94 | "execution_count": 4, 95 | "metadata": { 96 | "collapsed": false 97 | }, 98 | "outputs": [ 99 | { 100 | "name": "stdout", 101 | "output_type": "stream", 102 | "text": [ 103 | "hamming code [1 0 0 1] -> [0 0 1 1 0 0 1]\n", 104 | "with error [0 0 1 0 0 0 1]\n", 105 | "error @ 3 -> [1 0 0 1]\n" 106 | ] 107 | } 108 | ], 109 | "source": [ 110 | "parity_bits = 3\n", 111 | "data = np.random.randint(0, 2, 4)\n", 112 | "\n", 113 | "# generate code\n", 114 | "code = encode(parity_bits, data)\n", 115 | "print('hamming code', data, '->', code)\n", 116 | "\n", 117 | "# make error\n", 118 | "code[3] ^= 1\n", 119 | "print('with error', code)\n", 120 | "\n", 121 | "# reconstruct\n", 122 | "error, recon = decode(code)\n", 123 | "print('error @', error, '->', recon)" 124 | ] 125 | }, 126 | { 127 | "cell_type": "code", 128 | "execution_count": 5, 129 | "metadata": { 130 | "collapsed": false 131 | }, 132 | "outputs": [ 133 | { 134 | "name": "stdout", 135 | "output_type": "stream", 136 | "text": [ 137 | "hamming code [0 0 0 1 0 0 0 0 1 1 1] -> [1 1 0 0 0 0 1 1 0 0 0 0 1 1 1]\n", 138 | "with error [1 1 0 0 0 0 1 1 0 0 0 0 1 1 0]\n", 139 | "error @ 14 -> [0 0 0 1 0 0 0 0 1 1 1]\n" 140 | ] 141 | } 142 | ], 143 | "source": [ 144 | "parity_bits = 4\n", 145 | "data = np.random.randint(0, 2, 11)\n", 146 | "\n", 147 | "# generate code\n", 148 | "code = encode(parity_bits, data)\n", 149 | "print('hamming code', data, '->', code)\n", 150 | "\n", 151 | "# make error\n", 152 | "code[14] ^= 1\n", 153 | "print('with error', code)\n", 154 | "\n", 155 | "# reconstruct\n", 156 | "error, recon = decode(code)\n", 157 | "print('error @', error, '->', recon)" 158 | ] 159 | }, 160 | { 161 | "cell_type": "code", 162 | "execution_count": null, 163 | "metadata": { 164 | "collapsed": true 165 | }, 166 | "outputs": [], 167 | "source": [] 168 | } 169 | ], 170 | "metadata": { 171 | "kernelspec": { 172 | "display_name": "Python 3", 173 | "language": "python", 174 | "name": "python3" 175 | }, 176 | "language_info": { 177 | "codemirror_mode": { 178 | "name": "ipython", 179 | "version": 3 180 | }, 181 | "file_extension": ".py", 182 | "mimetype": "text/x-python", 183 | "name": "python", 184 | "nbconvert_exporter": "python", 185 | "pygments_lexer": "ipython3", 186 | "version": "3.6.0" 187 | } 188 | }, 189 | "nbformat": 4, 190 | "nbformat_minor": 2 191 | } 192 | -------------------------------------------------------------------------------- /day 30 - strassen multiplication.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": 1, 6 | "metadata": { 7 | "collapsed": true 8 | }, 9 | "outputs": [], 10 | "source": [ 11 | "import numpy as np" 12 | ] 13 | }, 14 | { 15 | "cell_type": "markdown", 16 | "metadata": {}, 17 | "source": [ 18 | "## algorithm" 19 | ] 20 | }, 21 | { 22 | "cell_type": "code", 23 | "execution_count": 2, 24 | "metadata": { 25 | "collapsed": true 26 | }, 27 | "outputs": [], 28 | "source": [ 29 | "def strassen(A, B):\n", 30 | " k = A.shape[0] // 2\n", 31 | " if k == 0:\n", 32 | " return A * B\n", 33 | "\n", 34 | " A11, A12 = A[:k, :k], A[:k, k:]\n", 35 | " A21, A22 = A[k:, :k], A[k:, k:]\n", 36 | " B11, B12 = B[:k, :k], B[:k, k:]\n", 37 | " B21, B22 = B[k:, :k], B[k:, k:]\n", 38 | " \n", 39 | " T1 = strassen(A11 + A22, B11 + B22)\n", 40 | " T2 = strassen(A21 + A22, B11)\n", 41 | " T3 = strassen(A11, B12 - B22)\n", 42 | " T4 = strassen(A22, B21 - B11)\n", 43 | " T5 = strassen(A11 + A12, B22)\n", 44 | " T6 = strassen(A21 - A11, B11 + B12)\n", 45 | " T7 = strassen(A12 - A22, B21 + B22)\n", 46 | " \n", 47 | " C = np.zeros(A.shape, dtype=A.dtype)\n", 48 | " C[:k, :k] = T1 + T4 - T5 + T7\n", 49 | " C[:k, k:] = T3 + T5\n", 50 | " C[k:, :k] = T2 + T4\n", 51 | " C[k:, k:] = T1 - T2 + T3 + T6\n", 52 | " \n", 53 | " return C" 54 | ] 55 | }, 56 | { 57 | "cell_type": "markdown", 58 | "metadata": {}, 59 | "source": [ 60 | "## run" 61 | ] 62 | }, 63 | { 64 | "cell_type": "code", 65 | "execution_count": 3, 66 | "metadata": { 67 | "collapsed": false 68 | }, 69 | "outputs": [ 70 | { 71 | "data": { 72 | "text/plain": [ 73 | "array([[9, 1, 1, 2, 5, 2, 8, 3],\n", 74 | " [4, 7, 1, 9, 6, 6, 9, 5],\n", 75 | " [0, 1, 0, 1, 7, 6, 0, 8],\n", 76 | " [9, 0, 4, 3, 3, 4, 4, 5],\n", 77 | " [6, 9, 4, 7, 1, 5, 5, 0],\n", 78 | " [3, 5, 8, 1, 6, 2, 3, 8],\n", 79 | " [3, 1, 0, 4, 2, 5, 1, 7],\n", 80 | " [2, 6, 4, 6, 3, 4, 6, 3]])" 81 | ] 82 | }, 83 | "execution_count": 3, 84 | "metadata": {}, 85 | "output_type": "execute_result" 86 | } 87 | ], 88 | "source": [ 89 | "X = np.random.randint(0, 10, (8, 8))\n", 90 | "X" 91 | ] 92 | }, 93 | { 94 | "cell_type": "code", 95 | "execution_count": 4, 96 | "metadata": { 97 | "collapsed": false 98 | }, 99 | "outputs": [ 100 | { 101 | "data": { 102 | "text/plain": [ 103 | "array([[8, 1, 1, 7, 6, 2, 7, 3],\n", 104 | " [2, 3, 6, 5, 8, 2, 0, 0],\n", 105 | " [5, 5, 1, 6, 3, 4, 4, 9],\n", 106 | " [4, 0, 6, 0, 4, 0, 7, 8],\n", 107 | " [2, 7, 0, 7, 3, 1, 5, 2],\n", 108 | " [8, 1, 9, 3, 3, 7, 6, 2],\n", 109 | " [8, 5, 7, 4, 7, 8, 9, 7],\n", 110 | " [4, 6, 2, 9, 2, 8, 0, 7]])" 111 | ] 112 | }, 113 | "execution_count": 4, 114 | "metadata": {}, 115 | "output_type": "execute_result" 116 | } 117 | ], 118 | "source": [ 119 | "Y = np.random.randint(0, 10, (8, 8))\n", 120 | "Y" 121 | ] 122 | }, 123 | { 124 | "cell_type": "code", 125 | "execution_count": 5, 126 | "metadata": { 127 | "collapsed": false 128 | }, 129 | "outputs": [ 130 | { 131 | "data": { 132 | "text/plain": [ 133 | "array([[189, 112, 108, 174, 156, 131, 190, 143],\n", 134 | " [239, 153, 228, 210, 228, 186, 242, 215],\n", 135 | " [100, 106, 82, 144, 67, 115, 78, 90],\n", 136 | " [194, 104, 105, 181, 137, 137, 175, 164],\n", 137 | " [196, 90, 186, 153, 201, 122, 187, 157],\n", 138 | " [162, 165, 102, 226, 147, 156, 129, 182],\n", 139 | " [122, 72, 99, 122, 84, 109, 98, 111],\n", 140 | " [170, 113, 162, 152, 165, 135, 165, 167]])" 141 | ] 142 | }, 143 | "execution_count": 5, 144 | "metadata": {}, 145 | "output_type": "execute_result" 146 | } 147 | ], 148 | "source": [ 149 | "strassen(X, Y)" 150 | ] 151 | }, 152 | { 153 | "cell_type": "code", 154 | "execution_count": null, 155 | "metadata": { 156 | "collapsed": true 157 | }, 158 | "outputs": [], 159 | "source": [] 160 | } 161 | ], 162 | "metadata": { 163 | "kernelspec": { 164 | "display_name": "Python 3", 165 | "language": "python", 166 | "name": "python3" 167 | }, 168 | "language_info": { 169 | "codemirror_mode": { 170 | "name": "ipython", 171 | "version": 3 172 | }, 173 | "file_extension": ".py", 174 | "mimetype": "text/x-python", 175 | "name": "python", 176 | "nbconvert_exporter": "python", 177 | "pygments_lexer": "ipython3", 178 | "version": "3.6.0" 179 | } 180 | }, 181 | "nbformat": 4, 182 | "nbformat_minor": 2 183 | } 184 | -------------------------------------------------------------------------------- /day 34 - aho-corasick.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": 1, 6 | "metadata": { 7 | "collapsed": false 8 | }, 9 | "outputs": [], 10 | "source": [ 11 | "from collections import deque, defaultdict\n", 12 | "from itertools import count" 13 | ] 14 | }, 15 | { 16 | "cell_type": "markdown", 17 | "metadata": {}, 18 | "source": [ 19 | "## algorithm" 20 | ] 21 | }, 22 | { 23 | "cell_type": "code", 24 | "execution_count": 2, 25 | "metadata": { 26 | "collapsed": true 27 | }, 28 | "outputs": [], 29 | "source": [ 30 | "def aho_corasick():\n", 31 | " G = defaultdict(count(1).__next__) # transitions\n", 32 | " W = defaultdict(set) # alphabet\n", 33 | " F = defaultdict(lambda: 0) # fallbacks\n", 34 | " O = defaultdict(set) # outputs\n", 35 | " \n", 36 | " # automaton\n", 37 | " return G, W, F, O" 38 | ] 39 | }, 40 | { 41 | "cell_type": "code", 42 | "execution_count": 3, 43 | "metadata": { 44 | "collapsed": true 45 | }, 46 | "outputs": [], 47 | "source": [ 48 | "def add_word(word, G, W, F, O):\n", 49 | " state = 0\n", 50 | "\n", 51 | " # add transitions between states\n", 52 | " for w in word:\n", 53 | " W[state].add(w)\n", 54 | " state = G[state, w]\n", 55 | " \n", 56 | " # add output\n", 57 | " O[state].add(word)" 58 | ] 59 | }, 60 | { 61 | "cell_type": "code", 62 | "execution_count": 4, 63 | "metadata": { 64 | "collapsed": false 65 | }, 66 | "outputs": [], 67 | "source": [ 68 | "def build_fsa(G, W, F, O):\n", 69 | " # initial states\n", 70 | " queue = deque(G[0, w] for w in W[0])\n", 71 | " \n", 72 | " while queue:\n", 73 | " state = queue.popleft()\n", 74 | " \n", 75 | " # for each letter in alphabet\n", 76 | " for w in W[state]:\n", 77 | " # find fallback state\n", 78 | " t = F[state]\n", 79 | " while t and (t, w) not in G:\n", 80 | " t = F[t]\n", 81 | " \n", 82 | " # for next state define its fallback and output\n", 83 | " s = G[state, w]\n", 84 | " F[s] = G[t, w] if (t, w) in G else 0\n", 85 | " O[s] |= O[F[s]]\n", 86 | " \n", 87 | " queue.append(s)" 88 | ] 89 | }, 90 | { 91 | "cell_type": "code", 92 | "execution_count": 5, 93 | "metadata": { 94 | "collapsed": true 95 | }, 96 | "outputs": [], 97 | "source": [ 98 | "def search(text, G, W, F, O):\n", 99 | " state = 0\n", 100 | " \n", 101 | " for i, t in enumerate(text):\n", 102 | " # fallback\n", 103 | " while state and (state, t) not in G:\n", 104 | " state = F[state]\n", 105 | " \n", 106 | " # transition\n", 107 | " state = G[state, t] if (state, t) in G else 0\n", 108 | " \n", 109 | " # output\n", 110 | " if O[state]:\n", 111 | " print('@', i, O[state])" 112 | ] 113 | }, 114 | { 115 | "cell_type": "markdown", 116 | "metadata": {}, 117 | "source": [ 118 | "## run" 119 | ] 120 | }, 121 | { 122 | "cell_type": "code", 123 | "execution_count": 6, 124 | "metadata": { 125 | "collapsed": false 126 | }, 127 | "outputs": [], 128 | "source": [ 129 | "AC = aho_corasick()\n", 130 | "add_word('bar', *AC)\n", 131 | "add_word('ara', *AC)\n", 132 | "add_word('bara', *AC)\n", 133 | "add_word('barbara', *AC)\n", 134 | "build_fsa(*AC)" 135 | ] 136 | }, 137 | { 138 | "cell_type": "code", 139 | "execution_count": 7, 140 | "metadata": { 141 | "collapsed": false 142 | }, 143 | "outputs": [ 144 | { 145 | "name": "stdout", 146 | "output_type": "stream", 147 | "text": [ 148 | "@ 2 {'bar'}\n", 149 | "@ 5 {'bar'}\n", 150 | "@ 12 {'bar'}\n", 151 | "@ 15 {'bar'}\n", 152 | "@ 16 {'ara', 'barbara', 'bara'}\n", 153 | "@ 26 {'bar'}\n", 154 | "@ 27 {'ara', 'bara'}\n" 155 | ] 156 | } 157 | ], 158 | "source": [ 159 | "search('barbarian barbara said: barabum', *AC)" 160 | ] 161 | }, 162 | { 163 | "cell_type": "code", 164 | "execution_count": null, 165 | "metadata": { 166 | "collapsed": true 167 | }, 168 | "outputs": [], 169 | "source": [] 170 | } 171 | ], 172 | "metadata": { 173 | "kernelspec": { 174 | "display_name": "Python 3", 175 | "language": "python", 176 | "name": "python3" 177 | }, 178 | "language_info": { 179 | "codemirror_mode": { 180 | "name": "ipython", 181 | "version": 3 182 | }, 183 | "file_extension": ".py", 184 | "mimetype": "text/x-python", 185 | "name": "python", 186 | "nbconvert_exporter": "python", 187 | "pygments_lexer": "ipython3", 188 | "version": "3.6.0" 189 | } 190 | }, 191 | "nbformat": 4, 192 | "nbformat_minor": 2 193 | } 194 | -------------------------------------------------------------------------------- /day 60 - bloom filter.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": 1, 6 | "metadata": { 7 | "collapsed": true 8 | }, 9 | "outputs": [], 10 | "source": [ 11 | "import numpy as np\n", 12 | "from collections import deque\n", 13 | "from bitarray import bitarray" 14 | ] 15 | }, 16 | { 17 | "cell_type": "markdown", 18 | "metadata": {}, 19 | "source": [ 20 | "## algorithm" 21 | ] 22 | }, 23 | { 24 | "cell_type": "code", 25 | "execution_count": 2, 26 | "metadata": { 27 | "collapsed": false 28 | }, 29 | "outputs": [], 30 | "source": [ 31 | "def ihash(x):\n", 32 | " h = 86813\n", 33 | " while True:\n", 34 | " for i in x:\n", 35 | " h = ((h + i) * 127733) % (1 << 32)\n", 36 | " yield h" 37 | ] 38 | }, 39 | { 40 | "cell_type": "code", 41 | "execution_count": 3, 42 | "metadata": { 43 | "collapsed": true 44 | }, 45 | "outputs": [], 46 | "source": [ 47 | "def bloom_filter(array_bytes, k):\n", 48 | " array = bitarray(array_bytes * 8)\n", 49 | " array.setall(0)\n", 50 | "\n", 51 | " def _hash(x):\n", 52 | " for _, h in zip(range(k), ihash(x)):\n", 53 | " yield h % len(array)\n", 54 | " \n", 55 | " def _add(x):\n", 56 | " for h in _hash(x):\n", 57 | " array[h] = 1\n", 58 | "\n", 59 | " def _contains(x):\n", 60 | " return all(array[h] for h in _hash(x))\n", 61 | "\n", 62 | " return _add, _contains" 63 | ] 64 | }, 65 | { 66 | "cell_type": "code", 67 | "execution_count": 4, 68 | "metadata": { 69 | "collapsed": true 70 | }, 71 | "outputs": [], 72 | "source": [ 73 | "def measure_accuracy(A, B, array_bytes, k):\n", 74 | " add, contains = bloom_filter(array_bytes, k)\n", 75 | " \n", 76 | " # store A\n", 77 | " deque((add(x) for x in A), 0)\n", 78 | "\n", 79 | " # find false positives in B\n", 80 | " fp = sum(contains(x) for x in B)\n", 81 | "\n", 82 | " # result\n", 83 | " acc = 1 - fp / len(B)\n", 84 | " print('{} hashes, {} false positives, {:.4f} accuracy'.format(k, fp, acc))" 85 | ] 86 | }, 87 | { 88 | "cell_type": "markdown", 89 | "metadata": {}, 90 | "source": [ 91 | "## run" 92 | ] 93 | }, 94 | { 95 | "cell_type": "code", 96 | "execution_count": 5, 97 | "metadata": { 98 | "collapsed": false 99 | }, 100 | "outputs": [ 101 | { 102 | "data": { 103 | "text/plain": [ 104 | "(999891, 999659)" 105 | ] 106 | }, 107 | "execution_count": 5, 108 | "metadata": {}, 109 | "output_type": "execute_result" 110 | } 111 | ], 112 | "source": [ 113 | "n = 10 ** 6\n", 114 | "A = set(map(tuple, np.random.randint(0, 256, (n, 4))))\n", 115 | "B = set(map(tuple, np.random.randint(0, 256, (n, 4)))) - A\n", 116 | "len(A), len(B)" 117 | ] 118 | }, 119 | { 120 | "cell_type": "code", 121 | "execution_count": 6, 122 | "metadata": { 123 | "collapsed": false 124 | }, 125 | "outputs": [ 126 | { 127 | "name": "stdout", 128 | "output_type": "stream", 129 | "text": [ 130 | "1 hashes, 117551 false positives, 0.8824 accuracy\n", 131 | "2 hashes, 66855 false positives, 0.9331 accuracy\n", 132 | "3 hashes, 40262 false positives, 0.9597 accuracy\n", 133 | "4 hashes, 61965 false positives, 0.9380 accuracy\n" 134 | ] 135 | } 136 | ], 137 | "source": [ 138 | "for k in [1, 2, 3, 4]:\n", 139 | " measure_accuracy(A, B, n, k)" 140 | ] 141 | }, 142 | { 143 | "cell_type": "code", 144 | "execution_count": 7, 145 | "metadata": { 146 | "collapsed": false 147 | }, 148 | "outputs": [ 149 | { 150 | "name": "stdout", 151 | "output_type": "stream", 152 | "text": [ 153 | "1 hashes, 30693 false positives, 0.9693 accuracy\n", 154 | "2 hashes, 5479 false positives, 0.9945 accuracy\n", 155 | "4 hashes, 937 false positives, 0.9991 accuracy\n", 156 | "6 hashes, 326 false positives, 0.9997 accuracy\n", 157 | "8 hashes, 454 false positives, 0.9995 accuracy\n" 158 | ] 159 | } 160 | ], 161 | "source": [ 162 | "for k in [1, 2, 4, 6, 8]:\n", 163 | " measure_accuracy(A, B, n * 4, k)" 164 | ] 165 | }, 166 | { 167 | "cell_type": "code", 168 | "execution_count": null, 169 | "metadata": { 170 | "collapsed": true 171 | }, 172 | "outputs": [], 173 | "source": [] 174 | } 175 | ], 176 | "metadata": { 177 | "kernelspec": { 178 | "display_name": "Python 3", 179 | "language": "python", 180 | "name": "python3" 181 | }, 182 | "language_info": { 183 | "codemirror_mode": { 184 | "name": "ipython", 185 | "version": 3 186 | }, 187 | "file_extension": ".py", 188 | "mimetype": "text/x-python", 189 | "name": "python", 190 | "nbconvert_exporter": "python", 191 | "pygments_lexer": "ipython3", 192 | "version": "3.6.0" 193 | } 194 | }, 195 | "nbformat": 4, 196 | "nbformat_minor": 2 197 | } 198 | -------------------------------------------------------------------------------- /day 24 - closest pair.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": 1, 6 | "metadata": { 7 | "collapsed": true 8 | }, 9 | "outputs": [], 10 | "source": [ 11 | "import numpy as np" 12 | ] 13 | }, 14 | { 15 | "cell_type": "markdown", 16 | "metadata": {}, 17 | "source": [ 18 | "## algorithm" 19 | ] 20 | }, 21 | { 22 | "cell_type": "code", 23 | "execution_count": 2, 24 | "metadata": { 25 | "collapsed": true 26 | }, 27 | "outputs": [], 28 | "source": [ 29 | "l1x = lambda a, b: abs(a[0] - b[0])\n", 30 | "l1y = lambda a, b: abs(a[1] - b[1])\n", 31 | "l2 = lambda a, b: np.sqrt((a[0] - b[0]) ** 2 + (a[1] - b[1]) ** 2)" 32 | ] 33 | }, 34 | { 35 | "cell_type": "code", 36 | "execution_count": 3, 37 | "metadata": { 38 | "collapsed": true 39 | }, 40 | "outputs": [], 41 | "source": [ 42 | "def merge(points_y, l, m, r):\n", 43 | " i, j, aux = l, m, []\n", 44 | " while i < m or j < r:\n", 45 | " if i < m and j < r and points_y[i][1] > points_y[j][1]:\n", 46 | " aux.append(points_y[j])\n", 47 | " j += 1\n", 48 | " elif i < m:\n", 49 | " aux.append(points_y[i])\n", 50 | " i += 1\n", 51 | " else:\n", 52 | " aux.append(points_y[j])\n", 53 | " j += 1\n", 54 | " points_y[l:r] = aux" 55 | ] 56 | }, 57 | { 58 | "cell_type": "code", 59 | "execution_count": 4, 60 | "metadata": { 61 | "collapsed": true 62 | }, 63 | "outputs": [], 64 | "source": [ 65 | "def search(points_x, points_y, l, r):\n", 66 | " if r - l < 2:\n", 67 | " return np.inf\n", 68 | "\n", 69 | " m = (l + r) // 2\n", 70 | "\n", 71 | " # search inside partitions\n", 72 | " delta1 = search(points_x, points_y, l, m)\n", 73 | " delta2 = search(points_x, points_y, m, r)\n", 74 | " delta = min(delta1, delta2)\n", 75 | "\n", 76 | " # sort points by y\n", 77 | " merge(points_y, l, m, r)\n", 78 | "\n", 79 | " # find the middle band in delta of x\n", 80 | " q = points[m]\n", 81 | " band = [p for p in points_y[l:r] if l1x(p, q) < delta]\n", 82 | "\n", 83 | " # search the middle band in delta of y\n", 84 | " for i in range(len(band)):\n", 85 | " p1 = band[i]\n", 86 | " for j in range(i + 1, len(band)):\n", 87 | " p2 = band[j]\n", 88 | " if l1y(p1, p2) < delta:\n", 89 | " delta = min(delta, l2(p1, p2))\n", 90 | " else:\n", 91 | " break\n", 92 | "\n", 93 | " # min distance\n", 94 | " return delta" 95 | ] 96 | }, 97 | { 98 | "cell_type": "code", 99 | "execution_count": 5, 100 | "metadata": { 101 | "collapsed": false 102 | }, 103 | "outputs": [], 104 | "source": [ 105 | "def closest_pair(points):\n", 106 | " points = sorted(points)\n", 107 | " return search(points, points[:], 0, len(points))" 108 | ] 109 | }, 110 | { 111 | "cell_type": "markdown", 112 | "metadata": {}, 113 | "source": [ 114 | "## run" 115 | ] 116 | }, 117 | { 118 | "cell_type": "code", 119 | "execution_count": 6, 120 | "metadata": { 121 | "collapsed": false 122 | }, 123 | "outputs": [ 124 | { 125 | "data": { 126 | "text/plain": [ 127 | "[(0.098408754012625277, 0.74280296333228502),\n", 128 | " (0.077086466963399936, 0.29657822643731369),\n", 129 | " (0.56160732190468798, 0.54675608365280715),\n", 130 | " (0.82076413876723719, 0.3014490061746683),\n", 131 | " (0.42758995432097113, 0.19199854966752694)]" 132 | ] 133 | }, 134 | "execution_count": 6, 135 | "metadata": {}, 136 | "output_type": "execute_result" 137 | } 138 | ], 139 | "source": [ 140 | "points = [tuple(i) for i in np.random.rand(100, 2)]\n", 141 | "points[:5]" 142 | ] 143 | }, 144 | { 145 | "cell_type": "code", 146 | "execution_count": 7, 147 | "metadata": { 148 | "collapsed": false 149 | }, 150 | "outputs": [ 151 | { 152 | "data": { 153 | "text/plain": [ 154 | "0.012360394883333799" 155 | ] 156 | }, 157 | "execution_count": 7, 158 | "metadata": {}, 159 | "output_type": "execute_result" 160 | } 161 | ], 162 | "source": [ 163 | "closest_pair(points)" 164 | ] 165 | }, 166 | { 167 | "cell_type": "code", 168 | "execution_count": null, 169 | "metadata": { 170 | "collapsed": true 171 | }, 172 | "outputs": [], 173 | "source": [] 174 | } 175 | ], 176 | "metadata": { 177 | "kernelspec": { 178 | "display_name": "Python 3", 179 | "language": "python", 180 | "name": "python3" 181 | }, 182 | "language_info": { 183 | "codemirror_mode": { 184 | "name": "ipython", 185 | "version": 3 186 | }, 187 | "file_extension": ".py", 188 | "mimetype": "text/x-python", 189 | "name": "python", 190 | "nbconvert_exporter": "python", 191 | "pygments_lexer": "ipython3", 192 | "version": "3.6.0" 193 | } 194 | }, 195 | "nbformat": 4, 196 | "nbformat_minor": 2 197 | } 198 | -------------------------------------------------------------------------------- /day 58 - integer exponentation.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": 1, 6 | "metadata": { 7 | "collapsed": true 8 | }, 9 | "outputs": [], 10 | "source": [ 11 | "import numpy as np" 12 | ] 13 | }, 14 | { 15 | "cell_type": "markdown", 16 | "metadata": {}, 17 | "source": [ 18 | "## algorithm" 19 | ] 20 | }, 21 | { 22 | "cell_type": "code", 23 | "execution_count": 2, 24 | "metadata": { 25 | "collapsed": true 26 | }, 27 | "outputs": [], 28 | "source": [ 29 | "def _power(x, y, identity=None, op=None):\n", 30 | " p = identity\n", 31 | "\n", 32 | " while y:\n", 33 | " p = op(p, x) if y & 1 else p\n", 34 | " x = op(x, x)\n", 35 | " y >>= 1\n", 36 | "\n", 37 | " return p" 38 | ] 39 | }, 40 | { 41 | "cell_type": "code", 42 | "execution_count": 3, 43 | "metadata": { 44 | "collapsed": true 45 | }, 46 | "outputs": [], 47 | "source": [ 48 | "def power(x, y):\n", 49 | " return _power(x, y, identity=type(x)(1), op=type(x).__mul__)" 50 | ] 51 | }, 52 | { 53 | "cell_type": "code", 54 | "execution_count": 4, 55 | "metadata": { 56 | "collapsed": true 57 | }, 58 | "outputs": [], 59 | "source": [ 60 | "def mod_power(x, y, n):\n", 61 | " return _power(x, y, \n", 62 | " identity=1,\n", 63 | " op=lambda a, b: (a * b) % n)" 64 | ] 65 | }, 66 | { 67 | "cell_type": "code", 68 | "execution_count": 5, 69 | "metadata": { 70 | "collapsed": true 71 | }, 72 | "outputs": [], 73 | "source": [ 74 | "def matrix_power(x, y):\n", 75 | " return _power(x, y, \n", 76 | " identity=np.eye(x.shape[0], dtype=x.dtype),\n", 77 | " op=np.ndarray.__matmul__)" 78 | ] 79 | }, 80 | { 81 | "cell_type": "markdown", 82 | "metadata": {}, 83 | "source": [ 84 | "## run" 85 | ] 86 | }, 87 | { 88 | "cell_type": "code", 89 | "execution_count": 6, 90 | "metadata": { 91 | "collapsed": false 92 | }, 93 | "outputs": [ 94 | { 95 | "data": { 96 | "text/plain": [ 97 | "(1267650600228229401496703205376, 1267650600228229401496703205376)" 98 | ] 99 | }, 100 | "execution_count": 6, 101 | "metadata": {}, 102 | "output_type": "execute_result" 103 | } 104 | ], 105 | "source": [ 106 | "power(2, 100), 2 ** 100" 107 | ] 108 | }, 109 | { 110 | "cell_type": "code", 111 | "execution_count": 7, 112 | "metadata": { 113 | "collapsed": false 114 | }, 115 | "outputs": [ 116 | { 117 | "data": { 118 | "text/plain": [ 119 | "(1.2676506002282294e+30, 1.2676506002282294e+30)" 120 | ] 121 | }, 122 | "execution_count": 7, 123 | "metadata": {}, 124 | "output_type": "execute_result" 125 | } 126 | ], 127 | "source": [ 128 | "power(2., 100), 2. ** 100" 129 | ] 130 | }, 131 | { 132 | "cell_type": "code", 133 | "execution_count": 8, 134 | "metadata": { 135 | "collapsed": false 136 | }, 137 | "outputs": [ 138 | { 139 | "data": { 140 | "text/plain": [ 141 | "(562, 562)" 142 | ] 143 | }, 144 | "execution_count": 8, 145 | "metadata": {}, 146 | "output_type": "execute_result" 147 | } 148 | ], 149 | "source": [ 150 | "mod_power(2, 100, 1001), (2 ** 100) % 1001" 151 | ] 152 | }, 153 | { 154 | "cell_type": "code", 155 | "execution_count": 9, 156 | "metadata": { 157 | "collapsed": false 158 | }, 159 | "outputs": [ 160 | { 161 | "data": { 162 | "text/plain": [ 163 | "array([[ 1, 1000],\n", 164 | " [ 0, 1]])" 165 | ] 166 | }, 167 | "execution_count": 9, 168 | "metadata": {}, 169 | "output_type": "execute_result" 170 | } 171 | ], 172 | "source": [ 173 | "matrix_power(np.array([[1, 1], [0, 1]]), 1000)" 174 | ] 175 | }, 176 | { 177 | "cell_type": "code", 178 | "execution_count": 10, 179 | "metadata": { 180 | "collapsed": false 181 | }, 182 | "outputs": [ 183 | { 184 | "data": { 185 | "text/plain": [ 186 | "array([[ 2.67041885e+111, 3.44456780e+111, 4.21871675e+111],\n", 187 | " [ 8.19736832e+111, 1.05737686e+112, 1.29501688e+112],\n", 188 | " [ 1.37243178e+112, 1.77029694e+112, 2.16816209e+112]])" 189 | ] 190 | }, 191 | "execution_count": 10, 192 | "metadata": {}, 193 | "output_type": "execute_result" 194 | } 195 | ], 196 | "source": [ 197 | "matrix_power(np.arange(9, dtype=float).reshape(3, 3), 100)" 198 | ] 199 | }, 200 | { 201 | "cell_type": "code", 202 | "execution_count": null, 203 | "metadata": { 204 | "collapsed": false 205 | }, 206 | "outputs": [], 207 | "source": [] 208 | } 209 | ], 210 | "metadata": { 211 | "kernelspec": { 212 | "display_name": "Python 3", 213 | "language": "python", 214 | "name": "python3" 215 | }, 216 | "language_info": { 217 | "codemirror_mode": { 218 | "name": "ipython", 219 | "version": 3 220 | }, 221 | "file_extension": ".py", 222 | "mimetype": "text/x-python", 223 | "name": "python", 224 | "nbconvert_exporter": "python", 225 | "pygments_lexer": "ipython3", 226 | "version": "3.6.0" 227 | } 228 | }, 229 | "nbformat": 4, 230 | "nbformat_minor": 2 231 | } 232 | -------------------------------------------------------------------------------- /day 62 - linked-list cycle.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "## algorithm" 8 | ] 9 | }, 10 | { 11 | "cell_type": "code", 12 | "execution_count": 1, 13 | "metadata": { 14 | "collapsed": false 15 | }, 16 | "outputs": [], 17 | "source": [ 18 | "def detect_cycle(head):\n", 19 | " if not head:\n", 20 | " return\n", 21 | " \n", 22 | " # cycle detection: 2k = k (mod C)\n", 23 | " p, q = head, head.next\n", 24 | " while q and p is not q:\n", 25 | " p, q = p.next, q.next and q.next.next\n", 26 | "\n", 27 | " if p is q:\n", 28 | " # cycle removal: k + T = 0 (mod C)\n", 29 | " p = head\n", 30 | " while p is not q.next:\n", 31 | " p, q = p.next, q.next\n", 32 | " \n", 33 | " # fix the last link\n", 34 | " q.next = None\n", 35 | " return q" 36 | ] 37 | }, 38 | { 39 | "cell_type": "markdown", 40 | "metadata": {}, 41 | "source": [ 42 | "## utilities" 43 | ] 44 | }, 45 | { 46 | "cell_type": "code", 47 | "execution_count": 2, 48 | "metadata": { 49 | "collapsed": true 50 | }, 51 | "outputs": [], 52 | "source": [ 53 | "class Node:\n", 54 | " def __init__(self, **kwargs):\n", 55 | " self.__dict__ = kwargs\n", 56 | " \n", 57 | " def __repr__(self):\n", 58 | " return str(self.__dict__)" 59 | ] 60 | }, 61 | { 62 | "cell_type": "code", 63 | "execution_count": 3, 64 | "metadata": { 65 | "collapsed": true 66 | }, 67 | "outputs": [], 68 | "source": [ 69 | "def linked_list_with_cycle(length, cycle):\n", 70 | " head, tail = None, None\n", 71 | " \n", 72 | " for i in range(length):\n", 73 | " # prepend head\n", 74 | " head = Node(value=length - i, next=head)\n", 75 | " tail = tail or head\n", 76 | " \n", 77 | " # make cycle of length C\n", 78 | " if i + 1 == cycle:\n", 79 | " tail.next = head\n", 80 | " \n", 81 | " return head" 82 | ] 83 | }, 84 | { 85 | "cell_type": "markdown", 86 | "metadata": {}, 87 | "source": [ 88 | "## run" 89 | ] 90 | }, 91 | { 92 | "cell_type": "code", 93 | "execution_count": 4, 94 | "metadata": { 95 | "collapsed": false 96 | }, 97 | "outputs": [ 98 | { 99 | "name": "stdout", 100 | "output_type": "stream", 101 | "text": [ 102 | "{'value': 1, 'next': {'value': 2, 'next': {'value': 3, 'next': {'value': 4, 'next': {'value': 5, 'next': {'value': 6, 'next': {'value': 7, 'next': {'value': 8, 'next': {'value': 9, 'next': {'value': 10, 'next': {...}}}}}}}}}}}\n" 103 | ] 104 | }, 105 | { 106 | "data": { 107 | "text/plain": [ 108 | "{'value': 10, 'next': None}" 109 | ] 110 | }, 111 | "execution_count": 4, 112 | "metadata": {}, 113 | "output_type": "execute_result" 114 | } 115 | ], 116 | "source": [ 117 | "linked_list = linked_list_with_cycle(10, 4)\n", 118 | "print(linked_list)\n", 119 | "detect_cycle(linked_list)" 120 | ] 121 | }, 122 | { 123 | "cell_type": "code", 124 | "execution_count": 5, 125 | "metadata": { 126 | "collapsed": false 127 | }, 128 | "outputs": [ 129 | { 130 | "data": { 131 | "text/plain": [ 132 | "{'value': 5, 'next': None}" 133 | ] 134 | }, 135 | "execution_count": 5, 136 | "metadata": {}, 137 | "output_type": "execute_result" 138 | } 139 | ], 140 | "source": [ 141 | "linked_list = linked_list_with_cycle(5, 1)\n", 142 | "detect_cycle(linked_list)" 143 | ] 144 | }, 145 | { 146 | "cell_type": "code", 147 | "execution_count": 6, 148 | "metadata": { 149 | "collapsed": false 150 | }, 151 | "outputs": [ 152 | { 153 | "data": { 154 | "text/plain": [ 155 | "{'value': 10, 'next': None}" 156 | ] 157 | }, 158 | "execution_count": 6, 159 | "metadata": {}, 160 | "output_type": "execute_result" 161 | } 162 | ], 163 | "source": [ 164 | "linked_list = linked_list_with_cycle(10, 5)\n", 165 | "detect_cycle(linked_list)" 166 | ] 167 | }, 168 | { 169 | "cell_type": "code", 170 | "execution_count": 7, 171 | "metadata": { 172 | "collapsed": false 173 | }, 174 | "outputs": [ 175 | { 176 | "data": { 177 | "text/plain": [ 178 | "{'value': 25, 'next': None}" 179 | ] 180 | }, 181 | "execution_count": 7, 182 | "metadata": {}, 183 | "output_type": "execute_result" 184 | } 185 | ], 186 | "source": [ 187 | "linked_list = linked_list_with_cycle(25, 25)\n", 188 | "detect_cycle(linked_list)" 189 | ] 190 | }, 191 | { 192 | "cell_type": "code", 193 | "execution_count": null, 194 | "metadata": { 195 | "collapsed": true 196 | }, 197 | "outputs": [], 198 | "source": [] 199 | } 200 | ], 201 | "metadata": { 202 | "kernelspec": { 203 | "display_name": "Python 3", 204 | "language": "python", 205 | "name": "python3" 206 | }, 207 | "language_info": { 208 | "codemirror_mode": { 209 | "name": "ipython", 210 | "version": 3 211 | }, 212 | "file_extension": ".py", 213 | "mimetype": "text/x-python", 214 | "name": "python", 215 | "nbconvert_exporter": "python", 216 | "pygments_lexer": "ipython3", 217 | "version": "3.6.0" 218 | } 219 | }, 220 | "nbformat": 4, 221 | "nbformat_minor": 2 222 | } 223 | -------------------------------------------------------------------------------- /day 68 - gale-shapley.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": 1, 6 | "metadata": { 7 | "collapsed": true 8 | }, 9 | "outputs": [], 10 | "source": [ 11 | "from collections import deque, defaultdict" 12 | ] 13 | }, 14 | { 15 | "cell_type": "markdown", 16 | "metadata": {}, 17 | "source": [ 18 | "## algorithm" 19 | ] 20 | }, 21 | { 22 | "cell_type": "code", 23 | "execution_count": 2, 24 | "metadata": { 25 | "collapsed": true 26 | }, 27 | "outputs": [], 28 | "source": [ 29 | "def stable_match(men, women):\n", 30 | " free_men = deque(men)\n", 31 | " engaged = defaultdict(lambda: None)\n", 32 | "\n", 33 | " while free_men:\n", 34 | " i = free_men.popleft()\n", 35 | "\n", 36 | " # man proposes women according his preferences\n", 37 | " for j in men[i]:\n", 38 | " preference = women[j].index\n", 39 | " fiance = engaged[j]\n", 40 | "\n", 41 | " # woman accepts the better offer\n", 42 | " if not fiance or preference(i) < preference(fiance):\n", 43 | " engaged[j] = i\n", 44 | " fiance and free_men.append(fiance)\n", 45 | " break\n", 46 | "\n", 47 | " return [(m, w) for w, m in engaged.items()]" 48 | ] 49 | }, 50 | { 51 | "cell_type": "markdown", 52 | "metadata": {}, 53 | "source": [ 54 | "## run" 55 | ] 56 | }, 57 | { 58 | "cell_type": "code", 59 | "execution_count": 3, 60 | "metadata": { 61 | "collapsed": true 62 | }, 63 | "outputs": [], 64 | "source": [ 65 | "men = {\n", 66 | " 'adam': ['claire', 'diana'],\n", 67 | " 'bob': ['diana', 'claire'],\n", 68 | "}\n", 69 | "women = {\n", 70 | " 'claire': ['bob', 'adam'],\n", 71 | " 'diana': ['adam', 'bob'],\n", 72 | "}" 73 | ] 74 | }, 75 | { 76 | "cell_type": "code", 77 | "execution_count": 4, 78 | "metadata": { 79 | "collapsed": false 80 | }, 81 | "outputs": [ 82 | { 83 | "data": { 84 | "text/plain": [ 85 | "[('adam', 'claire'), ('bob', 'diana')]" 86 | ] 87 | }, 88 | "execution_count": 4, 89 | "metadata": {}, 90 | "output_type": "execute_result" 91 | } 92 | ], 93 | "source": [ 94 | "stable_match(men, women)" 95 | ] 96 | }, 97 | { 98 | "cell_type": "code", 99 | "execution_count": 5, 100 | "metadata": { 101 | "collapsed": true 102 | }, 103 | "outputs": [], 104 | "source": [ 105 | "men = {\n", 106 | " 'adam': ['betty', 'claire', 'diana'],\n", 107 | " 'bob': ['betty', 'claire', 'diana'],\n", 108 | " 'charlie': ['betty', 'claire', 'diana'],\n", 109 | "}\n", 110 | "women = {\n", 111 | " 'betty': ['charlie', 'bob', 'adam'],\n", 112 | " 'claire': ['charlie', 'bob', 'adam'],\n", 113 | " 'diana': ['charlie', 'bob', 'adam'],\n", 114 | "}" 115 | ] 116 | }, 117 | { 118 | "cell_type": "code", 119 | "execution_count": 6, 120 | "metadata": { 121 | "collapsed": false 122 | }, 123 | "outputs": [ 124 | { 125 | "data": { 126 | "text/plain": [ 127 | "[('charlie', 'betty'), ('bob', 'claire'), ('adam', 'diana')]" 128 | ] 129 | }, 130 | "execution_count": 6, 131 | "metadata": {}, 132 | "output_type": "execute_result" 133 | } 134 | ], 135 | "source": [ 136 | "stable_match(men, women)" 137 | ] 138 | }, 139 | { 140 | "cell_type": "code", 141 | "execution_count": 7, 142 | "metadata": { 143 | "collapsed": false 144 | }, 145 | "outputs": [], 146 | "source": [ 147 | "men = {\n", 148 | " 'adam': ['diana', 'alice', 'betty', 'claire'],\n", 149 | " 'bob': ['betty', 'claire', 'alice', 'diana'],\n", 150 | " 'charlie': ['betty', 'diana', 'claire', 'alice'],\n", 151 | " 'david': ['claire', 'alice', 'diana', 'betty'],\n", 152 | "}\n", 153 | "women = {\n", 154 | " 'alice': ['david', 'adam', 'charlie', 'bob'],\n", 155 | " 'betty': ['adam', 'charlie', 'bob', 'david'],\n", 156 | " 'claire': ['adam', 'bob', 'charlie', 'david'],\n", 157 | " 'diana': ['david', 'adam', 'charlie', 'bob'],\n", 158 | "}" 159 | ] 160 | }, 161 | { 162 | "cell_type": "code", 163 | "execution_count": 8, 164 | "metadata": { 165 | "collapsed": false 166 | }, 167 | "outputs": [ 168 | { 169 | "data": { 170 | "text/plain": [ 171 | "[('adam', 'diana'),\n", 172 | " ('charlie', 'betty'),\n", 173 | " ('bob', 'claire'),\n", 174 | " ('david', 'alice')]" 175 | ] 176 | }, 177 | "execution_count": 8, 178 | "metadata": {}, 179 | "output_type": "execute_result" 180 | } 181 | ], 182 | "source": [ 183 | "stable_match(men, women)" 184 | ] 185 | }, 186 | { 187 | "cell_type": "code", 188 | "execution_count": null, 189 | "metadata": { 190 | "collapsed": true 191 | }, 192 | "outputs": [], 193 | "source": [] 194 | } 195 | ], 196 | "metadata": { 197 | "kernelspec": { 198 | "display_name": "Python 3", 199 | "language": "python", 200 | "name": "python3" 201 | }, 202 | "language_info": { 203 | "codemirror_mode": { 204 | "name": "ipython", 205 | "version": 3 206 | }, 207 | "file_extension": ".py", 208 | "mimetype": "text/x-python", 209 | "name": "python", 210 | "nbconvert_exporter": "python", 211 | "pygments_lexer": "ipython3", 212 | "version": "3.6.0" 213 | } 214 | }, 215 | "nbformat": 4, 216 | "nbformat_minor": 2 217 | } 218 | -------------------------------------------------------------------------------- /day 15 - breaking OTP.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "## ciphertext" 8 | ] 9 | }, 10 | { 11 | "cell_type": "code", 12 | "execution_count": 1, 13 | "metadata": { 14 | "collapsed": true 15 | }, 16 | "outputs": [], 17 | "source": [ 18 | "ciphertext = [\n", 19 | " b'm\\x99QH\\xfc\\x99\\xcel\\xfc>\\x11\\xf81\\xda:\\x15\"6\\xd3b\\x07\\x7f\\xed\\x87\\xd5\\xd4\\xf0\\xbb',\n", 20 | " b'x\\x96^\\r\\xb5\\x83\\x86u\\xeel\\x0e\\xf8,\\xce:\\x06 6\\xd0b\\nx\\xfd\\x87\\xd9\\xc9\\xe8',\n", 21 | " b'm\\x90O^\\xfc\\x80\\xd3f\\xe7>\\x16\\xf46\\x89w\\x05r8\\xcb-\\x04',\n", 22 | " b'`\\x97O\\r\\xbd\\x9f\\xc3%\\xe1q\\x0e\\xb15\\xdbu\\x0e5y\\xca*\\x1c7\\xec\\xc2\\xd2\\xcb',\n", 23 | " b\"m\\x90[Y\\xfc\\x80\\xdf%\\xeb\\x7f\\x03\\xe2b\\xc1{\\x167y\\xdf'\\x16y\\xa8\\xc6\\x97\\xc2\\xed\\xa9p(\",\n", 24 | " b'`\\x9dN\\r\\xb5\\x8b\\x86m\\xe0n\\x1f\\xb1*\\xc8i@45\\xd25\\x1d7\\xe9\\xd0\\xd6\\xdf',\n", 25 | " b'p\\x96\\x1aL\\xfc\\x83\\xcfb\\xe7jZ\\xfe0\\x89s\\x0er8\\x9d&\\x12n',\n", 26 | " b'p\\x96\\x1aL\\xfc\\x9b\\xcfv\\xe6q\\x14\\xb1-\\xdb:\\t\\x0e\\xfe0\\xc4\\x7f\\x0e&<\\xd9b\\x00\\x7f\\xe7\\xd5\\xd2',\n", 32 | " b'x\\x96^\\r\\x95\\xcd\\xcej\\xe3zZ\\xe6+\\xddr\\t\\x0e\\xf9'\\x89}\\x0f>=\\xd8,Sd\\xe9\\xc9\\xd3\",\n", 34 | " b'q\\x97M\\r\\xba\\x88\\xd1%\\xf6{\\x0e\\xb1*\\xc6m@&1\\xd8;St\\xfa\\xc2\\xd2\\xd6',\n", 35 | " b'm\\x90HB\\xa9\\x8a\\xce%\\xe2gZ\\xf7+\\xc7}\\x05 *\\x9d6\\x1c7\\xfc\\xcf\\xd2\\x86\\xfb\\xa9t5',\n", 36 | " b'n\\x90SA\\xb9\\xcd\\xcf%\\xf8{\\x1f\\xe1b\\xder\\t><\\x9d\\x0bS`\\xed\\xc2\\xc7',\n", 37 | " b'9\\xd8_I\\xbb\\x8c\\xd4%\\xeer\\x16\\xf0,\\x89j\\x0f7y\\x9dbS7\\xa8\\x87\\x97\\x86\\xbf',\n", 38 | "]" 39 | ] 40 | }, 41 | { 42 | "cell_type": "markdown", 43 | "metadata": {}, 44 | "source": [ 45 | "## algorithm" 46 | ] 47 | }, 48 | { 49 | "cell_type": "code", 50 | "execution_count": 2, 51 | "metadata": { 52 | "collapsed": true 53 | }, 54 | "outputs": [], 55 | "source": [ 56 | "from string import ascii_lowercase\n", 57 | "\n", 58 | "# set of allowed characters\n", 59 | "letters = set(ascii_lowercase + ' ')\n", 60 | "\n", 61 | "# reconstructed messages\n", 62 | "plaintext = [''] * len(ciphertext)\n", 63 | "\n", 64 | "# take all the codes at the same position\n", 65 | "for messages in zip(*ciphertext):\n", 66 | " keys = set()\n", 67 | " \n", 68 | " # find viable keys\n", 69 | " for key in range(256):\n", 70 | " for m in messages:\n", 71 | " if chr(m ^ key) not in letters:\n", 72 | " break\n", 73 | " else:\n", 74 | " keys.add(key)\n", 75 | "\n", 76 | " key = keys.pop() if len(keys) == 1 else None\n", 77 | "\n", 78 | " # reconstruct plaintext\n", 79 | " for i, m in enumerate(messages):\n", 80 | " if key is not None:\n", 81 | " plaintext[i] += chr(m ^ key)\n", 82 | " else:\n", 83 | " plaintext[i] += '?'" 84 | ] 85 | }, 86 | { 87 | "cell_type": "markdown", 88 | "metadata": {}, 89 | "source": [ 90 | "## result" 91 | ] 92 | }, 93 | { 94 | "cell_type": "code", 95 | "execution_count": 3, 96 | "metadata": { 97 | "collapsed": false 98 | }, 99 | "outputs": [ 100 | { 101 | "data": { 102 | "text/plain": [ 103 | "['take?this kiss upon?t',\n", 104 | " 'and ?n parting from?y',\n", 105 | " 'thus?much let me av?w',\n", 106 | " 'you ?re not wrong w?o',\n", 107 | " 'that?my days have b?e',\n", 108 | " 'yet ?f hope has flo?n',\n", 109 | " 'in a?night or in a ?a',\n", 110 | " 'in a?vision or in n?n',\n", 111 | " 'is i? therefore the?l',\n", 112 | " 'all ?hat we see or ?e',\n", 113 | " 'is b?t a dream with?n',\n", 114 | " 'i st?nd amid the ro?r',\n", 115 | " 'of a?surf tormented?s',\n", 116 | " 'and ? hold within m? ',\n", 117 | " 'grai?s of the golde? ',\n", 118 | " 'how ?ew yet how the? ',\n", 119 | " 'thro?gh my fingers ?o',\n", 120 | " 'whil? i weep while ? ',\n", 121 | " ' ed?ar allan poe ? ']" 122 | ] 123 | }, 124 | "execution_count": 3, 125 | "metadata": {}, 126 | "output_type": "execute_result" 127 | } 128 | ], 129 | "source": [ 130 | "plaintext" 131 | ] 132 | }, 133 | { 134 | "cell_type": "code", 135 | "execution_count": null, 136 | "metadata": { 137 | "collapsed": true 138 | }, 139 | "outputs": [], 140 | "source": [] 141 | } 142 | ], 143 | "metadata": { 144 | "kernelspec": { 145 | "display_name": "Python 3", 146 | "language": "python", 147 | "name": "python3" 148 | }, 149 | "language_info": { 150 | "codemirror_mode": { 151 | "name": "ipython", 152 | "version": 3 153 | }, 154 | "file_extension": ".py", 155 | "mimetype": "text/x-python", 156 | "name": "python", 157 | "nbconvert_exporter": "python", 158 | "pygments_lexer": "ipython3", 159 | "version": "3.6.0" 160 | } 161 | }, 162 | "nbformat": 4, 163 | "nbformat_minor": 2 164 | } 165 | -------------------------------------------------------------------------------- /day 31 - timeit.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": 1, 6 | "metadata": { 7 | "collapsed": true 8 | }, 9 | "outputs": [], 10 | "source": [ 11 | "import numpy as np\n", 12 | "from time import perf_counter\n", 13 | "from itertools import combinations" 14 | ] 15 | }, 16 | { 17 | "cell_type": "markdown", 18 | "metadata": {}, 19 | "source": [ 20 | "## algorithm" 21 | ] 22 | }, 23 | { 24 | "cell_type": "code", 25 | "execution_count": 2, 26 | "metadata": { 27 | "collapsed": true 28 | }, 29 | "outputs": [], 30 | "source": [ 31 | "def timeit(fn, fargs, n_range, seconds=5):\n", 32 | " print(f'[timeit] {seconds} seconds per N')\n", 33 | " \n", 34 | " # timeit for N\n", 35 | " bench = []\n", 36 | " for n in n_range:\n", 37 | " args = fargs(n)\n", 38 | " calls = 0\n", 39 | "\n", 40 | " # benchmark\n", 41 | " timer = perf_counter()\n", 42 | " while perf_counter() - timer < seconds:\n", 43 | " fn(args)\n", 44 | " calls += 1\n", 45 | " timer = perf_counter() - timer\n", 46 | "\n", 47 | " # results\n", 48 | " bench.append([np.e, n, timer / calls])\n", 49 | " print(f'[N={n}] {calls / timer:.2f} calls/sec')\n", 50 | "\n", 51 | " # estimate complexity\n", 52 | " bench = np.log(bench)\n", 53 | " (alpha, beta), *_ = np.linalg.lstsq(bench[:, :2], bench[:, -1])\n", 54 | " print(f'estimated O({np.exp(alpha):.3} * N ^ {beta:.3f})')" 55 | ] 56 | }, 57 | { 58 | "cell_type": "markdown", 59 | "metadata": {}, 60 | "source": [ 61 | "## setup" 62 | ] 63 | }, 64 | { 65 | "cell_type": "code", 66 | "execution_count": 3, 67 | "metadata": { 68 | "collapsed": false 69 | }, 70 | "outputs": [], 71 | "source": [ 72 | "def combinatorial_sort(data):\n", 73 | " data = data.copy()\n", 74 | " for i, j in combinations(range(len(data)), 2):\n", 75 | " if data[i] > data[j]:\n", 76 | " data[i], data[j] = data[j], data[i]\n", 77 | " return data" 78 | ] 79 | }, 80 | { 81 | "cell_type": "code", 82 | "execution_count": 4, 83 | "metadata": { 84 | "collapsed": true 85 | }, 86 | "outputs": [], 87 | "source": [ 88 | "def get_array(n):\n", 89 | " return np.random.randint(0, n, n)" 90 | ] 91 | }, 92 | { 93 | "cell_type": "markdown", 94 | "metadata": {}, 95 | "source": [ 96 | "## built-in sorted" 97 | ] 98 | }, 99 | { 100 | "cell_type": "code", 101 | "execution_count": 5, 102 | "metadata": { 103 | "collapsed": false 104 | }, 105 | "outputs": [ 106 | { 107 | "name": "stdout", 108 | "output_type": "stream", 109 | "text": [ 110 | "[timeit] 5 seconds per N\n", 111 | "[N=100] 44502.77 calls/sec\n", 112 | "[N=1000] 3092.61 calls/sec\n", 113 | "[N=10000] 231.72 calls/sec\n", 114 | "[N=100000] 16.99 calls/sec\n", 115 | "[N=1000000] 1.06 calls/sec\n", 116 | "estimated O(1.11e-07 * N ^ 1.151)\n" 117 | ] 118 | } 119 | ], 120 | "source": [ 121 | "n_range = [100, 1000, 10000, 100000, 1000000]\n", 122 | "timeit(sorted, get_array, n_range)" 123 | ] 124 | }, 125 | { 126 | "cell_type": "markdown", 127 | "metadata": {}, 128 | "source": [ 129 | "## numpy sort" 130 | ] 131 | }, 132 | { 133 | "cell_type": "code", 134 | "execution_count": 6, 135 | "metadata": { 136 | "collapsed": false 137 | }, 138 | "outputs": [ 139 | { 140 | "name": "stdout", 141 | "output_type": "stream", 142 | "text": [ 143 | "[timeit] 5 seconds per N\n", 144 | "[N=100] 304622.14 calls/sec\n", 145 | "[N=1000] 55807.77 calls/sec\n", 146 | "[N=10000] 1966.49 calls/sec\n", 147 | "[N=100000] 164.66 calls/sec\n", 148 | "[N=1000000] 13.92 calls/sec\n", 149 | "estimated O(1.38e-08 * N ^ 1.121)\n" 150 | ] 151 | } 152 | ], 153 | "source": [ 154 | "n_range = [100, 1000, 10000, 100000, 1000000]\n", 155 | "timeit(np.sort, get_array, n_range)" 156 | ] 157 | }, 158 | { 159 | "cell_type": "markdown", 160 | "metadata": {}, 161 | "source": [ 162 | "## combinatorial sort" 163 | ] 164 | }, 165 | { 166 | "cell_type": "code", 167 | "execution_count": 7, 168 | "metadata": { 169 | "collapsed": false 170 | }, 171 | "outputs": [ 172 | { 173 | "name": "stdout", 174 | "output_type": "stream", 175 | "text": [ 176 | "[timeit] 5 seconds per N\n", 177 | "[N=10] 49694.04 calls/sec\n", 178 | "[N=50] 2011.77 calls/sec\n", 179 | "[N=100] 515.40 calls/sec\n", 180 | "[N=500] 19.56 calls/sec\n", 181 | "[N=1000] 4.74 calls/sec\n", 182 | "estimated O(1.92e-07 * N ^ 2.010)\n" 183 | ] 184 | } 185 | ], 186 | "source": [ 187 | "n_range = [10, 50, 100, 500, 1000]\n", 188 | "timeit(combinatorial_sort, get_array, n_range)" 189 | ] 190 | }, 191 | { 192 | "cell_type": "code", 193 | "execution_count": null, 194 | "metadata": { 195 | "collapsed": true 196 | }, 197 | "outputs": [], 198 | "source": [] 199 | } 200 | ], 201 | "metadata": { 202 | "kernelspec": { 203 | "display_name": "Python 3", 204 | "language": "python", 205 | "name": "python3" 206 | }, 207 | "language_info": { 208 | "codemirror_mode": { 209 | "name": "ipython", 210 | "version": 3 211 | }, 212 | "file_extension": ".py", 213 | "mimetype": "text/x-python", 214 | "name": "python", 215 | "nbconvert_exporter": "python", 216 | "pygments_lexer": "ipython3", 217 | "version": "3.6.0" 218 | } 219 | }, 220 | "nbformat": 4, 221 | "nbformat_minor": 2 222 | } 223 | -------------------------------------------------------------------------------- /day 59 - colored tiling.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": 1, 6 | "metadata": { 7 | "collapsed": true 8 | }, 9 | "outputs": [], 10 | "source": [ 11 | "import numpy as np\n", 12 | "from collections import deque" 13 | ] 14 | }, 15 | { 16 | "cell_type": "markdown", 17 | "metadata": {}, 18 | "source": [ 19 | "## algorithm" 20 | ] 21 | }, 22 | { 23 | "cell_type": "code", 24 | "execution_count": 2, 25 | "metadata": { 26 | "collapsed": true 27 | }, 28 | "outputs": [], 29 | "source": [ 30 | "def add(wall, row, col, tile):\n", 31 | " assert np.all(wall[row, col, :] == -1)\n", 32 | " \n", 33 | " # check neighbours if the tile fits\n", 34 | " for i, j, m, n in [[-1, 0, 3, 0], [1, 0, 0, 3], [0, -1, 1, 2], [0, 1, 2, 1]]:\n", 35 | " t = wall[row + i, col + j, m]\n", 36 | " if t != -1 and t != tile[n]:\n", 37 | " return False\n", 38 | "\n", 39 | " # add the tile\n", 40 | " wall[row, col, :] = tile\n", 41 | " return True" 42 | ] 43 | }, 44 | { 45 | "cell_type": "code", 46 | "execution_count": 3, 47 | "metadata": { 48 | "collapsed": true 49 | }, 50 | "outputs": [], 51 | "source": [ 52 | "def remove(wall, row, col):\n", 53 | " wall[row, col, :] = -1" 54 | ] 55 | }, 56 | { 57 | "cell_type": "code", 58 | "execution_count": 4, 59 | "metadata": { 60 | "collapsed": true 61 | }, 62 | "outputs": [], 63 | "source": [ 64 | "def solve(wall, tiles, row=1, col=1):\n", 65 | " # carry on the next row\n", 66 | " if col == wall.shape[1] - 1:\n", 67 | " row += 1\n", 68 | " col = 1\n", 69 | "\n", 70 | " # solution found\n", 71 | " if row == wall.shape[0] - 1:\n", 72 | " return True\n", 73 | "\n", 74 | " # try each tile\n", 75 | " for i in range(len(tiles)):\n", 76 | " tile = tiles.popleft()\n", 77 | "\n", 78 | " if add(wall, row, col, tile):\n", 79 | " # backtrack\n", 80 | " if solve(wall, tiles, row, col + 1):\n", 81 | " return True\n", 82 | " remove(wall, row, col)\n", 83 | "\n", 84 | " tiles.append(tile)" 85 | ] 86 | }, 87 | { 88 | "cell_type": "markdown", 89 | "metadata": {}, 90 | "source": [ 91 | "## wall" 92 | ] 93 | }, 94 | { 95 | "cell_type": "code", 96 | "execution_count": 5, 97 | "metadata": { 98 | "collapsed": true 99 | }, 100 | "outputs": [], 101 | "source": [ 102 | "def make_wall(rows, cols):\n", 103 | " # create wall\n", 104 | " wall = np.zeros((rows, cols, 4), dtype=int) - 1\n", 105 | "\n", 106 | " # randomize wall edges\n", 107 | " wall[-1, :, 0] = np.random.randint(0, 2, cols)\n", 108 | " wall[:, 0, 1] = np.random.randint(0, 2, rows)\n", 109 | " wall[:, -1, 2] = np.random.randint(0, 2, rows)\n", 110 | " wall[0, :, 3] = np.random.randint(0, 2, cols)\n", 111 | "\n", 112 | " return wall" 113 | ] 114 | }, 115 | { 116 | "cell_type": "code", 117 | "execution_count": 6, 118 | "metadata": { 119 | "collapsed": true 120 | }, 121 | "outputs": [], 122 | "source": [ 123 | "def print_wall(wall):\n", 124 | " chars = np.array(list('01 '))\n", 125 | " tile = lambda i, j: ''.join(chars[wall[i, j, :]])\n", 126 | "\n", 127 | " # print rows\n", 128 | " for i in range(wall.shape[0]):\n", 129 | " row = [tile(i, j)[:2] for j in range(wall.shape[1])]\n", 130 | " print(' '.join(row))\n", 131 | " row = [tile(i, j)[2:] for j in range(wall.shape[1])]\n", 132 | " print(' '.join(row))" 133 | ] 134 | }, 135 | { 136 | "cell_type": "markdown", 137 | "metadata": {}, 138 | "source": [ 139 | "## run" 140 | ] 141 | }, 142 | { 143 | "cell_type": "code", 144 | "execution_count": 7, 145 | "metadata": { 146 | "collapsed": false 147 | }, 148 | "outputs": [], 149 | "source": [ 150 | "wall = make_wall(7, 7)\n", 151 | "tiles = deque(np.random.randint(0, 2, (30, 4)))" 152 | ] 153 | }, 154 | { 155 | "cell_type": "code", 156 | "execution_count": 8, 157 | "metadata": { 158 | "collapsed": false 159 | }, 160 | "outputs": [ 161 | { 162 | "name": "stdout", 163 | "output_type": "stream", 164 | "text": [ 165 | " 0 \n", 166 | " 1 0 0 0 0 1 00\n", 167 | " 1 01 00 00 01 10 \n", 168 | " 10 11 01 00 11 0 \n", 169 | " 0 00 10 10 01 10 \n", 170 | " 00 01 01 01 11 0 \n", 171 | " 1 01 10 11 11 10 \n", 172 | " 10 10 00 10 11 0 \n", 173 | " 1 00 00 00 00 10 \n", 174 | " 10 01 00 01 01 0 \n", 175 | " 0 00 10 01 10 11 \n", 176 | " 00 00 01 10 01 1 \n", 177 | "00 0 0 1 0 1 1 \n", 178 | " 0 \n" 179 | ] 180 | } 181 | ], 182 | "source": [ 183 | "solve(wall, tiles)\n", 184 | "print_wall(wall)" 185 | ] 186 | }, 187 | { 188 | "cell_type": "code", 189 | "execution_count": null, 190 | "metadata": { 191 | "collapsed": true 192 | }, 193 | "outputs": [], 194 | "source": [] 195 | } 196 | ], 197 | "metadata": { 198 | "kernelspec": { 199 | "display_name": "Python 3", 200 | "language": "python", 201 | "name": "python3" 202 | }, 203 | "language_info": { 204 | "codemirror_mode": { 205 | "name": "ipython", 206 | "version": 3 207 | }, 208 | "file_extension": ".py", 209 | "mimetype": "text/x-python", 210 | "name": "python", 211 | "nbconvert_exporter": "python", 212 | "pygments_lexer": "ipython3", 213 | "version": "3.6.0" 214 | } 215 | }, 216 | "nbformat": 4, 217 | "nbformat_minor": 2 218 | } 219 | -------------------------------------------------------------------------------- /day I00 - segmented eratosthenes sieve.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": 1, 6 | "metadata": { 7 | "collapsed": true 8 | }, 9 | "outputs": [], 10 | "source": [ 11 | "%load_ext Cython" 12 | ] 13 | }, 14 | { 15 | "cell_type": "markdown", 16 | "metadata": {}, 17 | "source": [ 18 | "## algorithm" 19 | ] 20 | }, 21 | { 22 | "cell_type": "code", 23 | "execution_count": 2, 24 | "metadata": { 25 | "collapsed": true 26 | }, 27 | "outputs": [], 28 | "source": [ 29 | "%%cython\n", 30 | "\n", 31 | "from libc.stdlib cimport malloc, free\n", 32 | "\n", 33 | "DEF LIMIT = 1024 * 31\n", 34 | "DEF PRIME = 1024 * 4\n", 35 | "DEF SIEVE = 1024 * 32\n", 36 | "\n", 37 | "cdef inline int imin(int a, int b) nogil:\n", 38 | " return a if a < b else b\n", 39 | "\n", 40 | "cdef inline int memset(char *p, int n) nogil:\n", 41 | " cdef:\n", 42 | " short *q = p\n", 43 | " int i, j = 0\n", 44 | "\n", 45 | " for i in range((n + 1) >> 1):\n", 46 | " j += q[i]\n", 47 | " q[i] = 0x0100\n", 48 | "\n", 49 | " return j >> 8\n", 50 | "\n", 51 | "cdef int naive_sieve(char *sieve, int *primes, int *offsets, int n) nogil:\n", 52 | " cdef int i, j\n", 53 | "\n", 54 | " memset(sieve, n)\n", 55 | "\n", 56 | " for i in range(3, n, 2):\n", 57 | " if sieve[i]:\n", 58 | " j = i * i\n", 59 | " while j < n:\n", 60 | " sieve[j] = 0\n", 61 | " j += i << 1\n", 62 | "\n", 63 | " primes[0] = i\n", 64 | " offsets[0] = j\n", 65 | " primes += 1\n", 66 | " offsets += 1\n", 67 | "\n", 68 | " primes[0] = 0\n", 69 | " offsets[0] = 0\n", 70 | "\n", 71 | " return memset(sieve, n)\n", 72 | "\n", 73 | "cdef int segmented_sieve(char *sieve, int *primes, int *offsets, int k, int n) nogil:\n", 74 | " cdef int i\n", 75 | "\n", 76 | " while primes[0]:\n", 77 | " i = offsets[0] - k\n", 78 | " while i < n:\n", 79 | " sieve[i] = 0\n", 80 | " i += primes[0] << 1\n", 81 | " offsets[0] = i + k\n", 82 | "\n", 83 | " primes += 1\n", 84 | " offsets += 1\n", 85 | "\n", 86 | " return memset(sieve, n)\n", 87 | "\n", 88 | "cpdef int eratosthenes(int n) nogil:\n", 89 | " cdef:\n", 90 | " char *sieve\n", 91 | " int *primes\n", 92 | " int *offsets\n", 93 | " int k, total\n", 94 | "\n", 95 | " if n > LIMIT * LIMIT:\n", 96 | " return -1\n", 97 | "\n", 98 | " sieve = malloc(SIEVE)\n", 99 | " primes = malloc(PRIME * sizeof(int))\n", 100 | " offsets = malloc(PRIME * sizeof(int))\n", 101 | "\n", 102 | " total = naive_sieve(sieve, primes, offsets, imin(n, LIMIT))\n", 103 | "\n", 104 | " memset(sieve, SIEVE)\n", 105 | " k = LIMIT\n", 106 | " n -= LIMIT\n", 107 | "\n", 108 | " while n > 0:\n", 109 | " total += segmented_sieve(sieve, primes, offsets, k, imin(n, SIEVE))\n", 110 | " k += SIEVE\n", 111 | " n -= SIEVE\n", 112 | "\n", 113 | " free(sieve)\n", 114 | " free(primes)\n", 115 | " free(offsets)\n", 116 | "\n", 117 | " return total" 118 | ] 119 | }, 120 | { 121 | "cell_type": "markdown", 122 | "metadata": {}, 123 | "source": [ 124 | "## run" 125 | ] 126 | }, 127 | { 128 | "cell_type": "code", 129 | "execution_count": 3, 130 | "metadata": {}, 131 | "outputs": [ 132 | { 133 | "name": "stdout", 134 | "output_type": "stream", 135 | "text": [ 136 | "primes below 10**1: 4\n", 137 | "primes below 10**2: 25\n", 138 | "primes below 10**3: 168\n", 139 | "primes below 10**4: 1229\n", 140 | "primes below 10**5: 9592\n", 141 | "primes below 10**6: 78498\n", 142 | "primes below 10**7: 664579\n", 143 | "primes below 10**8: 5761455\n", 144 | "primes below 10**9: 50847534\n" 145 | ] 146 | } 147 | ], 148 | "source": [ 149 | "for i in range(1, 10):\n", 150 | " print('primes below 10**%d: %d' % (i, eratosthenes(10**i)))" 151 | ] 152 | }, 153 | { 154 | "cell_type": "markdown", 155 | "metadata": {}, 156 | "source": [ 157 | "## timeit" 158 | ] 159 | }, 160 | { 161 | "cell_type": "code", 162 | "execution_count": 4, 163 | "metadata": {}, 164 | "outputs": [ 165 | { 166 | "name": "stdout", 167 | "output_type": "stream", 168 | "text": [ 169 | "10000 loops, best of 3: 56.6 µs per loop\n", 170 | "1000 loops, best of 3: 574 µs per loop\n", 171 | "100 loops, best of 3: 6.07 ms per loop\n", 172 | "10 loops, best of 3: 68.4 ms per loop\n", 173 | "1 loop, best of 3: 863 ms per loop\n" 174 | ] 175 | } 176 | ], 177 | "source": [ 178 | "%timeit eratosthenes(1024 * 31)\n", 179 | "%timeit eratosthenes(10**6)\n", 180 | "%timeit eratosthenes(10**7)\n", 181 | "%timeit eratosthenes(10**8)\n", 182 | "%timeit eratosthenes(10**9)" 183 | ] 184 | }, 185 | { 186 | "cell_type": "code", 187 | "execution_count": null, 188 | "metadata": { 189 | "collapsed": true 190 | }, 191 | "outputs": [], 192 | "source": [] 193 | } 194 | ], 195 | "metadata": { 196 | "kernelspec": { 197 | "display_name": "Python 3", 198 | "language": "python", 199 | "name": "python3" 200 | }, 201 | "language_info": { 202 | "codemirror_mode": { 203 | "name": "ipython", 204 | "version": 3 205 | }, 206 | "file_extension": ".py", 207 | "mimetype": "text/x-python", 208 | "name": "python", 209 | "nbconvert_exporter": "python", 210 | "pygments_lexer": "ipython3", 211 | "version": "3.6.1" 212 | } 213 | }, 214 | "nbformat": 4, 215 | "nbformat_minor": 2 216 | } 217 | -------------------------------------------------------------------------------- /day 56 - lzw.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "## algorithm" 8 | ] 9 | }, 10 | { 11 | "cell_type": "code", 12 | "execution_count": 1, 13 | "metadata": { 14 | "collapsed": false 15 | }, 16 | "outputs": [], 17 | "source": [ 18 | "def lzw_encode(data):\n", 19 | " code, code_bits = {bytes([i]): i for i in range(256)}, 8\n", 20 | " buffer, buffer_bits = 0, 0\n", 21 | " index, aux = 0, []\n", 22 | "\n", 23 | " while index < len(data):\n", 24 | " # find word\n", 25 | " for j in range(index + 1, len(data) + 1):\n", 26 | " word = data[index:j]\n", 27 | "\n", 28 | " # store word\n", 29 | " if word not in code:\n", 30 | " code[word] = len(code)\n", 31 | " word = word[:-1]\n", 32 | " break\n", 33 | "\n", 34 | " # write buffer\n", 35 | " buffer <<= code_bits\n", 36 | " buffer |= code[word]\n", 37 | " buffer_bits += code_bits\n", 38 | "\n", 39 | " # code length\n", 40 | " if len(code) > 2 ** code_bits:\n", 41 | " code_bits += 1\n", 42 | "\n", 43 | " # shift\n", 44 | " index += len(word)\n", 45 | "\n", 46 | " # buffer alignment\n", 47 | " if index >= len(data) and buffer_bits % 8:\n", 48 | " r = 8 - (buffer_bits % 8)\n", 49 | " buffer <<= r\n", 50 | " buffer_bits += r\n", 51 | "\n", 52 | " # emit output\n", 53 | " if not buffer_bits % 8:\n", 54 | " aux += int.to_bytes(buffer, buffer_bits >> 3, 'big')\n", 55 | " buffer, buffer_bits = 0, 0\n", 56 | "\n", 57 | " return bytes(aux)" 58 | ] 59 | }, 60 | { 61 | "cell_type": "code", 62 | "execution_count": 2, 63 | "metadata": { 64 | "collapsed": true 65 | }, 66 | "outputs": [], 67 | "source": [ 68 | "def lzw_decode(data):\n", 69 | " code, code_bits = {i: bytes([i]) for i in range(256)}, 8\n", 70 | " buffer, buffer_bits = 0, 0\n", 71 | " index, aux = 0, []\n", 72 | " prefix = b''\n", 73 | "\n", 74 | " while index < len(data) or buffer_bits >= code_bits:\n", 75 | " # read buffer\n", 76 | " while index < len(data) and buffer_bits < code_bits:\n", 77 | " buffer <<= 8\n", 78 | " buffer |= data[index]\n", 79 | " buffer_bits += 8\n", 80 | " index += 1\n", 81 | "\n", 82 | " # find word\n", 83 | " buffer_bits -= code_bits\n", 84 | " key = buffer >> buffer_bits\n", 85 | " buffer &= (1 << buffer_bits) - 1\n", 86 | " word = code.get(key, prefix + prefix[:1])\n", 87 | "\n", 88 | " # store word\n", 89 | " if prefix:\n", 90 | " code[len(code)] = prefix + word[:1]\n", 91 | " prefix = word\n", 92 | "\n", 93 | " # code length\n", 94 | " if len(code) >= 2 ** code_bits:\n", 95 | " code_bits += 1\n", 96 | "\n", 97 | " # emit output\n", 98 | " aux += word\n", 99 | " \n", 100 | " return bytes(aux)" 101 | ] 102 | }, 103 | { 104 | "cell_type": "markdown", 105 | "metadata": {}, 106 | "source": [ 107 | "## run" 108 | ] 109 | }, 110 | { 111 | "cell_type": "code", 112 | "execution_count": 3, 113 | "metadata": { 114 | "collapsed": false 115 | }, 116 | "outputs": [], 117 | "source": [ 118 | "def compress(data):\n", 119 | " encoded = lzw_encode(data.encode('ASCII'))\n", 120 | " decoded = lzw_decode(encoded).decode('ASCII')\n", 121 | " assert data == decoded\n", 122 | " \n", 123 | " print('compression', len(data), '->', len(encoded), 'bytes')" 124 | ] 125 | }, 126 | { 127 | "cell_type": "code", 128 | "execution_count": 4, 129 | "metadata": { 130 | "collapsed": false 131 | }, 132 | "outputs": [ 133 | { 134 | "name": "stdout", 135 | "output_type": "stream", 136 | "text": [ 137 | "compression 11 -> 9 bytes\n" 138 | ] 139 | } 140 | ], 141 | "source": [ 142 | "compress('ATGATCATGAG')" 143 | ] 144 | }, 145 | { 146 | "cell_type": "code", 147 | "execution_count": 5, 148 | "metadata": { 149 | "collapsed": false 150 | }, 151 | "outputs": [ 152 | { 153 | "name": "stdout", 154 | "output_type": "stream", 155 | "text": [ 156 | "compression 1000 -> 51 bytes\n" 157 | ] 158 | } 159 | ], 160 | "source": [ 161 | "compress('x' * 1000)" 162 | ] 163 | }, 164 | { 165 | "cell_type": "code", 166 | "execution_count": 6, 167 | "metadata": { 168 | "collapsed": false 169 | }, 170 | "outputs": [ 171 | { 172 | "name": "stdout", 173 | "output_type": "stream", 174 | "text": [ 175 | "compression 112 -> 84 bytes\n" 176 | ] 177 | } 178 | ], 179 | "source": [ 180 | "compress(\"\"\"\n", 181 | "I wish that I knew what I know now\n", 182 | "When I was younger.\n", 183 | "I wish that I knew what I know now\n", 184 | "When I was stronger.\n", 185 | "\"\"\")" 186 | ] 187 | }, 188 | { 189 | "cell_type": "code", 190 | "execution_count": null, 191 | "metadata": { 192 | "collapsed": true 193 | }, 194 | "outputs": [], 195 | "source": [] 196 | } 197 | ], 198 | "metadata": { 199 | "kernelspec": { 200 | "display_name": "Python 3", 201 | "language": "python", 202 | "name": "python3" 203 | }, 204 | "language_info": { 205 | "codemirror_mode": { 206 | "name": "ipython", 207 | "version": 3 208 | }, 209 | "file_extension": ".py", 210 | "mimetype": "text/x-python", 211 | "name": "python", 212 | "nbconvert_exporter": "python", 213 | "pygments_lexer": "ipython3", 214 | "version": "3.6.0" 215 | } 216 | }, 217 | "nbformat": 4, 218 | "nbformat_minor": 2 219 | } 220 | -------------------------------------------------------------------------------- /day 78 - horn-satifiability.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": 1, 6 | "metadata": { 7 | "collapsed": true 8 | }, 9 | "outputs": [], 10 | "source": [ 11 | "from collections import defaultdict, deque" 12 | ] 13 | }, 14 | { 15 | "cell_type": "markdown", 16 | "metadata": {}, 17 | "source": [ 18 | "## algorithm" 19 | ] 20 | }, 21 | { 22 | "cell_type": "code", 23 | "execution_count": 2, 24 | "metadata": { 25 | "collapsed": true 26 | }, 27 | "outputs": [], 28 | "source": [ 29 | "def knowledge_base(formulas):\n", 30 | " rules, variable, dependency = [], defaultdict(bool), defaultdict(list)\n", 31 | "\n", 32 | " def _clause(formula):\n", 33 | " # A, B, C => P\n", 34 | " neg, pos = formula.replace(' ', '').split('=>')\n", 35 | " neg, pos = set(neg.split('&')) - {''}, pos or None\n", 36 | "\n", 37 | " # add rule\n", 38 | " rules.append((neg, pos))\n", 39 | " \n", 40 | " # set variable and track dependencies\n", 41 | " for i in neg:\n", 42 | " dependency[i].append((neg, pos))\n", 43 | "\n", 44 | " # parse formulas and build knowledge base\n", 45 | " deque((_clause(i) for i in formulas.split('\\n') if i), 0)\n", 46 | " \n", 47 | " return rules, variable, dependency" 48 | ] 49 | }, 50 | { 51 | "cell_type": "code", 52 | "execution_count": 3, 53 | "metadata": { 54 | "collapsed": true 55 | }, 56 | "outputs": [], 57 | "source": [ 58 | "def resolution(rules, variable, dependency):\n", 59 | " # initial variables that have to be satisfied\n", 60 | " to_satisfy = [(neg, pos) for neg, pos in rules if not neg]\n", 61 | "\n", 62 | " while to_satisfy:\n", 63 | " neg, pos = to_satisfy.pop()\n", 64 | "\n", 65 | " # contradiction: true => false\n", 66 | " if not pos:\n", 67 | " return False\n", 68 | "\n", 69 | " # satisfy variable\n", 70 | " variable[pos] = True\n", 71 | "\n", 72 | " # update dependent rules\n", 73 | " for d_neg, d_pos in dependency[pos]:\n", 74 | " d_neg.remove(pos)\n", 75 | " \n", 76 | " # next variable to be satisfied\n", 77 | " if not d_neg and d_pos not in variable:\n", 78 | " to_satisfy.append((d_neg, d_pos))\n", 79 | "\n", 80 | " return True" 81 | ] 82 | }, 83 | { 84 | "cell_type": "code", 85 | "execution_count": 4, 86 | "metadata": { 87 | "collapsed": true 88 | }, 89 | "outputs": [], 90 | "source": [ 91 | "def hornsat(formulas):\n", 92 | " rules, variable, dependency = knowledge_base(formulas)\n", 93 | " satisfiable = resolution(rules, variable, dependency)\n", 94 | "\n", 95 | " print(['CONTRADICTION', 'SATISFIABLE'][satisfiable])\n", 96 | " print(', '.join('%s=%s' % i for i in variable.items()))" 97 | ] 98 | }, 99 | { 100 | "cell_type": "markdown", 101 | "metadata": {}, 102 | "source": [ 103 | "## run" 104 | ] 105 | }, 106 | { 107 | "cell_type": "code", 108 | "execution_count": 5, 109 | "metadata": { 110 | "collapsed": false 111 | }, 112 | "outputs": [ 113 | { 114 | "name": "stdout", 115 | "output_type": "stream", 116 | "text": [ 117 | "SATISFIABLE\n", 118 | "X=True, Y=True, Z=True\n" 119 | ] 120 | } 121 | ], 122 | "source": [ 123 | "hornsat(\"\"\"\n", 124 | "X => Y\n", 125 | "Y => Z\n", 126 | "=> X\n", 127 | "\"\"\")" 128 | ] 129 | }, 130 | { 131 | "cell_type": "code", 132 | "execution_count": 6, 133 | "metadata": { 134 | "collapsed": false 135 | }, 136 | "outputs": [ 137 | { 138 | "name": "stdout", 139 | "output_type": "stream", 140 | "text": [ 141 | "CONTRADICTION\n", 142 | "X=True, Y=True\n" 143 | ] 144 | } 145 | ], 146 | "source": [ 147 | "hornsat(\"\"\"\n", 148 | "X => Y\n", 149 | "Y => X\n", 150 | "=> X\n", 151 | "Y =>\n", 152 | "\"\"\")" 153 | ] 154 | }, 155 | { 156 | "cell_type": "code", 157 | "execution_count": 7, 158 | "metadata": { 159 | "collapsed": false 160 | }, 161 | "outputs": [ 162 | { 163 | "name": "stdout", 164 | "output_type": "stream", 165 | "text": [ 166 | "SATISFIABLE\n", 167 | "R=True, S=True, P=True\n" 168 | ] 169 | } 170 | ], 171 | "source": [ 172 | "hornsat(\"\"\"\n", 173 | "P & Q & R & S => X\n", 174 | "P & Q => R\n", 175 | "R => S\n", 176 | "X =>\n", 177 | "=> P\n", 178 | "=> R\n", 179 | "\"\"\")" 180 | ] 181 | }, 182 | { 183 | "cell_type": "code", 184 | "execution_count": 8, 185 | "metadata": { 186 | "collapsed": false 187 | }, 188 | "outputs": [ 189 | { 190 | "name": "stdout", 191 | "output_type": "stream", 192 | "text": [ 193 | "CONTRADICTION\n", 194 | "Q=True, P=True, R=True, S=True, X=True\n" 195 | ] 196 | } 197 | ], 198 | "source": [ 199 | "hornsat(\"\"\"\n", 200 | "P & Q & R & S => X\n", 201 | "P & Q => R\n", 202 | "R => S\n", 203 | "X =>\n", 204 | "=> P\n", 205 | "=> Q\n", 206 | "\"\"\")" 207 | ] 208 | }, 209 | { 210 | "cell_type": "code", 211 | "execution_count": null, 212 | "metadata": { 213 | "collapsed": true 214 | }, 215 | "outputs": [], 216 | "source": [] 217 | } 218 | ], 219 | "metadata": { 220 | "kernelspec": { 221 | "display_name": "Python 3", 222 | "language": "python", 223 | "name": "python3" 224 | }, 225 | "language_info": { 226 | "codemirror_mode": { 227 | "name": "ipython", 228 | "version": 3 229 | }, 230 | "file_extension": ".py", 231 | "mimetype": "text/x-python", 232 | "name": "python", 233 | "nbconvert_exporter": "python", 234 | "pygments_lexer": "ipython3", 235 | "version": "3.6.0" 236 | } 237 | }, 238 | "nbformat": 4, 239 | "nbformat_minor": 2 240 | } 241 | --------------------------------------------------------------------------------