• JUPYTER
  • FAQ
  • View as Code
  • Python 3 Kernel
  • View on GitHub
  • Execute on Binder
  • Download Notebook
  1. interactive-coding-challenges
  2. online_judges
  3. ransom_note

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

Solution Notebook¶

Problem: Given a magazine, see if a ransom note could have been written using the letters in the magazine.¶

  • Constraints
  • Test Cases
  • Algorithm
  • Code
  • Unit Test

Constraints¶

  • Is this case sensitive?
    • Yes
  • Can we assume we're working with ASCII characters?
    • Yes
  • Can we scan the entire magazine, or should we scan only when necessary?
    • You can scan the entire magazine
  • Can we assume the inputs are valid?
    • No
  • Can we assume this fits memory?
    • Yes

Test Cases¶

  • None -> Exception
  • '', '' -> Exception
  • 'a', 'b' -> False
  • 'aa', 'ab' -> False
  • 'aa', 'aab' -> True

Algorithm¶

  • Build a dictionary of the magazine characters and counts.
  • Loop through each letter in the ransom note and see if there are enough letters in the magazine's dictionary.
  • Note: You could make this more efficient by not scanning the entire magazine all at once, but instead scan just in time as you run out of letters in the dictionary.

Complexity:

  • Time: O(n+m), where n is the length of the ransom note and m is the length of the magazine
  • Space: O(n+m)

Code¶

In [1]:
class Solution(object):

    def match_note_to_magazine(self, ransom_note, magazine):
        if ransom_note is None or magazine is None:
            raise TypeError('ransom_note or magazine cannot be None')
        seen_chars = {}
        for char in magazine:
            if char in seen_chars:
                seen_chars[char] += 1
            else:
                seen_chars[char] = 1
        for char in ransom_note:
            try:
                seen_chars[char] -= 1
            except KeyError:
                return False
            if seen_chars[char] < 0:
                return False
        return True

Unit Test¶

In [2]:
%%writefile test_ransom_note.py
import unittest


class TestRansomNote(unittest.TestCase):

    def test_ransom_note(self):
        solution = Solution()
        self.assertRaises(TypeError, solution.match_note_to_magazine, None, None)
        self.assertEqual(solution.match_note_to_magazine('', ''), True)
        self.assertEqual(solution.match_note_to_magazine('a', 'b'), False)
        self.assertEqual(solution.match_note_to_magazine('aa', 'ab'), False)
        self.assertEqual(solution.match_note_to_magazine('aa', 'aab'), True)
        print('Success: test_ransom_note')


def main():
    test = TestRansomNote()
    test.test_ransom_note()


if __name__ == '__main__':
    main()
Overwriting test_ransom_note.py
In [3]:
%run -i test_ransom_note.py
Success: test_ransom_note

This website does not host notebooks, it only renders notebooks available on other websites.

Delivered by Fastly, Rendered by OVHcloud

nbviewer GitHub repository.

nbviewer version: 8b013f7

nbconvert version: 7.2.3

Rendered (Wed, 02 Jul 2025 20:06:49 UTC)