Тема: Магічні квадрати

Магічний квадрат NxN це 2 вимірний масив цілих чисел, де

  • кожний елемент квадрата унікальний

  • кожний ряд містить N цілих чисел, сума яких = S

  • кожна колона містить N цілих чисел, сума яких = S

  • для кожної з кутових діагоналів, сума чисел діагоналі = S

де S ціле число.

Як майстер магічних мистецтв магістр математичних наук, ділюсь знанями які майже забув і не давно згадав.

3x3

Python 3:

def A_f(x, y): return 1 - (1 - x + y) % 3
def B_f(x, y): return 1 - (x - 1 + y) % 3

def magic_square_f(w, h, v, l):
    return [
        [   + A_f(x, y) * v[0]
            + B_f(x, y) * v[1]
            + l
            for x in range(w)
        ]   for y in range(h)
    ]

for a in [+1, -1]:
    for b in [+3, -3]:
        for v in [[a, b], [b, a]]:
            print(magic_square_f(3, 3, v, +5))
Прихований текст


[[2, 9, 4], [7, 5, 3], [6, 1, 8]]
[[4, 9, 2], [3, 5, 7], [8, 1, 6]]
[[8, 3, 4], [1, 5, 9], [6, 7, 2]]
[[4, 3, 8], [9, 5, 1], [2, 7, 6]]
[[2, 7, 6], [9, 5, 1], [4, 3, 8]]
[[6, 7, 2], [1, 5, 9], [8, 3, 4]]
[[8, 1, 6], [3, 5, 7], [4, 9, 2]]
[[6, 1, 8], [7, 5, 3], [2, 9, 4]]

JavaScript:

const mod = (x, m) => (x % m + m) % m;
const A_f = (x, y) => 1 - mod(1 - x + y, 3);
const B_f = (x, y) => 1 - mod(x - 1 + y, 3);
let n = 0;
const magic_square_log = (w, h, v, l) => {
    let s = 'Magic #' + ++n;
    for(let y = 0; y < h; ++y) {
        s += "\r\n";
        for(let x = 0; x < w; ++x) {
            let value = l;
            value += A_f(x, y) * v[0];
            value += B_f(x, y) * v[1];
            s += x === 0 ? "\t" : ' ';
            s += value;
        }
    }
    console.log(s);
}
for(let a of [+1, -1])
    for(let b of [+3, -3])
        for(let v of [[a, b], [b, a]])
            magic_square_log(3, 3, v, +5);

2

Re: Магічні квадрати

Подіагональний (pandiagonal) магічний квадрат має додаткові властивості

  • для кожної діагоналі, сума чисел = S

https://upload.wikimedia.org/wikipedia/commons/thumb/f/f6/4x4_magic_square_hierarchy.svg/200px-4x4_magic_square_hierarchy.svg.png

4x4

Для 4x4 кожний подіагональний є досконалий (most-perfect).

Python 3:

def  B_f(x, y): return x >> 1 & 1 ^ y & 1
def  A_f(x, y): return B_f(x + 1, y)
def AT_f(x, y): return A_f(y, x)
def BT_f(x, y): return B_f(y, x)

def magic_square_4x4_f(v, l, x0, y0, w = 4, h = 4):
    return [
        [   +  A_f(x - x0, y - y0) * v[0]
            +  B_f(x - x0, y - y0) * v[1]
            + AT_f(x - x0, y - y0) * v[2]
            + BT_f(x - x0, y - y0) * v[3]
            + l
            for x in range(w)
        ]   for y in range(h)
    ]

from itertools import permutations

def print_all_4x4(x0, y0):
    for v in permutations({ 1, 2, 4, 8 }):
        print(magic_square_4x4_f(v, +1, x0, y0))

# print_all_4x4(0, 0)    # 24/384

for y in range(4):
    for x in range(4):
        print_all_4x4(x, y)    # 24 * 4 * 4 = 384 magic squares
Прихований текст


[[1, 15, 10, 8], [12, 6, 3, 13], [7, 9, 16, 2], [14, 4, 5, 11]]
[[1, 15, 10, 8], [14, 4, 5, 11], [7, 9, 16, 2], [12, 6, 3, 13]]
[[1, 14, 11, 8], [12, 7, 2, 13], [6, 9, 16, 3], [15, 4, 5, 10]]
[[1, 14, 11, 8], [15, 4, 5, 10], [6, 9, 16, 3], [12, 7, 2, 13]]
...
[[4, 9, 7, 14], [5, 16, 2, 11], [10, 3, 13, 8], [15, 6, 12, 1]]
[[10, 3, 13, 8], [5, 16, 2, 11], [4, 9, 7, 14], [15, 6, 12, 1]]
[[4, 9, 6, 15], [5, 16, 3, 10], [11, 2, 13, 8], [14, 7, 12, 1]]
[[11, 2, 13, 8], [5, 16, 3, 10], [4, 9, 6, 15], [14, 7, 12, 1]]

JavaScript:

const  B_f = (x, y) => x >> 1 & 1 ^ y & 1;
const  A_f = (x, y) => B_f(x + 1, y);
const AT_f = (x, y) => A_f(y, x);
const BT_f = (x, y) => B_f(y, x);
let n = 0;
const magic_square_log = (v, l, x0, y0, w = 4, h = 4) => {
    let s = 'Magic#' + ++n;
    for(let y = 0; y < h; ++y) {
        s += "\r\n";
        for(let x = 0; x < w; ++x) {
            let value = l;
            value +=  A_f(x - x0, y - y0) * v[0];
            value +=  B_f(x - x0, y - y0) * v[1];
            value += AT_f(x - x0, y - y0) * v[2];
            value += BT_f(x - x0, y - y0) * v[3];
            s += x === 0 ? "\t" : ' ';
            s += ' '.repeat(2 - ('' + value).length);
            s += value;
        }
    }
    console.log(s);
};
const all_squares_log = (x0, y0) => {
    let v = [1, 2, 4, 8];
    for(let a of v)
    for(let b of v.filter(x => x != a))
    for(let c of v.filter(x => x != a && x != b))
    for(let d of v.filter(x => x != a && x != b && x != c))
        magic_square_log([a, b, c, d], +1, x0, y0);
}
for(let y = 0; y < 4; ++y)
    for(let x = 0; x < 4; ++x)
        all_squares_log(x, y);    // 24 * 4 * 4 = 384 magic squares