• Nem Talált Eredményt

forráskód. Törtátlókban található összegek képzése és összehasonlítása

Hernyák Zoltán)

13. fejezet - A mágikus és bűvös négyzetek (szerző: Hernyák Zoltán)

13.11. forráskód. Törtátlókban található összegek képzése és összehasonlítása

static void panmagikus_kiir_A(int[,] m) {

int N = m.GetLength(0);

ConsoleColor[] color = new ConsoleColor[] { ConsoleColor.Red, ConsoleColor.Green, ConsoleColor.Yellow, ConsoleColor.Cyan, ConsoleColor.White, ConsoleColor.Magenta };

static void panmagikus_kiir_A(int[,] m) {

int N = m.GetLength(0);

ConsoleColor[] color = new ConsoleColor[] { ConsoleColor.Red, ConsoleColor.Green, ConsoleColor.Yellow, ConsoleColor.Cyan, ConsoleColor.White, ConsoleColor.Magenta }; hogy ezenfelül szükséges még a sorok és az oszlopok összegeinek ellenőrzése is (valamint a sorok és oszlopok összegeinek is egyezniük kell a törtátlók összegeivel)!

13.11. forráskód. Törtátlókban található összegek képzése és összehasonlítása

static bool panmagikus_ell(int[,] m) {

int N = m.GetLength(0);

int[] sum1 = new int[N];

int[] sum2 = new int[N];

//

int i1, i2;

for (int i = 0; i < N; i++) {

i1 = i;

i2 = N - i - 1;

for (int j = 0; j < N; j++) {

sum1[i1] = sum1[i1] + m[i, j];

sum2[i2] = sum2[i2] + m[i, j];

i1++;

if (i1>= N) i1= 0;

i2++;

if (i2 >= N) i2 = 0;

} } //

for (int i = 1; i < N; i++) if (sum1[i] != sum1[0]) return false;

for (int i = 1; i < N; i++) if (sum2[i] != sum2[0]) return false;

if (sum1[0] != sum2[0]) return false;

// minden ok return true;

}

Bevezető információk: Az ördögkeretek4 olyan (nagyobb méretű) mágikus négyzetek, melyek külső keretét eltávolítva szintén mágikus négyzetet kapunk – tehát mágikus négyzetek vannak egymásba ágyazva.

Értelemszerűen ezen kisebb méretű mágikus négyzet kulcsértéke is kisebb, mivel a keretet alkotó értékek már nem szerepelnek a sorok és oszlopok összegszámításában. Érdekesebb esetben ez az egymásba ágyazás több szinten is előfordulhat, mígnem egy olyan belső mátrixhoz jutunk el, amire már nem teljesül, hogy ő is egy önálló mágikus négyzet. A 13.6. ábrán egy 12-ed rendű ördögkeret látható.

13.6. ábra. 12-ed rendű ördögkeret

13.5. feladat (Ördögkeretek – szint: 4). Írjunk olyan programot, amely beolvas egy fájlból egy méretű mátrixot, és meghatározza, hogy milyen mélységben tartalmaz mágikus négyzeteket egymásba ágyazva! Ha ez a szám 0, akkor már a kiinduló mátrix sem volt mágikus négyzet.

4angolul néha Border Square-nek nevezik

Magyarázat: Ehhez 13.2 feladatban leírt mágikus négyzet ellenőrzése módszert kell kiterjeszteni, hogy ne a teljes mátrixra, csak annak egy részére terjedjen ki az ellenőrzés. Ez a módosítás nemcsak a fő ellenőrző függvényt (buvos_negyzet_e) érinti, hanem a belőle hívott segédfüggvényeket is.

13.12. forráskód. Bűvös négyzet – „buvos_negyzet_e_2”

static bool magikus_negyzet_e_2(int[,] m,int eltolas) {

int N = m.GetLength(0) - 2 * eltolas;

int[] sorok = new int[N];

int[] oszlopok = new int[N];

osszegekGen2(m, sorok, oszlopok, eltolas);

// sorok, oszlopok osszegei

if (mindEgyenlo(sorok) == false ||

mindEgyenlo(oszlopok) == false ||

sorok[0] != oszlopok[0]) return false;

// atlok osszegei int atlo1, atlo2;

atlokGen2(m, out atlo1, out atlo2,eltolas);

if (atlo1 != atlo2 || atlo1 != sorok[0]) return false;

// egyediseg

for (int i = 0; i < N; i++) for (int j = 0; j < N; j++)

if (megszamol2(m, m[i, j],eltolas) != 1) return false;

// minden rendben return true;

}

13.13. forráskód. Bűvös négyzet – „osszegekGen2”

static void osszegekGen2(int[,] m,int[] sorok,int[] oszlopok,int eltolas) {

for (int i = 0; i < sorok.Length; i++) for (int j = 0; j < oszlopok.Length; j++) {

sorok[i] = sorok[i] + m[i + eltolas, j + eltolas];

oszlopok[j] = oszlopok[j] + m[i + eltolas, j + eltolas];

} }

13.14. forráskód. Bűvös négyzet – „mindEgyenlo”

static bool mindEgyenlo(int[] l) {

int x = l[0];

foreach (int a in l)

if (x != a) return false;

return true;

}

13.15. forráskód. Bűvös négyzet – „atlokGen2”

static void atlokGen2(int[,] m, out int a, out int b, int eltolas) {

a = 0; b = 0;

int N = m.GetLength(0);

for (int i = 0; i < N; i++) {

a = a + m[i + eltolas, i + eltolas];

b = b + m[i + eltolas, N - i - 1 - +eltolas];

} }

13.16. forráskód. Bűvös négyzet – „megszamol2”

static int megszamol2(int[,] m, int x, int eltolas) {

int N = m.GetLength(0)-eltolas;

int db = 0;

for (int i = 0; i < N; i++) for (int j = 0; j < N; j++)

if (m[i+eltolas, j+eltolas] == x) db++;

return db;

}

Bevezető információk: Az olyan méretű mátrixok, amelyekben minden szám szerepel

intervallumból, s melyeknél a sorok, az oszlopok és az átlókban szereplő összegek különbözőek: antimágikus négyzetnek nevezzük. Bizonyítható, hogy nem létezik , , méretű anti mágikus négyzet.

13.6. feladat (Antimágikus négyzet ellenőrzése – szint: 2). Egy méretű kitöltött mátrixot ellenőrizzünk le, hogy antimágikus négyzet-e! Az ellenőrzés után jelenítsük meg a mátrixot a képernyőn, minden sorhoz és oszlophoz jelenítsük meg az összegeket, a főátló és a mellékátló összegét is! Az ellenőrzés eredményét írjuk vörös színnel, ha nem felelt meg, és zölddel, ha megfelelt!

Magyarázat: A főprogramban (a 13.57. forráskód) a mátrixot az alapadatokal történő feltöltés után megjelenítjük a képernyőn. A 13.59. forráskódban egy intelligens megjelenítő függvényt készítettünk, amely maga számolja ki a sor- és oszlopösszegeket, valamint az átlók összegét (semmit sem bízván a véletlenre). A sorok összegét kiírás közben számolja a sum változóba, és minden sor kiírásának végén azt meg is jeleníti. Az oszlopösszegeket a oszlopok vektorban számolja, mert az csak a legalsó sor kiírása után lesz látható. A főátlóbeli összeget a jobb sarokban jeleníti meg, a foatlo változó alapján. A mellékátló összegét az alsó sorban, az oszlopátlók előtt írja ki. A vizsgálatot a 13.58. forráskódban szereplő anti_buvos_negyzet_e függvény végzi.

A sorok összege N, az oszlopok összege is N, a főátlóbeli és a mellékátlóbeli elemek összege 2 darab szám, így összesen 2 * N + 2 összeget kell kiszámítani, ezért készül az osszegek vektor ezzel a mérettel el. Az első N elemében szerepelnek majd a sorok összegei, a további N elemében az oszlopok, az utolsó előtti a főátló, az utolsó a mellékátló összege. A vektor feltöltése után ellenőrizzük, hogy van-e az összegek között két egyforma.

Ha idáig minden rendben, akkor még azt is ellenőrizni kell, hogy minden szám szerepel-e az intervallumból, mindegyik pontosan egyszer.

13.7. ábra. A program outputja

13.17. forráskód. Anti bűvös négyzet-e – teszt főprogram

static void Main() {

const int N = 5;

int[,] m = new int[N, N];

Console.SetCursorPosition(0, N + 2);

if (anti_magikus_negyzet_e(m) == false) {

Console.ForegroundColor = ConsoleColor.Red;

Console.WriteLine("NEM ANTI-MAGIKUS NEGYZET");

} else {

Console.ForegroundColor = ConsoleColor.Green;

Console.WriteLine("IGENIS ANTI-MAGIKUS NEGYZET");

}

Console.ReadLine();

}

13.18. forráskód. Anti bűvös négyzet-e – az ellenőrző függvény

13.19. forráskód. Anti bűvös négyzet-e – mátrix megjelenítés

static void Magikus_Kiiras(int[,] m) {

int N = m.GetLength(0);

int[] oszlopok = new int[N];

int foatlo = 0;

int mellekatlo = 0;

//

//

for (int i = 0; i < N; i++) {

Console.ForegroundColor = ConsoleColor.Yellow;

int sum = 0;

Console.Write(" ");

for (int j = 0; j < N; j++) {

Console.Write("{0,3} ", m[i, j]);

//

sum = sum + m[i, j];

oszlopok[j] = oszlopok[j] +m[i, j];

if (i==j) foatlo=foatlo+m[i,j];

if (i == N - j - 1)

mellekatlo = mellekatlo + m[i, j];

} //

Console.ForegroundColor = ConsoleColor.Cyan;

Console.Write("{0,4} ", sum);

Console.WriteLine();

} //

Console.ForegroundColor = ConsoleColor.Green;

Console.Write("{0,3} ", mellekatlo);

Console.ForegroundColor = ConsoleColor.Cyan;

for (int j = 0; j < N; j++)

Console.Write("{0,3} ", oszlopok[j]);

Console.ForegroundColor = ConsoleColor.Green;

Console.Write("{0,3} ", foatlo);

Console.ForegroundColor = ConsoleColor.Gray;

}

13.7. feladat (Antimágikus négyzet generálása – szint: 2). Generáljunk egy méretű mátrixot oly módon, hogy a végeredménye antimágikus négyzet legyen!

Magyarázat: A generálás során először feltöltjük a mátrixot módszeresen közötti értékekkel. Majd kiszámítjuk a sorok, oszlopok, átlók összegeit az előző feladatban ismertetett módon egy 2 * N + 2 méretű vektorba. Megkeressük, melyik két összeg egyenlő egymással. Ha nincs egyenlőség, akkor készen vagyunk. Ha találunk egyenlőséget, akkor választunk egy cellát a problémás sorból/oszlopból/átlóból, valamint egy véletlen cellát a mátrix tetszőleges helyéről. A két cellában lévő értéket felcseréljük.

Ezt addig ismételjük, amíg már nem lesz egyenlőség sehol. A mátrix megjelenítésén is finomítottunk: amelyik két összeg egyenlő egymással, azokat piros színnel jelenítjük meg. Valamint kiírásra kerül az is, hogy hány cserét kellett elvégezni, hogy a kívánt eredményt elérjük. Ez általában kevés csere, mivel a mátrix kezdeti feltöltése majdnem megfelelő. Ezért azzal bonyolítottuk a megoldást, hogy a kezdeti feltöltés után sok cserét hajtottunk végre a mátrix cellái között, hogy egy összekevert kezdő állapotot elérjünk. A mátrix ezen állapota is elég kedvező az antimágikus négyzet kiindulási állapotához, mert ezek után sincs szükség sok cserére. Úgy tűnik, ilyen négyzetek előállítása könnyű. A 13.60. ... 13.65. közötti forráskódok fedik le a megoldást.

13.8. ábra. A program outputja