Een magisch vierkant of een tovervierkant is een vierkant $$n \times n$$ rooster dat gevuld wordt met $$n^2$$ verschillende natuurlijke getallen (elk getal komt slechts één keer voor), zodat de $$n$$ rijen, de $$n$$ kolommen en beide diagonalen allemaal dezelfde som opleveren. Het getal $$n$$ wordt de orde van het vierkant genoemd. De unieke som wordt de magische constante of het karakteristieke getal van het vierkant genoemd. Hieronder zie je bijvoorbeeld een magisch vierkant van orde 4 met magische constante 34.
16 | 3 | 2 | 13 |
5 | 10 | 11 | 8 |
9 | 6 | 7 | 12 |
4 | 15 | 14 | 1 |
Dit bekend magisch vierkant komt voor op de gravure Melencolia I (melancholie) van Albrecht Dürer uit 1514. Merk op dat het jaartal van de gravure verwerkt zit in de onderste rij van het vierkant. Dit magische vierkant is niet alleen opmerkelijk omdat alle rijen, kolommen en diagonalen dezelfde som 34 hebben, maar onder meer ook de vier hoekpunten, de vier middelste getallen, de $$2 \times 2$$ getallen in de linkerbovenhoek, rechterbovenhoek, linkerbenedenhoek en rechterbenedenhoek, en de twee middelste getallen in de eerste en laatste kolom, respectievelijk de bovensten en onderste rij.
Een heterovierkant is een vierkant $$n \times n$$ rooster dat opgevuld wordt met $$n^2$$ verschillende natuurlijke getallen, zodat de $$n$$ rijen, de $$n$$ kolommen en beide diagonalen allemaal een verschillende som opleveren. Hieronder zie je bijvoorbeeld een heterovierkant van orde 4.
2 | 1 | 3 | 4 |
5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 |
Een antimagisch vierkant is een heterovierkant waarvan de sommen van de rijen, de kolommen en beide diagonalen een opeenvolgende reeks natuurlijke getallen vormen (als ze eerst in stijgende volgorde gesorteerd worden). Hieronder zie je bijvoorbeeld een antimagisch vierkant van orde 4.
2 | 15 | 5 | 13 |
16 | 3 | 7 | 12 |
9 | 8 | 14 | 1 |
6 | 4 | 11 | 10 |
We stellen een vierkant $$n \times n$$ rooster voor als een reeks (list of tuple) van $$n$$ elementen, die de $$n$$ rijen van het rooster voorstellen (opgelijst van boven naar onder). Elke rij wordt op haar beurt voorgesteld als een reeks (list of tuple) van $$n$$ natuurlijke getallen (int), die de opeenvolgende getallen op de rij voorstellen (opgelijst van links naar rechts).
Gevraagd wordt om vijf functies te schrijven, waaraan telkens een vierkant $$n \times n$$ rooster moet doorgegeven worden:
Een functie getallen die een verzameling (set) teruggeeft met de getallen (int) die in het gegeven rooster voorkomen.
Een functie sommen die een verzameling (set) teruggeeft met de sommen (int) van alle rijen, kolommen en diagonalen van het gegeven rooster.
Een functie ismagisch die een Booleaanse waarde (bool) teruggeeft, die aangeeft of het gegeven rooster een magisch vierkant is.
Een functie ishetero die een Booleaanse waarde (bool) teruggeeft, die aangeeft of het gegeven rooster een heterovierkant is.
Een functie isantimagisch die een Booleaanse waarde (bool) teruggeeft, die aangeeft of het gegeven rooster een antimagisch vierkant is.
>>> sommen([[2, 7, 6], [9, 5, 1], [4, 3, 8]])
{15}
>>> sommen([[2, 1, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12], [13, 14, 15, 16]])
{34, 35, 36, 40, 10, 42, 26, 58, 29, 31}
>>> sommen([[2, 15, 5, 13], [16, 3, 7, 12], [9, 8, 14, 1], [6, 4, 11, 10]])
{32, 33, 34, 35, 36, 37, 38, 29, 30, 31}
>>> getallen([[2, 7, 6], [9, 5, 1], [4, 3, 8]])
{1, 2, 3, 4, 5, 6, 7, 8, 9}
>>> getallen([[2, 1, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12], [13, 14, 15, 16]])
{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}
>>> getallen([[2, 15, 5, 13], [16, 3, 7, 12], [9, 8, 14, 1], [6, 4, 11, 10]])
{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}
>>> ismagisch([[2, 7, 6], [9, 5, 1], [4, 3, 8]])
True
>>> ismagisch([[2, 1, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12], [13, 14, 15, 16]])
False
>>> ismagisch([[2, 15, 5, 13], [16, 3, 7, 12], [9, 8, 14, 1], [6, 4, 11, 10]])
False
>>> ishetero([[2, 7, 6], [9, 5, 1], [4, 3, 8]])
False
>>> ishetero([[2, 1, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12], [13, 14, 15, 16]])
True
>>> ishetero([[2, 15, 5, 13], [16, 3, 7, 12], [9, 8, 14, 1], [6, 4, 11, 10]])
True
>>> isantimagisch([[2, 7, 6], [9, 5, 1], [4, 3, 8]])
False
>>> isantimagisch([[2, 1, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12], [13, 14, 15, 16]])
False
>>> isantimagisch([[2, 15, 5, 13], [16, 3, 7, 12], [9, 8, 14, 1], [6, 4, 11, 10]])
True