This notebook was prepared by Donne Martin. Source and license info is on GitHub.

Challenge Notebook

Problem: Add two numbers whose digits are stored in a linked list in reverse order.

Constraints

  • Can we assume this is a non-circular, singly linked list?
    • Yes
  • Do we expect the return to be in reverse order too?
    • Yes
  • What if one of the inputs is None?
    • Return None for an invalid operation
  • How large are these numbers--can they fit in memory?
    • Yes
  • Can we assume we already have a linked list class that can be used for this problem?
    • Yes
  • Can we assume this fits in memory?
    • Yes

Test Cases

  • Empty list(s) -> None
  • Add values of different lengths
    • Input 1: 6->5->None
    • Input 2: 9->8->7
    • Result: 5->4->8
  • Add values of same lengths
    • Exercised from values of different lengths
    • Done here for completeness

Algorithm

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.

Code

In [ ]:
%run ../linked_list/linked_list.py
%load ../linked_list/linked_list.py
In [ ]:
class MyLinkedList(LinkedList):

    def add_reverse(self, first_list, second_list):
        # TODO: Implement me
        pass

Unit Test

The following unit test is expected to fail until you solve the challenge.

In [ ]:
# %load test_add_reverse.py
import unittest


class TestAddReverse(unittest.TestCase):

    def test_add_reverse(self):
        print('Test: Empty list(s)')
        self.assertEqual(MyLinkedList().add_reverse(None, None), None)
        self.assertEqual(MyLinkedList().add_reverse(Node(5), None), None)
        self.assertEqual(MyLinkedList().add_reverse(None, Node(10)), None)

        print('Test: Add values of different lengths')
        # Input 1: 6->5->None
        # Input 2: 9->8->7
        # Result: 5->4->8
        first_list = MyLinkedList(Node(6))
        first_list.append(5)
        second_list = MyLinkedList(Node(9))
        second_list.append(8)
        second_list.append(7)
        result = MyLinkedList().add_reverse(first_list, second_list)
        self.assertEqual(result.get_all_data(), [5, 4, 8])

        print('Test: Add values of same lengths')
        # Input 1: 6->5->4
        # Input 2: 9->8->7
        # Result: 5->4->2->1
        first_head = Node(6)
        first_list = MyLinkedList(first_head)
        first_list.append(5)
        first_list.append(4)
        second_head = Node(9)
        second_list = MyLinkedList(second_head)
        second_list.append(8)
        second_list.append(7)
        result = MyLinkedList().add_reverse(first_list, second_list)
        self.assertEqual(result.get_all_data(), [5, 4, 2, 1])

        print('Success: test_add_reverse')


def main():
    test = TestAddReverse()
    test.test_add_reverse()


if __name__ == '__main__':
    main()

Solution Notebook

Review the Solution Notebook for a discussion on algorithms and code solutions.