# Definition for an infinite stream.
# class InfiniteStream:
# def next(self) -> int:
# pass
class Solution:
def findPattern(
self,
stream: Optional['InfiniteStream'],
pattern: list[int],
) -> int:
lps = self._getLPS(pattern)
i = 0 # stream's index
j = 0 # pattern's index
bit = 0 # the bit in the stream
readNext = False
while True:
if not readNext:
bit = stream.next()
readNext = True
if bit == pattern[j]:
i += 1
readNext = False
j += 1
if j == len(pattern):
return i - j
# Mismatch after j matches.
elif j > 0:
# Don't match lps[0..lps[j - 1]] since they will match anyway.
j = lps[j - 1]
else:
i += 1
readNext = False
def _getLPS(self, pattern: list[int]) -> list[int]:
"""
Returns the lps array, where lps[i] is the length of the longest prefix of
pattern[0..i] which is also a suffix of this substring.
"""
lps = [0] * len(pattern)
j = 0
for i in range(1, len(pattern)):
while j > 0 and pattern[j] != pattern[i]:
j = lps[j - 1]
if pattern[i] == pattern[j]:
j += 1
lps[i] = j
return lps