-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(strings): look and say sequence algorithm
Adds a new algorithm to handle string processing where the count of each character in a provided string is added to the result of the output along with the character itself.
- Loading branch information
BrianLusina
authored and
BrianLusina
committed
Dec 11, 2024
1 parent
3ff15c0
commit 58a5558
Showing
8 changed files
with
99 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
# Look-and-Say Sequence | ||
|
||
The first few terms of the sequence are: | ||
|
||
```plain | ||
1, 11, 21, 1211, 111221, 312211, 13112221, 1113213211, ... | ||
``` | ||
|
||
To generate a member of the sequence from the previous member, read off the digits of the previous member and record the | ||
count of the number of digits in groups of the same digit. | ||
|
||
For example, 1 is read off as one 1 which implies that the count of 1 is one. As 1 is read off as “one 1”, the next | ||
sequence will be written as 11 where 1 replaces one. Now 11 is read off as “two 1s” as the count of “1” is two in this term. Hence, the next term in the sequence becomes 21. | ||
|
||
Look at the below images to see how we generate this sequence up to the fifth term: | ||
|
||
![First Term](images/first_term.png) | ||
![Second Term](images/second_term.png) | ||
![Third Term](images/third_term.png) | ||
![Fourth Term](images/fourth_term.png) | ||
![Fifth Term](images/fifth_term.png) | ||
|
||
Now, you can easily guess the sixth term. There you go: | ||
|
||
```plain | ||
111221 is read off as "three 1s, two 2s, then one 1" or 312211. | ||
``` | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
from typing import List | ||
|
||
|
||
def look_and_say_sequence(sequence: str) -> str: | ||
""" | ||
Counts the number of occurrences of each character in the provided sequence and returns the count of each character | ||
alongside the character itself as a string in the format `cx`, where c is the count and x is the character. This | ||
retains the sequence order passed in and only includes the counts | ||
Args: | ||
sequence (str): sequence of characters, e.g. "11" or "121", etc | ||
Returns: | ||
str: string in the format of count of characters along with the characters themselves, | ||
e.g. if sequence is "1", return will be "11" | ||
Complexity: | ||
Time: O(n) where n is the number of characters in the provided sequence as the algorithm has to iterate over each | ||
character in the sequence | ||
Space: O(n) where n is the number of characters in the provided sequence. This is because the algorithm uses a list | ||
to store the count of characters and the characters themselves to later join into a string as the result | ||
""" | ||
result: List[str] = [] | ||
i = 0 | ||
|
||
while i < len(sequence): | ||
# count is reset to one to keep track of the current count of the sequence | ||
count = 1 | ||
|
||
while i + 1 < len(sequence) and sequence[i] == sequence[i+1]: | ||
# here we keep track of consecutive similar characters and increase their count if we encounter them. | ||
|
||
i += 1 | ||
count += 1 | ||
|
||
# the string version of the count of the character is added along with the character itself to the resulting | ||
# list | ||
result.append(str(count) + sequence[i]) | ||
# we increment the i variable to move to the next character in the sequence | ||
i += 1 | ||
|
||
return "".join(result) |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
29 changes: 29 additions & 0 deletions
29
pystrings/look_and_say_sequence/test_look_and_say_sequence.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
import unittest | ||
from . import look_and_say_sequence | ||
|
||
|
||
class LookAndSaySequenceTestCases(unittest.TestCase): | ||
def test_1(self): | ||
"""sequence of 1 should return 11""" | ||
sequence = "1" | ||
expected = "11" | ||
actual = look_and_say_sequence(sequence) | ||
self.assertEqual(expected, actual) | ||
|
||
def test_2(self): | ||
"""sequence of 11 should return 21""" | ||
sequence = "11" | ||
expected = "21" | ||
actual = look_and_say_sequence(sequence) | ||
self.assertEqual(expected, actual) | ||
|
||
def test_3(self): | ||
"""sequence of 21 should return 1211""" | ||
sequence = "21" | ||
expected = "1211" | ||
actual = look_and_say_sequence(sequence) | ||
self.assertEqual(expected, actual) | ||
|
||
|
||
if __name__ == '__main__': | ||
unittest.main() |