From ebf6981c3e463b4a5f7d6d9d527022127cd59851 Mon Sep 17 00:00:00 2001 From: Kristian Rother Date: Wed, 5 Jun 2024 16:45:15 +0200 Subject: [PATCH] improve anagram challenge --- challenges/anagrams.rst | 31 ++++++++++++++++++------------- solutions/anagrams.py | 35 +++++++++++++++++++++++++++++++++++ 2 files changed, 53 insertions(+), 13 deletions(-) create mode 100644 solutions/anagrams.py diff --git a/challenges/anagrams.rst b/challenges/anagrams.rst index 55ac2a8..100bdf0 100644 --- a/challenges/anagrams.rst +++ b/challenges/anagrams.rst @@ -1,35 +1,40 @@ Anagrams ======== -**🎯 Generate all anagrams of a word with 3-6 letters.** +**🎯 Check whether two words are anagrams of each other.** For example, the string: :: - ROT + players -has the anagrams (permutations of characters): +has the anagram (permutations of characters): :: - TOR - ORT - TRO - RTO - OTR + parsley + +Write a function `anagram()` that satisfies the following checks: + +.. code:: python3 + + assert anagram("players", "parsley") is True + assert anagram("hello", "world") is False Hints ----- -- Look up the function ``itertools.permutations()``. -- You may need an expression like ``''.join(["T", "O", "R"])`` +- consider sorting the characters +- consider the `set()` data type +- consider `collections.Counter` +- look up the function `itertools.permutations()`. Extra challenges ---------------- -- Get yourself a word list. Find anagrams that are real words. -- Implement the algorithm to generate the anagrams yourself. Get - informed about **dynamic programming**. +- Look for anagrams in the `SOWPODS word list `__ . +- Implement an algorithm to generate all possible anagrams. Inform yourself about **dynamic programming**. +- what is the time complexity of your implementation? *Translated with* `www.DeepL.com `__ diff --git a/solutions/anagrams.py b/solutions/anagrams.py new file mode 100644 index 0000000..1f43961 --- /dev/null +++ b/solutions/anagrams.py @@ -0,0 +1,35 @@ +from collections import Counter +from itertools import permutations + + +def anagram(s1: str, s2: str) -> bool: + """clean and neat solution in O(n log n) time""" + return sorted(s1) == sorted(s2) + + +def anagram(s1: str, s2: str) -> bool: + """from scratch solution, also O(n log n) because of 'in' """ + if len(s1) == len(s2): + for c1 in s1: + if c1 not in s2: + return False + return True + return False + +def anagram(s1: str, s2: str) -> bool: + """faster O(n) but fails for character duplicates""" + return set(s1) == set(s2) + +def anagram(s1: str, s2: str) -> bool: + """using counter dict, covers duplicates and should be O(n)""" + return Counter(s1) == Counter(s2) + + +def anagram(s1: str, s2: str) -> bool: + """super slow, probably O(n!)""" + return tuple(s1) in permutations(s2) + + + +assert anagram("players", "parsley") is True +assert anagram("hello", "foo") is False \ No newline at end of file