Dr. Eureka is a game where players take on the role of apprentice scientists. They race to be the first to realize the correct combination of the colored balls in the test tubes, in the order prescribed on the current challenge card. In order to achieve this, players must transfer the balls from one tube to the other, without touching them with their hands or letting them fall from the tubes.

Dr. Eureka
A player of the Dr.Eureka game has managed to arrange the materials in the test tubes in the correct order prescribed on the challenge card.

When all players are ready to get started, the top challenge card is turned face up. All at the same time, players race to complete the challenge by transferring their balls from one tube to another, trying to arrange their balls in the order shown on the current challenge card. Players must obey the following rules:

opdracht
Een opdracht kan voltooid worden met alle reageerbuizen rechtopstaand (A) of door één buis omgekeerd neer te zetten (B).

The order of the test tubes (from left to right) doesn't matter in realizing a combination. Only the order of the colored balls in the test tubes (from top to bottom) matters. Players are allowed to swap the position of their tubes if that may help them.

If a player touches or drops one of his balls, or incorrectly announces that he has completed the challenge, he is immediately removed from the rest of the round (until the current challenge card is completed).

The game is played with a fixed number of test tubes. These tubes have a maximal capacity, which indicates the maximum number of balls that fit in a test tube.

The first player who arranges his balls in the correct combination, calls out "Eureka!". If all the players agree that his combination is correct, he scores the current challenge card as 1 point.

Players leave their balls where they were at the end of the previous challenge. They are not returned to a particular starting position. However, all tubes must be turned right side up before beginning a new round. When all player are ready to start again, a new round begins by drawing the next challenge card face up. The first player to 5 points (5 challenge cards) wins the game.

Assignment

Define a class Eureka that can be used to simulate how the players of Dr. Eureka can arrange the colored balls into their test tubes. To refer to the individual test tubes, the tubes are numbered from left to right, starting from 0.

When creating a simulation (Eureka), a string (str) must be passed that describes the configuration of the colored balls in the different test tubes. Each ball is represented as an uppercase letter that indicates the color of the ball (the same letters represent balls of the same color). Each test tube is described by the sequence of balls it contains, listed from bottom to top. The successive test tubes are separated by commas (,). For example, PG,GR,PR describes the configuration of three test tubes that can be seen in the first image of the introduction, where the uppercase letter P represents a purple ball, G a green ball and R a red ball.

The maximum capacity (int) of the test tubes can be passed to the optional parameter maximum (default value: 4). If one of the test tubes in the given configuration exceeds the maximum capacity, an AssertionError must be raised with the message invalid configuration.

If a test tube is flipped upside down, its number (int) can be passed to the optional parameter flipped. All test tubes are turned right side up by default. If an invalid number is passed, an AssertionError must be raised with the message invalid configuration.

If a simulation (Eureka) is passed to the built-in function repr, a string representation (str) must be returned that reads as a Python expression to create a new simulation with the same configuration as the object passed to the function repr. The maximum capacity of the test tubes must always be passed explicitly to the parameter maximum. Only if one of the test tubes is flipped upside down, its number must be passed to the parameter flipped.

If a simulation (Eureka) is passed to the built-in function str, a string representation (str) of the test tube configuration must be returned. The format of this representation can be derived from the examples below. Note that the top (= =) and bottom (===) of each test tube indicate whether the tube is upright or upside down. All tubes are separated from each other by a single space in the string representation.

In addition, the class Eureka must support at least the following methods:

Two simulations $$r$$ and $$s$$ (Eureka) are the same (r == s) if the colored balls are arranged in the same order (from bottom to top) in the test tubes. The order of the test tubes (from left to right) doesn't matter. Also the position of the test tubes (upright or upside down) or the maximum capacity of the tubes isn't taken into account.

Example

>>> game = Eureka('RPG,G,PR')
>>> game
Eureka('RPG,G,PR', maximum=4)
>>> print(game)
= = = = = =
| | | | | |
|G| | | | |
|P| | | |R|
|R| |G| |P|
=== === ===
>>> game.transfer(0, 1, 1)
Eureka('RP,GG,PR', maximum=4)
>>> print(game)
= = = = = =
| | | | | |
| | | | | |
|P| |G| |R|
|R| |G| |P|
=== === ===
>>> game.transfer(1, 2, 2)
Eureka('RP,,PRGG', maximum=4)
>>> print(game)
= = = = = =
| | | | |G|
| | | | |G|
|P| | | |R|
|R| | | |P|
=== === ===
>>> game.transfer(0, 1, 1)
Eureka('R,P,PRGG', maximum=4)
>>> print(game)
= = = = = =
| | | | |G|
| | | | |G|
| | | | |R|
|R| |P| |P|
=== === ===
>>> game.transfer(2, 1, 1).transfer(2, 0, 1)
Eureka('RG,PG,PR', maximum=4)
>>> print(game)
= = = = = =
| | | | | |
| | | | | |
|G| |G| |R|
|R| |P| |P|
=== === ===
>>> game.flip(2)
Eureka('RG,PG,RP', maximum=4, flipped=2)
>>> print(game)
= = = = ===
| | | | | |
| | | | | |
|G| |G| |P|
|R| |P| |R|
=== === = =
>>> game == Eureka('RP,RG,PG')
True
>>> game == Eureka('PR,RG,PG')
False

>>> game.flip(100)                     # wrong tube index
Traceback (most recent call last):
AssertionError: invalid move
>>> game.flip(0)                       # another tube is already flipped over
Traceback (most recent call last):
AssertionError: invalid move
>>> game.transfer(0, 1)                # a tube is flipped over
Traceback (most recent call last):
AssertionError: invalid move

>>> game.flip(2)
Eureka('RG,PG,PR', maximum=4)
>>> print(game)
= = = = = =
| | | | | |
| | | | | |
|G| |G| |R|
|R| |P| |P|
=== === ===
>>> game.transfer(0, 100)              # wrong tube index
Traceback (most recent call last):
AssertionError: invalid move
>>> game.transfer(100, 0)              # wrong tube index
Traceback (most recent call last):
AssertionError: invalid move
>>> game.transfer(0, 0)                # tube cannot be transferred into itself
Traceback (most recent call last):
AssertionError: invalid move
>>> game.transfer(0, 1)
Eureka(',PGGR,PR', maximum=4)
>>> print(game)
= = = = = =
| | |R| | |
| | |G| | |
| | |G| |R|
| | |P| |P|
=== === ===
>>> game.transfer(2, 1)                # capacity of tube 1 would be exceeded
Traceback (most recent call last):
AssertionError: invalid move
>>> game.transfer(0, 1)
Eureka(',PGGR,PR', maximum=4)
>>> print(game)
= = = = = =
| | |R| | |
| | |G| | |
| | |G| |R|
| | |P| |P|
=== === ===