Browse Source

add most perfect magic square

hudriwudri-games 3 years ago
parent
commit
54f7c7d5a4
3 changed files with 265 additions and 50 deletions
  1. 127 49
      Main.c
  2. 1 1
      Makefile
  3. 137 0
      solutions.txt

+ 127 - 49
Main.c

@@ -2,42 +2,43 @@
 #include <stdlib.h>
 
 int size = 0;
-int* data = NULL;
+int *data = NULL;
 int (*fitness)() = NULL;
 
-void init() {
+void init()
+{
     int end = size * size;
     data = malloc(sizeof(int) * end);
-    for(int i = 0; i < end; i++) {
+    for (int i = 0; i < end; i++)
+    {
         data[i] = i + 1;
     }
 }
 
-int get(int x, int y) {
-    return data[y * size + x];
-}
+int get(int x, int y) { return data[y * size + x]; }
 
-int errorFactor(int e) {
-    return e * e;
-}
+int errorFactor(int e) { return e * e; }
 
-int getWanted() {
-    return (size * (size * size + 1)) / 2;
-}
+int getWanted() { return (size * (size * size + 1)) / 2; }
 
-int getSemiFitness() {
+int getSemiFitness()
+{
     int fitness = 0;
     int wanted = getWanted();
-    for(int y = 0; y < size; y++) {
+    for (int y = 0; y < size; y++)
+    {
         int sum = 0;
-        for(int x = 0; x < size; x++) {
+        for (int x = 0; x < size; x++)
+        {
             sum += get(x, y);
         }
         fitness += errorFactor(sum - wanted);
     }
-    for(int x = 0; x < size; x++) {
+    for (int x = 0; x < size; x++)
+    {
         int sum = 0;
-        for(int y = 0; y < size; y++) {
+        for (int y = 0; y < size; y++)
+        {
             sum += get(x, y);
         }
         fitness += errorFactor(sum - wanted);
@@ -45,10 +46,12 @@ int getSemiFitness() {
     return fitness;
 }
 
-int getDiagonalBase() {
+int getDiagonalBase()
+{
     int diaA = 0;
     int diaB = 0;
-    for(int i = 0; i < size; i++) {
+    for (int i = 0; i < size; i++)
+    {
         diaA += get(i, i);
         diaB += get(i, (size - 1) - i);
     }
@@ -58,17 +61,18 @@ int getDiagonalBase() {
     return fitness;
 }
 
-int getNormalFitness() {
-    return getSemiFitness() + getDiagonalBase();
-}
+int getNormalFitness() { return getSemiFitness() + getDiagonalBase(); }
 
-int getPandiagonalBase() {
+int getPandiagonalBase()
+{
     int fitness = 0;
     int wanted = getWanted();
-    for(int x = 0; x < size; x++) {
+    for (int x = 0; x < size; x++)
+    {
         int sumA = 0;
         int sumB = 0;
-        for(int y = 0; y < size; y++) {
+        for (int y = 0; y < size; y++)
+        {
             sumA += get((x + y) % size, y);
             sumB += get((x - y + size) % size, y);
         }
@@ -78,11 +82,14 @@ int getPandiagonalBase() {
     return fitness;
 }
 
-int getAssociativeBase() {
+int getAssociativeBase()
+{
     int fitness = 0;
     int wanted = size * size + 1;
-    for(int x = 0; x < size; x++) {
-        for(int y = 0; y < size; y++) {
+    for (int x = 0; x < size; x++)
+    {
+        for (int y = 0; y < size; y++)
+        {
             int sum = get(x, y) + get(size - x - 1, size - y - 1);
             fitness += errorFactor(sum - wanted);
         }
@@ -90,14 +97,61 @@ int getAssociativeBase() {
     return fitness;
 }
 
-int getUltraFitness() {
+int getUltraFitness()
+{
     return getSemiFitness() + getPandiagonalBase() + getAssociativeBase();
 }
 
-void print() {
+int get2x2SquareBase()
+{
+    int fitness = 0;
+    int wanted = 2 * (size * size + 1);
+    for (int x = 0; x < size; x++)
+    {
+        for (int y = 0; y < size; y++)
+        {
+            if (x % 2 == 0 && y % 2 == 0)
+            {
+                int sum = get(x, y) + get(x + 1, y) + get(x, y + 1) +
+                          get(x + 1, y + 1);
+                fitness += errorFactor(sum - wanted);
+            }
+        }
+    }
+    return fitness;
+}
+int getPerfectDiagonalBase()
+{
+    int fitness = 0;
+    int wanted = size * size + 1;
+    for (int x = 0; x < size / 2; x++)
+    {
+        for (int y = 0; y < size; y++)
+        {
+            int sum =
+                get(x, y) + get((x + size / 2) % size, (y + size / 2) % size);
+            fitness += errorFactor(sum - wanted);
+        }
+    }
+    return fitness;
+}
+
+int getMostPerfectFitness()
+{
+    // printf("ultra: %d\n", getUltraFitness());
+    // printf("square: %d\n", get2x2SquareBase());
+    // printf("diagonal: %d\n", getPerfectDiagonalBase());
+    return getSemiFitness() + getPandiagonalBase() + get2x2SquareBase() +
+           getPerfectDiagonalBase();
+}
+
+void print()
+{
     printf("Fitness: %d\n", fitness());
-    for(int y = 0; y < size; y++) {
-        for(int x = 0; x < size; x++) {
+    for (int y = 0; y < size; y++)
+    {
+        for (int x = 0; x < size; x++)
+        {
             printf("%2d ", get(x, y));
         }
         putchar('\n');
@@ -105,23 +159,31 @@ void print() {
     putchar('\n');
 }
 
-void swap(int a, int b) {
+void swap(int a, int b)
+{
     int tmp = data[a];
     data[a] = data[b];
     data[b] = tmp;
 }
 
-void randSwaps(int swaps) {
-    for(int i = 0; i < swaps; i++) {
+void randSwaps(int swaps)
+{
+    for (int i = 0; i < swaps; i++)
+    {
         swap(rand() % (size * size), rand() % (size * size));
     }
 }
 
-int main(int argAmount, char** args) {
-    if(argAmount < 5) {
-        if(argAmount <= 0) {
+int main(int argAmount, char **args)
+{
+    if (argAmount < 5)
+    {
+        if (argAmount <= 0)
+        {
             printf("... <type> <size> <tries> <generations>\n");
-        } else {
+        }
+        else
+        {
             printf("%s <type> <size> <tries> <generations>\n", args[0]);
         }
         return 0;
@@ -131,15 +193,27 @@ int main(int argAmount, char** args) {
     int tries = atoi(args[3]);
     int generations = atoi(args[4]);
 
-    switch(type) {
-        case 1: fitness = getNormalFitness; break;
-        case 2: fitness = getUltraFitness; break;
-        default: puts("unknown type"); return 0;
+    switch (type)
+    {
+    case 1:
+        fitness = getNormalFitness;
+        break;
+    case 2:
+        fitness = getUltraFitness;
+        break;
+    case 3:
+        fitness = getMostPerfectFitness;
+        break;
+    default:
+        puts("unknown type");
+        return 0;
     }
 
     init();
-    for(int k = 0; k < tries; k++) {
-        for(int i = 0; i < generations; i++) {
+    for (int k = 0; k < tries; k++)
+    {
+        for (int i = 0; i < generations; i++)
+        {
             int oldFitness = fitness();
 
             int a = rand() % (size * size);
@@ -147,18 +221,22 @@ int main(int argAmount, char** args) {
             swap(a, b);
 
             int newFitness = fitness();
-            if(newFitness == 0) {
+            if (newFitness == 0)
+            {
                 break;
             }
 
-            if(newFitness >= oldFitness) {
+            if (newFitness >= oldFitness)
+            {
                 swap(a, b);
             }
         }
-        if(fitness() == 0) {
+        // if (fitness() < 50)
+        if (fitness() == 0)
+        {
             print();
         }
-        randSwaps(400);
+        randSwaps(100);
     }
     free(data);
     return 0;

+ 1 - 1
Makefile

@@ -1,5 +1,5 @@
 run: build
-	./magic 2 5 50 200000
+	./magic 2 9 500000 1000000
 
 build: Main.c 
 	gcc -o magic Main.c -Wall -Wextra -pedantic -Werror -O3

+ 137 - 0
solutions.txt

@@ -0,0 +1,137 @@
+
+9x9 - Simple Magic Square
+Fitness: 0
+61 14 35 71  1 25  7 74 81 
+36 24 27 38 65 59 29 12 79 
+ 3 51 45 41  2 66 69 19 73 
+54 75 63 20 76 15 16 40 10 
+37 43 17 52 53 77 33 31 26 
+49 11 68  4 67  6 70 48 46 
+56 32 44 30 42 78 60  9 18 
+39 57 23 55 13 22 80 72  8 
+34 62 47 58 50 21  5 64 28 
+
+Fitness: 0
+70 21 57 63 18 16 79 23 22 
+17 12  3 53 52 65 67 44 56 
+10 80 72 32 38 58 66  7  6 
+74  2 11 31 27 73 50 68 33 
+42 60 41 75  8 15 14 36 78 
+55 64 71  5 49 26 39  9 51 
+69 13 46 54 35 34 29 59 30 
+ 4 77 43 19 81 20  1 76 48 
+28 40 25 37 61 62 24 47 45 
+
+Fitness: 0
+76 70 11 25 21 49 62 31 24 
+44 23 63 81  6 22 41 18 71 
+12 67 59 16 69 30 75  9 32 
+10 68 38 57  8 52 37 65 34 
+60 15 43 78 54 55  4 20 40 
+77 35 27 17 47  5 42 46 73 
+ 7 61 36 53 51 28 45 74 14 
+19 29 26  3 80 72 13 48 79 
+64  1 66 39 33 56 50 58  2 
+
+Fitness: 0
+35 70  9 33  8 79 76 21 38 
+61  1 49 14 69 13 36 68 58 
+46 10 59 80 48 23 18 22 63 
+60 67  7 28 30 37 72 43 25 
+47 31 32 75 74 56  6 44  4 
+52 50 73 16 45 57 55  2 19 
+29 65 42 78  3 24 15 62 51 
+27 64 17  5 39 54 20 66 77 
+12 11 81 40 53 26 71 41 34 
+
+Fitness: 0
+72 58 56 74 53 14 15 17 10 
+52 70 65 27  2  4 19 79 51 
+43 80  1 42 28 61 41 48 25 
+34 33 37  8 32 54 64 67 40 
+75  5 45 63 39 21 71 12 38 
+ 6 77 66 62 24 35 23 29 47 
+49 36 57 11 50 76 59  9 22 
+18  7 16 69 73 44 31 30 81 
+20  3 26 13 68 60 46 78 55 
+
+Fitness: 0
+25 35 39 53 79  9 62  7 60 
+13 51 58  2 72 54  1 69 49 
+81 11 16 37 67 18 36 38 65 
+41 73 64 80  4 48 22 23 14 
+15 61 75  3  6 68 66 31 44 
+52 46 19 59 33 50 63 26 21 
+78  8 10 56 29 70 47 43 28 
+40 57 12  5 45 20 42 77 71 
+24 27 76 74 34 32 30 55 17 
+
+Fitness: 0
+42 57 34  2 77 66  3 17 71 
+23 69 64 41 70 30 52 15  5 
+73 79 65 46  4 11 12 39 40 
+63 16 55 14 24 67 13 72 45 
+78 22  8 51 26 32 48 76 28 
+44 36  9 75 53  6 59 37 50 
+27 29 31 47 33 61 81 35 25 
+ 1 54 60 74 62 38 21 10 49 
+18  7 43 19 20 58 80 68 56 
+
+
+9x9 - Ultra Magic Square
+
+
+
+8x8 - Most Perfect Magic Square
+
+Fitness: 0
+42 22 32 18 17 63 14 52 
+11 55 31 49 15 35 40 24 
+58  6 26 19 64  5 20 62 
+38 28 29 56 53  8 44  4 
+48  2 51 13 23 43 33 47 
+50 30 25 41 54 10 34 16 
+ 1 60 45  3  7 59 39 46 
+12 57 21 61 27 37 36  9 
+
+Fitness: 0
+18 44 63 41  3 10 32 49 
+ 7 61 11 15 60 57 40  9 
+31 22 42 28 19 59 30 29 
+64 13 12 48 38 14 26 45 
+62 55 33 16 47 21  2 24 
+ 5  8 25 56 58  4 54 50 
+46  6 35 36 34 43 23 37 
+27 51 39 20  1 52 53 17 
+
+Fitness: 0
+ 2 44 51 20  8 50 61 24 
+59 25 43 16 60 12 36  9 
+47 48 35 11 32 46 28 13 
+34  1 58 26 42 10 62 27 
+57 15  4 41 63 21 14 45 
+ 5 53 29 56  6 40 22 49 
+33 19 37 52 18 17 30 54 
+23 55  3 38 31 64  7 39 
+
+Fitness: 0
+6 64 13 46 40 61  2 28 
+39 21 35 36  5 24 47 53 
+23 11 57 48 31 49  9 32 
+51 45 15 10 43  7 62 27 
+25  4 63 37 59  1 52 19 
+60 41 18 12 26 44 30 29 
+34 16 56 33 42 54  8 17 
+22 58  3 38 14 20 50 55 
+
+Fitness: 0
+28 23 15 60 51 35 36 12 
+17 62 49  6  1 43 38 44 
+54 26 25  7 57 10 20 61 
+41  9 52 46 31 32 47  2 
+14 30 29 53 37 42 50  5 
+64 22 27 21 48  3 16 59 
+ 8 55 45  4 11 39 40 58 
+34 33 18 63 24 56 13 19 
+
+