In het laboratorium gebruikt men centrifuges om vloeibare mengsels op basis van dichtheid te scheiden. In een centrifuge zitten gaten waarin reageerbuizen kunnen geplaatst worden. Door de reageerbuizen met hoge snelheid te laten ronddraaien, zorgt de middelpuntvliedende kracht1 (centrifugale kracht) voor de scheiding. Dit is bijvoorbeeld een centrifuge met 20 gaten, waarvan er 8 met reageerbuizen gevuld zijn:

centrifuge
Een centrifuge met 8 proefbuizen verdeeld over 20 gaten.

Opgave

Voor een centrifuge met $$n$$ gaten die op gelijke afstand rond een cirkel liggen, voeren we een coördinatenstelsel in waarbij de X-as en de Y-as elkaar snijden in het middelpunt van die cirkel. Er is altijd een gat waarvan het middelpunt op de positieve X-as ligt. De gaten worden in tegenwijzerzin genummerd vanaf 0, te beginnen bij dit gat waarvan het middelpunt op de positieve X-as ligt.

centrifuge
De zes gaten van deze centrifuge worden in tegenwijzerzin genummerd vanaf nul, te beginnen bij het gat waarvan het middelpunt op de positieve X-as ligt. De vier oranje gaten (0, 1, 3 en 4) zijn gevuld met reageerbuizen en de twee grijze gaten (2 en 5) zijn leeg.

Een configuratie die beschrijft welke gaten van een centrifuge gevuld zijn met reageerbuizen, stellen we voor als een array (Array) met de nummers (Number) van de gevulde gaten. Daarbij maakt het niet uit in welke volgorde de nummers van de gevulde gaten opgelijst worden. Als in bovenstaande figuur de vier oranje gaten met reageerbuizen gevuld zijn en de twee donkergrijze gaten leeg zijn, dan kunnen we die configuratie bijvoorbeeld voorstellen als de array [4, 1, 3, 0].

Een centrifuge kan in wijzerzin of in tegenwijzerzin roteren. Bij één rotatiestap schuiven alle gaten (en reageerbuizen) één nummer door in wijzerzin of in tegenwijzerzin, zodat er telkens een gat met middelpunt op de positieve X-as blijft liggen. Dit wordt geïllustreerd in onderstaande figuur, waarbij we alle gaten van de centrifuge gevuld hebben met reageerbuizen die elk een unieke kleur hebben.

rotatiestap
Een centrifuge kan in wijzerzin of in tegenwijzerzin roteren. Bij één rotatiestap schuiven alle gaten (en reageerbuizen) één nummer door in wijzerzin of in tegenwijzerzin, zodat er telkens een gat met middelpunt op de positieve X-as blijft liggen. Dit wordt geïllustreerd in deze figuur, waarbij we alle gaten van de centrifuge gevuld hebben met reageerbuizen die elk een unieke kleur hebben.

Bij het spiegelen van een centrifuge wordt de configuratie van haar reageerbuizen gespiegeld ten opzichte van de X-as. Als we een gespiegelde centrifuge nog eens spiegelen, dan krijgen we terug de oorspronkelijke configuratie van de centrifuge.

spiegelen
Bij het spiegelen van een centrifuge wordt haar configuratie gespiegeld ten opzichte van de X-as. Als we een gespiegelde centrifuge nog eens spiegelen, dan krijgen we terug de oorspronkelijke configuratie van de centrifuge.

Definieer een klasse Centrifuge waarmee centrifuges kunnen voorgesteld worden waarvan sommige gaten met reageerbuizen gevuld zijn. Bij het aanmaken van een centrifuge (Centrifuge) moeten twee argumenten doorgegeven worden: i) het aantal gaten $$n$$ (int) en ii) een configuratie die beschrijft welke gaten van de centrifuge gevuld zijn met reageerbuizen.

Op een centrifuge $$c$$ (Centrifuge) moeten minstens de volgende methoden kunnen aangeroepen worden:

Voorbeeld

> let centrifuge = new Centrifuge(6, [4, 1, 3, 0]);
> centrifuge.toString()
"Centrifuge(6, [0, 1, 3, 4])"
> centrifuge.roteer().toString()
"Centrifuge(6, [1, 2, 4, 5])"
> centrifuge.roteer(wijzerzin=true).toString()
"Centrifuge(6, [0, 1, 3, 4])"
> centrifuge.spiegel().toString()
"Centrifuge(6, [0, 2, 3, 5])"
> centrifuge.spiegel().toString()
"Centrifuge(6, [0, 1, 3, 4])"

> centrifuge = new Centrifuge(6, [2, 0, 5]);
> centrifuge.isGelijk(new Centrifuge(6, [2, 4, 5]))
true
> centrifuge.isGelijk(new Centrifuge(6, [3, 4, 5]))
false
> centrifuge.toString()
"Centrifuge(6, [0, 2, 5])"
> centrifuge.roteer().roteer().spiegel().toString()
"Centrifuge(6, [2, 4, 5])"
> centrifuge.spiegel().roteer(true).roteer(true).toString()
"Centrifuge(6, [0, 2, 5])"
> centrifuge.vul(new Centrifuge(6, [1, 4])).toString()
"Centrifuge(6, [0, 1, 2, 4, 5])"
> centrifuge.vul(new Centrifuge(6, [1, 4, 2])).toString()
AssertionError: gaten kunnen niet gevuld worden
> centrifuge.leeg(new Centrifuge(6, [1, 4])).toString()
"Centrifuge(6, [0, 2, 5])"
> centrifuge.leeg(new Centrifuge(6, [1, 5])).toString()
AssertionError: gaten kunnen niet geleegd worden