diff --git a/bit_manipulation/bits_to_flip/__init__.py b/bit_manipulation/bits_to_flip/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/bit_manipulation/bits_to_flip/bits_to_flip_challenge.ipynb b/bit_manipulation/bits_to_flip/bits_to_flip_challenge.ipynb new file mode 100644 index 0000000..29a18e1 --- /dev/null +++ b/bit_manipulation/bits_to_flip/bits_to_flip_challenge.ipynb @@ -0,0 +1,172 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "This notebook was prepared by [Donne Martin](https://github.com/donnemartin). Source and license info is on [GitHub](https://github.com/donnemartin/interactive-coding-challenges)." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Challenge Notebook" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Problem: Determine the number of bits to flip to convert int a to int b'.\n", + "\n", + "* [Constraints](#Constraints)\n", + "* [Test Cases](#Test-Cases)\n", + "* [Algorithm](#Algorithm)\n", + "* [Code](#Code)\n", + "* [Unit Test](#Unit-Test)\n", + "* [Solution Notebook](#Solution-Notebook)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Constraints\n", + "\n", + "* Can we assume A and B are always ints?\n", + " * Yes\n", + "* Is the output an int?\n", + " * Yes\n", + "* Can we assume A and B are always the same number of bits?\n", + " * Yes\n", + "* Can we assume the inputs are valid (not None)?\n", + " * No\n", + "* Can we assume this fits memory?\n", + " * Yes" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Test Cases\n", + "\n", + "* A or B is None -> Exception\n", + "* General case\n", + "
\n", + " A = 11101\n", + " B = 01111\n", + " Result: 2\n", + "" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Algorithm\n", + "\n", + "Refer to the [Solution Notebook](). If you are stuck and need a hint, the solution notebook's algorithm discussion might be a good place to start." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Code" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "class Bits(object):\n", + "\n", + " def bits_to_flip(self, a, b):\n", + " # TODO: Implement me\n", + " pass" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Unit Test" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**The following unit test is expected to fail until you solve the challenge.**" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "# %load test_bits_to_flip.py\n", + "from nose.tools import assert_equal\n", + "\n", + "\n", + "class TestBits(object):\n", + "\n", + " def test_bits_to_flip(self):\n", + " bits = Bits()\n", + " a = int('11101', base=2)\n", + " b = int('01111', base=2)\n", + " expected = 2\n", + " assert_equal(bits.bits_to_flip(a, b), expected)\n", + " print('Success: test_bits_to_flip')\n", + "\n", + "\n", + "def main():\n", + " test = TestBits()\n", + " test.test_bits_to_flip()\n", + "\n", + "\n", + "if __name__ == '__main__':\n", + " main()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Solution Notebook\n", + "\n", + "Review the [Solution Notebook]() for a discussion on algorithms and code solutions." + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.5.0" + } + }, + "nbformat": 4, + "nbformat_minor": 0 +} diff --git a/bit_manipulation/bits_to_flip/bits_to_flip_solution.ipynb b/bit_manipulation/bits_to_flip/bits_to_flip_solution.ipynb new file mode 100644 index 0000000..87db11d --- /dev/null +++ b/bit_manipulation/bits_to_flip/bits_to_flip_solution.ipynb @@ -0,0 +1,200 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "This notebook was prepared by [Donne Martin](https://github.com/donnemartin). Source and license info is on [GitHub](https://github.com/donnemartin/interactive-coding-challenges)." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Solution Notebook" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Problem: Determine the number of bits to flip to convert int a to int b.\n", + "\n", + "* [Constraints](#Constraints)\n", + "* [Test Cases](#Test-Cases)\n", + "* [Algorithm](#Algorithm)\n", + "* [Code](#Code)\n", + "* [Unit Test](#Unit-Test)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Constraints\n", + "\n", + "* Can we assume A and B are always ints?\n", + " * Yes\n", + "* Is the output an int?\n", + " * Yes\n", + "* Can we assume A and B are always the same number of bits?\n", + " * Yes\n", + "* Can we assume the inputs are valid (not None)?\n", + " * No\n", + "* Can we assume this fits memory?\n", + " * Yes" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Test Cases\n", + "\n", + "* A or B is None -> Exception\n", + "* General case\n", + "\n", + " A = 11101\n", + " B = 01111\n", + " Result: 2\n", + "" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Algorithm\n", + "\n", + "We can use the xor operator to determine the bit differences between a and b\n", + "\n", + "* Set count to 0\n", + "* Set c to a xor b\n", + "* Loop while c != 0:\n", + " * Increment count if the LSB in c is a 1\n", + " * We can check this by using a mask of 1\n", + " * Right shift c by 1\n", + "* Return the count\n", + " \n", + "Complexity:\n", + "* Time: O(b), where b is the number of bits\n", + "* Space: O(b), where b is the number of bits" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Code" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "class Bits(object):\n", + "\n", + " def bits_to_flip(self, a, b):\n", + " if a is None or b is None:\n", + " raise TypeError('a or b cannot be None')\n", + " count = 0\n", + " c = a ^ b\n", + " while c:\n", + " count += c & 1\n", + " c >>= 1\n", + " return count" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Unit Test" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Overwriting test_bits_to_flip.py\n" + ] + } + ], + "source": [ + "%%writefile test_bits_to_flip.py\n", + "from nose.tools import assert_equal\n", + "\n", + "\n", + "class TestBits(object):\n", + "\n", + " def test_bits_to_flip(self):\n", + " bits = Bits()\n", + " a = int('11101', base=2)\n", + " b = int('01111', base=2)\n", + " expected = 2\n", + " assert_equal(bits.bits_to_flip(a, b), expected)\n", + " print('Success: test_bits_to_flip')\n", + "\n", + "\n", + "def main():\n", + " test = TestBits()\n", + " test.test_bits_to_flip()\n", + "\n", + "\n", + "if __name__ == '__main__':\n", + " main()" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Success: test_bits_to_flip\n" + ] + } + ], + "source": [ + "%run -i test_bits_to_flip.py" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.5.0" + } + }, + "nbformat": 4, + "nbformat_minor": 0 +} diff --git a/bit_manipulation/bits_to_flip/test_bits_to_flip.py b/bit_manipulation/bits_to_flip/test_bits_to_flip.py new file mode 100644 index 0000000..c2bbd0b --- /dev/null +++ b/bit_manipulation/bits_to_flip/test_bits_to_flip.py @@ -0,0 +1,21 @@ +from nose.tools import assert_equal + + +class TestBits(object): + + def test_bits_to_flip(self): + bits = Bits() + a = int('11101', base=2) + b = int('01111', base=2) + expected = 2 + assert_equal(bits.bits_to_flip(a, b), expected) + print('Success: test_bits_to_flip') + + +def main(): + test = TestBits() + test.test_bits_to_flip() + + +if __name__ == '__main__': + main() \ No newline at end of file