Add sum two challenge

This commit is contained in:
Donne Martin 2017-03-28 05:10:39 -04:00
parent a97d35f86a
commit f469ccd088
3 changed files with 410 additions and 0 deletions

View File

@ -0,0 +1,164 @@
{
"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: Sum of Two Integers.\n",
"\n",
"See the [LeetCode](https://leetcode.com/problems/sum-of-two-integers/) problem page.\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 we're working with 32 bit ints?\n",
" * Yes\n",
"* Can we assume the inputs are valid?\n",
" * No, check for None\n",
"* Can we assume this fits memory?\n",
" * Yes"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Test Cases\n",
"\n",
"See the [LeetCode](https://leetcode.com/problems/sum-of-two-integers/) problem page."
]
},
{
"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 Solution(object):\n",
"\n",
" def sum_two(self, val):\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_sum_two.py\n",
"from nose.tools import assert_equal, assert_raises\n",
"\n",
"\n",
"class TestSumTwo(object):\n",
"\n",
" def test_sum_two(self):\n",
" solution = Solution()\n",
" assert_raises(TypeError, solution.sum_two, None)\n",
" assert_equal(solution.sum_two(5, 7), 12)\n",
" assert_equal(solution.sum_two(-5, -7), -12)\n",
" assert_equal(solution.sum_two(5, -7), -2)\n",
" print('Success: test_sum_two')\n",
"\n",
"\n",
"def main():\n",
" test = TestSumTwo()\n",
" test.test_sum_two()\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
}

View File

@ -0,0 +1,225 @@
{
"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: Sum of Two Integers.\n",
"\n",
"See the [LeetCode](https://leetcode.com/problems/sum-of-two-integers/) problem page.\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 we're working with 32 bit ints?\n",
" * Yes\n",
"* Can we assume the inputs are valid?\n",
" * No, check for None\n",
"* Can we assume this fits memory?\n",
" * Yes"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Test Cases\n",
"\n",
"<pre>\n",
"* None input -> TypeError\n",
"* 5, 7 -> 12\n",
"* -5, -7 -> -12\n",
"* 5, -7 -> -2\n",
"</pre>"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Algorithm\n",
"\n",
"We'll look at the following example, adding a and b:\n",
"\n",
"<pre>\n",
"a 0111 \n",
"b 0101\n",
"</pre>\n",
"\n",
"First, add a and b, without worrying about the carry (0+0=0, 0+1=1, 1+1=0):\n",
"\n",
"result = a ^ b = 0010\n",
"\n",
"Next, calculate the carry (1+1=2). We'll need to left shift one to prepare for the next iteration when we move to the next most significant bit:\n",
"\n",
"carry = (a&b) << 1 = 1010\n",
"\n",
"If the carry is not zero, we'll need to add the carry to the result. Recusively call the function, passing in result and carry.\n",
"\n",
"Below are the values of a, b, and the carry of a = 7 and b = 5, producing the result of 12.\n",
"\n",
"<pre>\n",
"a 0111 \n",
"b 0101 \n",
"----- \n",
"c 0101 \n",
"a 0010 \n",
"b 1010 \n",
"----- \n",
"c 0010 \n",
"a 1000 \n",
"b 0100 \n",
"----- \n",
"c 0000 \n",
"a 1100 \n",
"b 0000\n",
"\n",
"c = carry = 0, return the result 1100\n",
"</pre>\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 Solution(object):\n",
"\n",
" def sum_two(self, a, b):\n",
" if a is None or b is None:\n",
" raise TypeError('a or b cannot be None')\n",
" result = a ^ b;\n",
" carry = (a&b) << 1\n",
" if carry != 0:\n",
" return self.sum_two(result, carry)\n",
" return result;"
]
},
{
"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_sum_two.py\n"
]
}
],
"source": [
"%%writefile test_sum_two.py\n",
"from nose.tools import assert_equal, assert_raises\n",
"\n",
"\n",
"class TestSumTwo(object):\n",
"\n",
" def test_sum_two(self):\n",
" solution = Solution()\n",
" assert_raises(TypeError, solution.sum_two, None)\n",
" assert_equal(solution.sum_two(5, 7), 12)\n",
" assert_equal(solution.sum_two(-5, -7), -12)\n",
" assert_equal(solution.sum_two(5, -7), -2)\n",
" print('Success: test_sum_two')\n",
"\n",
"\n",
"def main():\n",
" test = TestSumTwo()\n",
" test.test_sum_two()\n",
"\n",
"\n",
"if __name__ == '__main__':\n",
" main()"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {
"collapsed": false,
"scrolled": true
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Success: test_sum_two\n"
]
}
],
"source": [
"%run -i test_sum_two.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
}

View File

@ -0,0 +1,21 @@
from nose.tools import assert_equal, assert_raises
class TestSumTwo(object):
def test_sum_two(self):
solution = Solution()
assert_raises(TypeError, solution.sum_two, None)
assert_equal(solution.sum_two(5, 7), 12)
assert_equal(solution.sum_two(-5, -7), -12)
assert_equal(solution.sum_two(5, -7), -2)
print('Success: test_sum_two')
def main():
test = TestSumTwo()
test.test_sum_two()
if __name__ == '__main__':
main()