#!/usr/bin/env python # coding: utf-8 # 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). # # Solution Notebook # ## Problem: Given two 16 bit numbers, n and m, and two indices i, j, insert m into n such that m starts at bit j and ends at bit i. # # * [Constraints](#Constraints) # * [Test Cases](#Test-Cases) # * [Algorithm](#Algorithm) # * [Code](#Code) # * [Unit Test](#Unit-Test) # ## Constraints # # * Can we assume j > i? # * Yes # * Can we assume i through j have enough space for m? # * Yes # * Can we assume the inputs are valid? # * No # * Can we assume this fits memory? # * Yes # ## Test Cases # # * None as an input -> Exception # * Negative index for i or j -> Exception # * General case # #
# i = 2, j = 6 # j i # n = 0000 0100 0011 1101 # m = 0000 0000 0001 0011 # result = 0000 0100 0100 1101 ## ## Algorithm # #
# j i # n = 0000 0100 0011 1101 # m = 0000 0000 0001 0011 # # lmask = 1111 1111 1111 1111 -1 # lmask = 1111 1111 1000 0000 -1 << (j + 1) # # rmask = 0000 0000 0000 0001 1 # rmask = 0000 0000 0000 0100 1 << i # rmask = 0000 0000 0000 0011 (1 << i) -1 # # mask = 1111 1111 1000 0011 lmask | rmask # # n = 0000 0100 0011 1101 # mask = 1111 1111 1000 0011 n & mask # -------------------------------------------------- # n2 = 0000 0100 0000 0001 # # n2 = 0000 0100 0000 0001 # mask2 = 0000 0000 0100 1100 m << i # -------------------------------------------------- # result = 0000 0100 0100 1101 n2 | mask2 ## # Complexity: # * Time: O(b), where b is the number of bits # * Space: O(b), where b is the number of bits # ## Code # In[1]: class Bits(object): def insert_m_into_n(self, m, n, i, j): if None in (m, n, i, j): raise TypeError('Argument cannot be None') if i < 0 or j < 0: raise ValueError('Index cannot be negative') left_mask = -1 << (j + 1) right_mask = (1 << i) - 1 n_mask = left_mask | right_mask # Clear bits from j to i, inclusive n_cleared = n & n_mask # Shift m into place before inserting it into n m_mask = m << i return n_cleared | m_mask # ## Unit Test # In[2]: get_ipython().run_cell_magic('writefile', 'test_insert_m_into_n.py', "import unittest\n\n\nclass TestBit(unittest.TestCase):\n\n def test_insert_m_into_n(self):\n n = int('0000010000111101', base=2)\n m = int('0000000000010011', base=2)\n expected = int('0000010001001101', base=2)\n bits = Bits()\n self.assertEqual(bits.insert_m_into_n(m, n, i=2, j=6), expected)\n print('Success: test_insert_m_into_n')\n\n\ndef main():\n test = TestBit()\n test.test_insert_m_into_n()\n\n\nif __name__ == '__main__':\n main()\n") # In[3]: get_ipython().run_line_magic('run', '-i test_insert_m_into_n.py')