Een berucht probleem in de moleculaire biologie is het vouwen van eiwitten. Een eiwitmolecuul bestaat uit een keten van aminozuren die zichzelf spontaan opvouwt tot een driedimensionale vorm die energetisch het gunstigst is. Deze bindingsenergie hangt af van de onderlinge positie van alle aminozuren. Dit levert zoveel mogelijkheden op dat zelfs de modernste supercomputers hier nog op stuklopen.

Om het probleem iets makkelijker te maken, gaan we een eiwitmolecuul simuleren dat zich in twee dimensies opvouwt. De begintoestand is een vierkant rooster waarin elk aminozuur een positieve of negatieve lading heeft. Het opvouwen gebeurt door schotjes tussen de hokjes te plaatsen, zodanig dat een keten door het rooster ontstaat die alle hokjes omvat. De uiteinden van het molecuul hoeven niet aan de rand van het rooster te liggen.

Overal waar een schotje tussen twee hokjes staat, is het molecuul gevouwen en raken de aminozuren elkaar. Als tussen een hokje met lading $$-3$$ en een hokje met lading $$4$$ een schotje staat, dan levert dit een bindingsenergie van $$-3 \times 4 = -12$$ op. Een aminozuur kan aan meerdere aminozuren raken, en levert dan met elke buur bindingsenergie op. Uiteraard kan, vanwege de mintekens, bindingsenergie zowel positief als negatief zijn.

eiwitvouwen

Als voorbeeld staat hierboven een $$4\times4$$ rooster, waarin een eiwit met 16 aminozuren is opgevouwen tot een configuratie met bindingsenergie gelijk aan \[ \begin{multline} \phantom{xxxxxxxxxxxx}(-1 \times 2) + (2 \times -5) + (5 \times -3) + (4 \times 3) + (5\times -1) + \phantom{x}\\ (-1 \times 2) + (-4 \times 2) + (-5 \times 6) + (1 \times 2) =  -58\phantom{xxxxxxxxxxxx} \nonumber \end{multline} \]

Opgave

Definieer een klasse Eiwit met volgende methoden:

Voorbeeld

>>> eiwit = Eiwit([-2, 5, -4, 2, 4, -1, 2])
Traceback (most recent call last):
AssertionError: ongeldige begintoestand

>>> eiwit = Eiwit([-2, 5, -4, 2, 4, -1, 2, 1, 3, 2, -5, 2, 5, -3, 6, 1])
>>> eiwit.bindingsenergie()
0
>>> print(eiwit)
+----+----+----+----+
| -2   5    -4   2  |
+    +    +    +    +
| 4    -1   2    1  |
+    +    +    +    +
| 3    2    -5   2  |
+    +    +    +    +
| 5    -3   6    1  |
+----+----+----+----+

>>> eiwit.opvouwen([(1, 1, 1, 2), (2, 1, 2, 2), (3, 0, 3, 1),
...                 (1, 0, 2, 0), (0, 1, 1, 1), (1, 1, 2, 1),
...                 (0, 2, 1, 2), (2, 2, 3, 2), (1, 3, 2, 3)])
>>> eiwit.bindingsenergie()
-58
>>> print(eiwit)
+----+----+----+----+
| -2   5    -4   2  |
+    +----+----+    +
| 4    -1 | 2    1  |
+----+----+    +----+
| 3    2  | -5   2  |
+    +    +----+    +
| 5  | -3   6    1  |
+----+----+----+----+

>>> eiwit.opvouwen([(1, 1, 1, 2), (2, 1, 2, 2), (4, 0, 4, 1)])
Traceback (most recent call last):
AssertionError: ongeldige configuratie
>>> eiwit.opvouwen([(1, 1, 1, 2), (2, 1, 3, 3), (3, 0, 3, 1)])
Traceback (most recent call last):
AssertionError: ongeldige configuratie

>>> eiwit = Eiwit([7, -2, -4, 3], [(0, 1, 1, 1)])
>>> eiwit.bindingsenergie()
-6
>>> print(eiwit)
+----+----+
| 7    -2 |
+    +----+
| -4   3  |
+----+----+