Skip to content

Commit

Permalink
feat(strings): look and say sequence algorithm
Browse files Browse the repository at this point in the history
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
Show file tree
Hide file tree
Showing 8 changed files with 99 additions and 0 deletions.
28 changes: 28 additions & 0 deletions pystrings/look_and_say_sequence/README.md
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.
```

42 changes: 42 additions & 0 deletions pystrings/look_and_say_sequence/__init__.py
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 pystrings/look_and_say_sequence/test_look_and_say_sequence.py
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()

0 comments on commit 58a5558

Please sign in to comment.