Skip to content

Commit 65caa98

Browse files
committed
Add bits to flip challenge
1 parent 5b8ae59 commit 65caa98

File tree

4 files changed

+393
-0
lines changed

4 files changed

+393
-0
lines changed

bit_manipulation/bits_to_flip/__init__.py

Whitespace-only changes.
Lines changed: 172 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,172 @@
1+
{
2+
"cells": [
3+
{
4+
"cell_type": "markdown",
5+
"metadata": {},
6+
"source": [
7+
"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)."
8+
]
9+
},
10+
{
11+
"cell_type": "markdown",
12+
"metadata": {},
13+
"source": [
14+
"# Challenge Notebook"
15+
]
16+
},
17+
{
18+
"cell_type": "markdown",
19+
"metadata": {},
20+
"source": [
21+
"## Problem: Determine the number of bits to flip to convert int a to int b'.\n",
22+
"\n",
23+
"* [Constraints](#Constraints)\n",
24+
"* [Test Cases](#Test-Cases)\n",
25+
"* [Algorithm](#Algorithm)\n",
26+
"* [Code](#Code)\n",
27+
"* [Unit Test](#Unit-Test)\n",
28+
"* [Solution Notebook](#Solution-Notebook)"
29+
]
30+
},
31+
{
32+
"cell_type": "markdown",
33+
"metadata": {},
34+
"source": [
35+
"## Constraints\n",
36+
"\n",
37+
"* Can we assume A and B are always ints?\n",
38+
" * Yes\n",
39+
"* Is the output an int?\n",
40+
" * Yes\n",
41+
"* Can we assume A and B are always the same number of bits?\n",
42+
" * Yes\n",
43+
"* Can we assume the inputs are valid (not None)?\n",
44+
" * No\n",
45+
"* Can we assume this fits memory?\n",
46+
" * Yes"
47+
]
48+
},
49+
{
50+
"cell_type": "markdown",
51+
"metadata": {},
52+
"source": [
53+
"## Test Cases\n",
54+
"\n",
55+
"* A or B is None -> Exception\n",
56+
"* General case\n",
57+
"<pre>\n",
58+
" A = 11101\n",
59+
" B = 01111\n",
60+
" Result: 2\n",
61+
"<pre>"
62+
]
63+
},
64+
{
65+
"cell_type": "markdown",
66+
"metadata": {},
67+
"source": [
68+
"## Algorithm\n",
69+
"\n",
70+
"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."
71+
]
72+
},
73+
{
74+
"cell_type": "markdown",
75+
"metadata": {},
76+
"source": [
77+
"## Code"
78+
]
79+
},
80+
{
81+
"cell_type": "code",
82+
"execution_count": null,
83+
"metadata": {
84+
"collapsed": false
85+
},
86+
"outputs": [],
87+
"source": [
88+
"class Bits(object):\n",
89+
"\n",
90+
" def bits_to_flip(self, a, b):\n",
91+
" # TODO: Implement me\n",
92+
" pass"
93+
]
94+
},
95+
{
96+
"cell_type": "markdown",
97+
"metadata": {},
98+
"source": [
99+
"## Unit Test"
100+
]
101+
},
102+
{
103+
"cell_type": "markdown",
104+
"metadata": {},
105+
"source": [
106+
"**The following unit test is expected to fail until you solve the challenge.**"
107+
]
108+
},
109+
{
110+
"cell_type": "code",
111+
"execution_count": null,
112+
"metadata": {
113+
"collapsed": false
114+
},
115+
"outputs": [],
116+
"source": [
117+
"# %load test_bits_to_flip.py\n",
118+
"from nose.tools import assert_equal\n",
119+
"\n",
120+
"\n",
121+
"class TestBits(object):\n",
122+
"\n",
123+
" def test_bits_to_flip(self):\n",
124+
" bits = Bits()\n",
125+
" a = int('11101', base=2)\n",
126+
" b = int('01111', base=2)\n",
127+
" expected = 2\n",
128+
" assert_equal(bits.bits_to_flip(a, b), expected)\n",
129+
" print('Success: test_bits_to_flip')\n",
130+
"\n",
131+
"\n",
132+
"def main():\n",
133+
" test = TestBits()\n",
134+
" test.test_bits_to_flip()\n",
135+
"\n",
136+
"\n",
137+
"if __name__ == '__main__':\n",
138+
" main()"
139+
]
140+
},
141+
{
142+
"cell_type": "markdown",
143+
"metadata": {},
144+
"source": [
145+
"## Solution Notebook\n",
146+
"\n",
147+
"Review the [Solution Notebook]() for a discussion on algorithms and code solutions."
148+
]
149+
}
150+
],
151+
"metadata": {
152+
"kernelspec": {
153+
"display_name": "Python 3",
154+
"language": "python",
155+
"name": "python3"
156+
},
157+
"language_info": {
158+
"codemirror_mode": {
159+
"name": "ipython",
160+
"version": 3
161+
},
162+
"file_extension": ".py",
163+
"mimetype": "text/x-python",
164+
"name": "python",
165+
"nbconvert_exporter": "python",
166+
"pygments_lexer": "ipython3",
167+
"version": "3.5.0"
168+
}
169+
},
170+
"nbformat": 4,
171+
"nbformat_minor": 0
172+
}
Lines changed: 200 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,200 @@
1+
{
2+
"cells": [
3+
{
4+
"cell_type": "markdown",
5+
"metadata": {},
6+
"source": [
7+
"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)."
8+
]
9+
},
10+
{
11+
"cell_type": "markdown",
12+
"metadata": {},
13+
"source": [
14+
"# Solution Notebook"
15+
]
16+
},
17+
{
18+
"cell_type": "markdown",
19+
"metadata": {},
20+
"source": [
21+
"## Problem: Determine the number of bits to flip to convert int a to int b.\n",
22+
"\n",
23+
"* [Constraints](#Constraints)\n",
24+
"* [Test Cases](#Test-Cases)\n",
25+
"* [Algorithm](#Algorithm)\n",
26+
"* [Code](#Code)\n",
27+
"* [Unit Test](#Unit-Test)"
28+
]
29+
},
30+
{
31+
"cell_type": "markdown",
32+
"metadata": {},
33+
"source": [
34+
"## Constraints\n",
35+
"\n",
36+
"* Can we assume A and B are always ints?\n",
37+
" * Yes\n",
38+
"* Is the output an int?\n",
39+
" * Yes\n",
40+
"* Can we assume A and B are always the same number of bits?\n",
41+
" * Yes\n",
42+
"* Can we assume the inputs are valid (not None)?\n",
43+
" * No\n",
44+
"* Can we assume this fits memory?\n",
45+
" * Yes"
46+
]
47+
},
48+
{
49+
"cell_type": "markdown",
50+
"metadata": {},
51+
"source": [
52+
"## Test Cases\n",
53+
"\n",
54+
"* A or B is None -> Exception\n",
55+
"* General case\n",
56+
"<pre>\n",
57+
" A = 11101\n",
58+
" B = 01111\n",
59+
" Result: 2\n",
60+
"<pre>"
61+
]
62+
},
63+
{
64+
"cell_type": "markdown",
65+
"metadata": {},
66+
"source": [
67+
"## Algorithm\n",
68+
"\n",
69+
"We can use the xor operator to determine the bit differences between a and b\n",
70+
"\n",
71+
"* Set count to 0\n",
72+
"* Set c to a xor b\n",
73+
"* Loop while c != 0:\n",
74+
" * Increment count if the LSB in c is a 1\n",
75+
" * We can check this by using a mask of 1\n",
76+
" * Right shift c by 1\n",
77+
"* Return the count\n",
78+
" \n",
79+
"Complexity:\n",
80+
"* Time: O(b), where b is the number of bits\n",
81+
"* Space: O(b), where b is the number of bits"
82+
]
83+
},
84+
{
85+
"cell_type": "markdown",
86+
"metadata": {},
87+
"source": [
88+
"## Code"
89+
]
90+
},
91+
{
92+
"cell_type": "code",
93+
"execution_count": 1,
94+
"metadata": {
95+
"collapsed": false
96+
},
97+
"outputs": [],
98+
"source": [
99+
"class Bits(object):\n",
100+
"\n",
101+
" def bits_to_flip(self, a, b):\n",
102+
" if a is None or b is None:\n",
103+
" raise TypeError('a or b cannot be None')\n",
104+
" count = 0\n",
105+
" c = a ^ b\n",
106+
" while c:\n",
107+
" count += c & 1\n",
108+
" c >>= 1\n",
109+
" return count"
110+
]
111+
},
112+
{
113+
"cell_type": "markdown",
114+
"metadata": {},
115+
"source": [
116+
"## Unit Test"
117+
]
118+
},
119+
{
120+
"cell_type": "code",
121+
"execution_count": 2,
122+
"metadata": {
123+
"collapsed": false
124+
},
125+
"outputs": [
126+
{
127+
"name": "stdout",
128+
"output_type": "stream",
129+
"text": [
130+
"Overwriting test_bits_to_flip.py\n"
131+
]
132+
}
133+
],
134+
"source": [
135+
"%%writefile test_bits_to_flip.py\n",
136+
"from nose.tools import assert_equal\n",
137+
"\n",
138+
"\n",
139+
"class TestBits(object):\n",
140+
"\n",
141+
" def test_bits_to_flip(self):\n",
142+
" bits = Bits()\n",
143+
" a = int('11101', base=2)\n",
144+
" b = int('01111', base=2)\n",
145+
" expected = 2\n",
146+
" assert_equal(bits.bits_to_flip(a, b), expected)\n",
147+
" print('Success: test_bits_to_flip')\n",
148+
"\n",
149+
"\n",
150+
"def main():\n",
151+
" test = TestBits()\n",
152+
" test.test_bits_to_flip()\n",
153+
"\n",
154+
"\n",
155+
"if __name__ == '__main__':\n",
156+
" main()"
157+
]
158+
},
159+
{
160+
"cell_type": "code",
161+
"execution_count": 3,
162+
"metadata": {
163+
"collapsed": false
164+
},
165+
"outputs": [
166+
{
167+
"name": "stdout",
168+
"output_type": "stream",
169+
"text": [
170+
"Success: test_bits_to_flip\n"
171+
]
172+
}
173+
],
174+
"source": [
175+
"%run -i test_bits_to_flip.py"
176+
]
177+
}
178+
],
179+
"metadata": {
180+
"kernelspec": {
181+
"display_name": "Python 3",
182+
"language": "python",
183+
"name": "python3"
184+
},
185+
"language_info": {
186+
"codemirror_mode": {
187+
"name": "ipython",
188+
"version": 3
189+
},
190+
"file_extension": ".py",
191+
"mimetype": "text/x-python",
192+
"name": "python",
193+
"nbconvert_exporter": "python",
194+
"pygments_lexer": "ipython3",
195+
"version": "3.5.0"
196+
}
197+
},
198+
"nbformat": 4,
199+
"nbformat_minor": 0
200+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
from nose.tools import assert_equal
2+
3+
4+
class TestBits(object):
5+
6+
def test_bits_to_flip(self):
7+
bits = Bits()
8+
a = int('11101', base=2)
9+
b = int('01111', base=2)
10+
expected = 2
11+
assert_equal(bits.bits_to_flip(a, b), expected)
12+
print('Success: test_bits_to_flip')
13+
14+
15+
def main():
16+
test = TestBits()
17+
test.test_bits_to_flip()
18+
19+
20+
if __name__ == '__main__':
21+
main()

0 commit comments

Comments
 (0)