Skip to content

Instantly share code, notes, and snippets.

@victor-iyi
Last active March 12, 2021 06:22
Show Gist options
  • Save victor-iyi/23fb1f8f90ff91054a448311905873f0 to your computer and use it in GitHub Desktop.
Save victor-iyi/23fb1f8f90ff91054a448311905873f0 to your computer and use it in GitHub Desktop.
Check if two words are anagram
"""Classic interview question to check if two words are anagram."""
import collections
import itertools
import pytest
def is_anagram(first: str, second: str) -> bool:
"""Implementation of anagram checker with 3 different methods.
Note:
Method 1 - Uses brute force.
Method 2 - Uses the built in `sorted` function.
Method 3 - Uses `itertools`' Counter method.
Method 3 is the fasted while Method 1 is the slowest at O(n!*n!)
Args:
first (str) - First word.
second (str) - Second word.
Return:
(bool) - Whether `first` and `second` are anagrams.
"""
# Method 1 (Brute force):
# for permutation1 in itertools.permutation(first):
# for permutation2 in itertools.permutation(second):
# if permutation1 == permutation2:
# return True
# return False
# Method 2 (Sort):
# return sorted(first) == sorted(second)
# Method 3 (Counter):
return collections.Counter(first) == collections.Counter(second)
@pytest.mark.parametrize(
('first', 'second')
(
('', ''), # An emtpy string is a valid anagram.
('a', 'a'), # Same 1 char string is a valid anagram.
('of', 'fo'), # Same counts of same char is a valid anagram.
('oof', 'foo'), # Same counts of same char is a valid anagram.
)
)
def test_matches(first, second):
"""Test to show the first and second word is a valid anagram."""
assert is_anagram(first, second) is True
@pytest.mark.parametrize(
('first', 'second'),
(
('a', 'b'), # Different 1 char isn't a valid anagram.
('of', 'off'), # Different sized string isn't a valid anagram.
('oof', 'ffo'), # Different counts of same char isn't an anagram.
)
)
def test_not_matches(first, second):
"""Test to show the first and second word isn't a valid anagram."""
assert is_anagram(first, second) is False
@victor-iyi
Copy link
Author

Classic interview question to check if two words are anagram.

Install PyTest to run tests:

$ virtualenv venv
created virtual environment CPython3.8.7.final.0-64 in 158ms
  creator CPython3Posix(dest=/Users/johndoe/workspace/venv, clear=False, no_vcs_ignore=False, global=False)
  seeder FromAppData(download=False, pip=bundle, setuptools=bundle, wheel=bundle, via=copy, app_data_dir=/Users/johndoe/Library/Application Support/virtualenv)
    added seed packages: pip==21.0.1, setuptools==53.0.0, wheel==0.36.2
  activators BashActivator,CShellActivator,FishActivator,PowerShellActivator,PythonActivator,XonshActivator
(venv) $ . venv/bin/activate
(venv) $ pip install pytest
Collecting pytest
  Using cached pytest-6.2.2-py3-none-any.whl (280 kB)
Collecting attrs>=19.2.0
  Using cached attrs-20.3.0-py2.py3-none-any.whl (49 kB)
Collecting packaging
  Using cached packaging-20.9-py2.py3-none-any.whl (40 kB)
Collecting toml
  Using cached toml-0.10.2-py2.py3-none-any.whl (16 kB)
Collecting pluggy<1.0.0a1,>=0.12
  Using cached pluggy-0.13.1-py2.py3-none-any.whl (18 kB)
Collecting iniconfig
  Using cached iniconfig-1.1.1-py2.py3-none-any.whl (5.0 kB)
Collecting py>=1.8.2
  Using cached py-1.10.0-py2.py3-none-any.whl (97 kB)
Collecting pyparsing>=2.0.2
  Using cached pyparsing-2.4.7-py2.py3-none-any.whl (67 kB)
Installing collected packages: pyparsing, toml, py, pluggy, packaging, iniconfig, attrs, pytest
Successfully installed attrs-20.3.0 iniconfig-1.1.1 packaging-20.9 pluggy-0.13.1 py-1.10.0 pyparsing-2.4.7 pytest-6.2.2 toml-0.10.2

You can run the test like so:

$ pytest anagram.py
================================================= test session starts ==================================================
platform darwin -- Python 3.8.7, pytest-6.2.2, py-1.10.0, pluggy-0.13.1
rootdir: /Users/johndoe/workspace
collected 7 items                                                                                                      
anagram.py .......                                                                                               [100%]
================================================== 7 passed in 0.01s ===================================================

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment