Skip to content

Commit 1fd5e8a

Browse files
authored
Merge pull request #541 from sir-gon/feature/sherlock_and_anagrams
Feature/sherlock and anagrams
2 parents fdfdb9a + f089797 commit 1fd5e8a

File tree

4 files changed

+118
-55
lines changed

4 files changed

+118
-55
lines changed

docs/hackerrank/interview_preparation_kit/dictionaries_and_hashmaps/sherlock_and_anagrams.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# [Sherlock and Anagrams](https://www.hackerrank.com/challenges/mark-and-toys)
22

33
- Difficulty: `#medium`
4-
- Category: `#ProblemSolvingMedium`
4+
- Category: `#ProblemSolvingMedium` `#DictionariesAndHashmaps` `#Strings`
55

66
Two strings are [http://en.wikipedia.org/wiki/Anagram](anagrams) of each other
77
if the letters of one string can be rearranged to form the other string.
Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
[
2+
{
3+
"title": "Sample Test Case 0",
4+
"tests": [
5+
{
6+
"input": "abba",
7+
"expected": 4
8+
},
9+
{
10+
"input": "abcd",
11+
"expected": 0
12+
}
13+
]
14+
},
15+
{
16+
"title": "Sample Test Case 1",
17+
"tests": [
18+
{
19+
"input": "ifailuhkqq",
20+
"expected": 3
21+
},
22+
{
23+
"input": "kkkk",
24+
"expected": 10
25+
}
26+
]
27+
},
28+
{
29+
"title": "Sample Test Case 1",
30+
"tests": [
31+
{
32+
"input": "cdcd",
33+
"expected": 5
34+
}
35+
]
36+
},
37+
{
38+
"title": "Test case 3",
39+
"tests": [
40+
{
41+
"input":
42+
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
43+
"expected": 166650
44+
},
45+
{
46+
"input":
47+
"bbcaadacaacbdddcdbddaddabcccdaaadcadcbddadababdaaabcccdcdaacadcababbabbdbacabbdcbbbbbddacdbbcdddbaaa",
48+
"expected": 4832
49+
},
50+
{
51+
"input":
52+
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
53+
"expected": 166650
54+
},
55+
{
56+
"input":
57+
"cacccbbcaaccbaacbbbcaaaababcacbbababbaacabccccaaaacbcababcbaaaaaacbacbccabcabbaaacabccbabccabbabcbba",
58+
"expected": 13022
59+
},
60+
{
61+
"input":
62+
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
63+
"expected": 166650
64+
},
65+
{
66+
"input":
67+
"bbcbacaabacacaaacbbcaabccacbaaaabbcaaaaaaaccaccabcacabbbbabbbbacaaccbabbccccaacccccabcabaacaabbcbaca",
68+
"expected": 9644
69+
},
70+
{
71+
"input":
72+
"cbaacdbaadbabbdbbaabddbdabbbccbdaccdbbdacdcabdbacbcadbbbbacbdabddcaccbbacbcadcdcabaabdbaacdccbbabbbc",
73+
"expected": 6346
74+
},
75+
{
76+
"input":
77+
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
78+
"expected": 166650
79+
},
80+
{
81+
"input":
82+
"babacaccaaabaaaaaaaccaaaccaaccabcbbbabccbbabababccaabcccacccaaabaccbccccbaacbcaacbcaaaaaaabacbcbbbcc",
83+
"expected": 8640
84+
},
85+
{
86+
"input":
87+
"bcbabbaccacbacaacbbaccbcbccbaaaabbbcaccaacaccbabcbabccacbaabbaaaabbbcbbbbbaababacacbcaabbcbcbcabbaba",
88+
"expected": 11577
89+
}
90+
]
91+
}
92+
]
Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,25 @@
11
# @link Problem definition
22
# [[docs/hackerrank/interview_preparation_kit/dictionaries_and_hashmaps/sherlock_and_anagrams.md]]
33

4+
from typing import Dict, List
45
import math
56

7+
import logging
8+
9+
LOGGER = logging.getLogger(__name__)
10+
611

712
def sherlock_and_anagrams(s_word: str) -> int:
813

9-
candidates = {}
10-
size = len(s_word)
14+
candidates: Dict[str, List[str]] = {}
15+
size: int = len(s_word)
1116

1217
# Calculate all substrings
1318
for i in range(0, size):
1419
for j in range(0, size - i):
1520
substr = s_word[i:size - j]
16-
print(f'i: {i}, {size} size - j: {size - j} | substr: {substr}')
21+
LOGGER.debug('i: %i, size: %i, size - j: %i | substr: %s',
22+
i, size, size - j, substr)
1723

1824
# Add substrings to a candidate list.
1925
# two strings are anagrams if sorted strings are the same.
@@ -25,20 +31,20 @@ def sherlock_and_anagrams(s_word: str) -> int:
2531
else:
2632
candidates[anagram_candidate] = [substr]
2733

28-
count = 0
34+
count: int = 0
2935
# Final Anagram list
30-
for i in list(candidates):
31-
total = len(candidates[i])
36+
for word in list(candidates):
37+
quantity_of_anagrams = len(candidates[word])
3238
k = 2
3339

34-
if len(candidates[i]) <= 1:
35-
del candidates[i]
40+
if quantity_of_anagrams <= 1:
41+
del candidates[word]
3642
else:
3743
# Binomial coefficient: https://en.wikipedia.org/wiki/Binomial_coefficient
38-
count += math.factorial(total) // (
39-
math.factorial(k) * math.factorial(total - k)
44+
count += math.factorial(quantity_of_anagrams) // (
45+
math.factorial(k) * math.factorial(quantity_of_anagrams - k)
4046
)
4147

