When two or more different monomers unite together to polymerize, the result is called a heteropolymer or a copolymer. Polymers that contain only a single type of repeat unit are known as homopolymers. Commercially relevant copolymers include acrylonitrile butadiene styrene (ABS) plastic, styrene-butadiene rubber (SBR), nitrile rubber, styrene-acrylonitrile, styrene-isoprene-styrene (SIS) and ethylene-vinyl acetate.
Since a copolymer consists of at least two types of constituent units (also structural units), they can be classified based on how these units are arranged along the chain. Periodic copolymers, for example, are copolymers whose structural units are arranged in a repeating sequence. If we represent structural units by uppercase letters, the shorthand notation for periodic copolymers reads as $$(ABC)_n$$. In this notation, $$ABC$$ indicates the period and $$n \in \mathbb{N}$$ ($$n \geq 2$$) indicates that the periodic copolymer consists of $$n$$ repetitions of the period.
In this exercise, copolymers are represented as strings containing uppercase letters only. Each uppercase letter represents one of the structural units used as building blocks of the copolymer. Your task is to check whether or not a given copolymer is periodic. If this is the case, you also have to derive the shorthand notation for the periodic copolymer. This is done in the following way:
Write a function copolymer that takes a single string. If the given strings contains uppercase letters only, it already represents a copolymer and the function must return the string itself. However, if the string is formatted as (p)_n, it represents the shorthand notation of a periodic copolymer with period $$p$$ repeated $$n \in \mathbb{N}_0$$ times. In this case, the function must return the periodic copolymer in full length.
Write a function is_periodic that takes two strings. The first argument represents a copolymer and the second argument a period (which is a copolymer itself). The function must return a Boolean value that indicates whether or not the given copolymer (first argument) is composed as a set number of repetitions of the given period (second argument).
Use the function is_periodic to write a function period that takes a string representing a copolymer. The function must return the shortest possible period of the copolymer. This period may be equal to the given copolymer itself, in case the copolymer is not composed as the repetition of a shorter period. The function also has an optional parameter minimal_repetition that takes an integer $$n \in \mathbb{N}_0$$ (default value: 1). In case the given copolymer is not composed out of a period that is repeated at least $$n$$ times, the function must return the empty string.
Use the function period to write a function shorthand that takes a string representing a copolymer. In case the copolymer is periodic with a period that is repeated at least twice, the function must return the short notation of the copolymer formatted as (p)_n. In this notation, $$p$$ represents the shortest possible period of the periodic copolymer, and $$n \in \mathbb{N}_0$$ ($$n \geq 2$$) represents the number of repetitions of the period in the copolymer. In case the copolymer is not periodic or if the copolymer is not composed of at least two repetitions of a period, the function must return the given copolymer itself.
>>> copolymer('(AB)_18')
'ABABABABABABABABABABABABABABABABABAB'
>>> copolymer('(ABBA)_9')
'ABBAABBAABBAABBAABBAABBAABBAABBAABBA'
>>> copolymer('(ABABBAAAABBB)_3')
'ABABBAAAABBBABABBAAAABBBABABBAAAABBB'
>>> copolymer('ABABBAAAABBBABABBAAAABBBBBABBAAAABBB')
'ABABBAAAABBBABABBAAAABBBBBABBAAAABBB'
>>> is_periodic('ABABABABABABABABABABABABABABABABABAB', 'AB')
True
>>> is_periodic('ABABABABABABABABABABABABABABABABABAB', 'ABA')
False
>>> is_periodic('ABABABABABABABABABABABABABABABABABAB', 'ABAB')
True
>>> is_periodic('ABABBAAAABBBABABBAAAABBBABABBAAAABBB', 'ABABBAAAABBB')
True
>>> period('ABABABABABABABABABABABABABABABABABAB')
'AB'
>>> period('ABABABABABABABABABABABABABABABABABAB', minimal_repetition=10)
'AB'
>>> period('ABABABABABABABABABABABABABABABABABAB', 20)
''
>>> period('ABBAABBAABBAABBAABBAABBAABBAABBAABBA')
'ABBA'
>>> period('ABABBAAAABBBABABBAAAABBBABABBAAAABBB')
'ABABBAAAABBB'
>>> period('ABABBAAAABBBABABBAAAABBBBBABBAAAABBB')
'ABABBAAAABBBABABBAAAABBBBBABBAAAABBB'
>>> period('ABABBAAAABBBABABBAAAABBBBBABBAAAABBB', 2)
''
>>> shorthand('ABABABABABABABABABABABABABABABABABAB')
'(AB)_18'
>>> shorthand('ABBAABBAABBAABBAABBAABBAABBAABBAABBA')
'(ABBA)_9'
>>> shorthand('ABABBAAAABBBABABBAAAABBBABABBAAAABBB')
'(ABABBAAAABBB)_3'
>>> shorthand('ABABBAAAABBBABABBAAAABBBBBABBAAAABBB')
'ABABBAAAABBBABABBAAAABBBBBABBAAAABBB'