36 lines
1.1 KiB
Python
36 lines
1.1 KiB
Python
import itertools
|
|
|
|
def cycler(start_items):
|
|
return itertools.cycle(start_items).__next__
|
|
|
|
def _kolakoski_gen(start_items):
|
|
s, k = [], 0
|
|
c = cycler(start_items)
|
|
while True:
|
|
c_next = c()
|
|
s.append(c_next)
|
|
sk = s[k]
|
|
yield sk
|
|
if sk > 1:
|
|
s += [c_next] * (sk - 1)
|
|
k += 1
|
|
|
|
def kolakoski(start_items=(1, 2), length=20):
|
|
return list(itertools.islice(_kolakoski_gen(start_items), length))
|
|
|
|
def _run_len_encoding(truncated_series):
|
|
return [len(list(group)) for grouper, group in itertools.groupby(truncated_series)][:-1]
|
|
|
|
def is_series_eq_its_rle(series):
|
|
rle = _run_len_encoding(series)
|
|
return (series[:len(rle)] == rle) if rle else not series
|
|
|
|
if __name__ == '__main__':
|
|
for start_items, length in [((1, 2), 20), ((2, 1), 20),
|
|
((1, 3, 1, 2), 30), ((1, 3, 2, 1), 30)]:
|
|
print(f'\n## {length} members of the series generated from {start_items} is:')
|
|
s = kolakoski(start_items, length)
|
|
print(f' {s}')
|
|
ans = 'YES' if is_series_eq_its_rle(s) else 'NO'
|
|
print(f' Does it look like a Kolakoski sequence: {ans}')
|