42-
print(f'filtered candidates: {count}')
48+
LOGGER.debug('Sherlock_and_anagrams() Filtered candidates %i', count)
4349

4450
return count
Lines changed: 8 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -1,48 +1,13 @@
11
import unittest
2+
import json
3+
from pathlib import Path
24

35
from .sherlock_and_anagrams import sherlock_and_anagrams
46

5-
6-
TEST_CASES = [
7-
{
8-
'title': 'Sample Test Case 0',
9-
'tests':
10-
[
11-
{
12-
'input': 'abba',
13-
'answer': 4
14-
},
15-
{
16-
'input': 'abcd',
17-
'answer': 0
18-
}
19-
]
20-
},
21-
{
22-
'title': 'Sample Test Case 1',
23-
'tests':
24-
[
25-
{
26-
'input': 'ifailuhkqq',
27-
'answer': 3
28-
},
29-
{
30-
'input': 'kkkk',
31-
'answer': 10
32-
}
33-
]
34-
},
35-
{
36-
'title': 'Sample Test Case 1',
37-
'tests':
38-
[
39-
{
40-
'input': 'cdcd',
41-
'answer': 5
42-
}
43-
]
44-
}
45-
]
7+
FILE_PATH = str(Path(__file__).resolve().parent)
8+
JSON_DATA_FILE = FILE_PATH + '/sherlock_and_anagrams.json'
9+
with open(JSON_DATA_FILE, encoding="utf-8") as file:
10+
TEST_CASES = json.load(file)
4611

4712

4813
class TestSherlockAndAnagrams(unittest.TestCase):
@@ -54,6 +19,6 @@ def test_sherlock_and_anagrams(self):
5419
for _, _tt in enumerate(testset['tests']):
5520

5621
self.assertEqual(
57-
sherlock_and_anagrams(_tt['input']), _tt['answer'],
22+
sherlock_and_anagrams(_tt['input']), _tt['expected'],
5823
f"{_} | sherlock_and_anagrams({_tt['input']}) must be "
59-
f"=> {_tt['answer']}")
24+
f"=> {_tt['expected']}")

0 commit comments

Comments
 (0)