From 65caa98e572b04a60cb5204bf21b7b393bd2735c Mon Sep 17 00:00:00 2001 From: Donne Martin Date: Fri, 31 Mar 2017 04:45:28 -0400 Subject: [PATCH] Add bits to flip challenge --- bit_manipulation/bits_to_flip/__init__.py | 0 .../bits_to_flip/bits_to_flip_challenge.ipynb | 172 +++++++++++++++ .../bits_to_flip/bits_to_flip_solution.ipynb | 200 ++++++++++++++++++ .../bits_to_flip/test_bits_to_flip.py | 21 ++ 4 files changed, 393 insertions(+) create mode 100644 bit_manipulation/bits_to_flip/__init__.py create mode 100644 bit_manipulation/bits_to_flip/bits_to_flip_challenge.ipynb create mode 100644 bit_manipulation/bits_to_flip/bits_to_flip_solution.ipynb create mode 100644 bit_manipulation/bits_to_flip/test_bits_to_flip.py 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