Setting aside some frustrating negative aspects, the recent discussion about a 4 x4 magic square captured my interest. Lengthy browsing got me to this site.
https://www.hackster.io/Klausj/r3-r4-compare-using-magic-square-6d7e7f
Did a bit of Google Translate work so that I had some faint idea what his/her code was doing. But as I dont have a 1.8" TFT or anything similar the hard part was getting it to deliver printed output instead. A few sessions with AI and I finally had a working sketch.
There are actually 880 solutions. But I asked it to include mirroring and rotation for the hell of it, which delivered the full 7040, in about 16 mins. About 42,000 lines so won't attempt to paste it. If anyone wants it pleased PM me with an email address.
Working sketch below:
const byte cols = 4;
const byte maxi = cols * cols;
const byte sum = (maxi + 1) * maxi / 2 / cols;
byte p[maxi]; // Holds the current square
const byte seq[] = {
0, 1, 2, 3,
4, 5, 6, 7,
8, 10, 12, 13,
9, 11, 14, 15
};
int count = 0;
unsigned long startTime;
void setup() {
Serial.begin(115200);
delay(1000); // Give serial monitor time to connect
Serial.println(F("Generating 4x4 magic squares...\n"));
startTime = millis();
place(0, 0xFFFF);
Serial.print(F("\nDone. Total solutions: "));
Serial.println(count);
}
void loop() {}
void place(byte pos, int avail) {
byte i;
switch (pos) {
case 0: case 1: case 2: case 4: case 5: case 6: case 8: case 10:
for (i = 1; i <= maxi; i++) Try(pos, i, avail); break;
case 3: i = rem3(0, 1, 2); Try(pos, i, avail); break;
case 7: i = rem3(4, 5, 6); Try(pos, i, avail); break;
case 9: i = rem3(0, 4, 8); Try(pos, i, avail); break;
case 11: i = rem3(1, 5, 10); Try(pos, i, avail); break;
case 12: i = rem3(5, 6, 10); Try(pos, i, avail); break;
case 13: i = rem3(8, 10, 12); Try(pos, i, avail); break;
case 14: i = rem3(2, 6, 12); Try(pos, i, avail); break;
case 15:
i = rem3(3, 7, 13);
Try(pos, i, avail);
break;
case 16:
if (rem3(0, 5, 12) == p[15]) {
count++;
unsigned long elapsed = (millis() - startTime) / 1000;
Serial.print(F("Solution #"));
Serial.print(count);
Serial.print(F(" ["));
Serial.print(elapsed);
Serial.println(F(" sec]:"));
printSquare();
delay(10); // optional: slow output if needed
}
}
}
void Try(byte pos, byte value, int avail) {
if ((value < 1) || (value > maxi)) return;
int mask = 1 << (value - 1);
if (avail & mask) {
p[pos] = value;
place(pos + 1, avail & ~mask);
p[pos] = 0;
}
}
byte rem3(byte a, byte b, byte c) {
return sum - p[a] - p[b] - p[c];
}
void printSquare() {
for (byte i = 0; i < 16; i++) {
Serial.print(p[i] < 10 ? " " : "");
Serial.print(p[i]);
Serial.print(" ");
if ((i + 1) % 4 == 0) Serial.println();
}
Serial.println();
}