Shifting a string of lowercase letters moves every character forward by the same number of places in the alphabet, wrapping from z back to a. Shifting "abc" by 1 gives "bcd", and shifting "az" by 1 gives "ba". Two strings belong to the same shift family when one of them becomes the other after a single shift by some amount from 0 to 25.
Given a list of strings, split it into shift families.
Function Signature
def group_shift_families(strings: List[str]) -> List[List[str]]:
Rules
-
A shift moves every character of the string by the same amount, modulo 26.
-
Strings of different lengths are never in the same family.
-
Every input element appears exactly once in the output. Duplicate strings are separate elements and land in the same family.
-
Inside a family, strings appear in their input order.
-
Families are ordered by the input index of their first member.
Constraints
-
1 <= len(strings) <= 10^4
-
1 <= len(strings[i]) <= 50
-
Every string contains only the lowercase English letters
a
to
z
.
Examples
Example 1
Input: strings = ["abc", "bcd", "acef", "xyz", "az", "ba", "a", "z"]
Output: [["abc", "bcd", "xyz"], ["acef"], ["az", "ba"], ["a", "z"]]
Shifting "abc" by 1 gives "bcd" and by 23 gives "xyz". No other string has length 4, so "acef" is alone. Shifting "az" by 1 gives "ba". Any two one-letter strings are shifts of each other. The families start at input indices 0, 2, 4 and 6.
Example 2
Input: strings = ["ab", "ab", "yz", "ac"]
Output: [["ab", "ab", "yz"], ["ac"]]
Both copies of "ab" are kept, and "yz" is "ab" shifted by 24.
Example 3
Input: strings = ["a"]
Output: [["a"]]