Welcome to collectivesolver - Programming & Software Q&A with code examples. A website with trusted programming answers. All programs are tested and work.

Contact: aviboots(AT)netvision.net.il

Semrush - keyword research tool

Turn ChatGPT, Claude, Gemini, And CoPilot Into Your Personal Assistant, Business Coach, Content Creator, And More

AFFILIATE MARKETING Your all-in-one performance engine Manage affiliates, creators, and customer referrals in one unified platform—turning every partnership into measurable growth
Secure & Reliable Web Hosting, Free Domain, Free SSL, 1-Click WordPress Install, Expert 24/7 Support

Boost your online presence with premium web hosting and servers

Disclosure: My content contains affiliate links.

42,596 questions

55,330 answers

573 users

How to generate a random 4×4 binary magic square (using only 0 and 1) in C

2 Answers

0 votes
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

/*
    ============================================================
    Generate a random 4×4 magic square containing only 0 and 1.

    A valid square must satisfy:
      • All rows sum to the same target value.
      • All columns sum to that same target value.
      • Both diagonals also match that target value.

    The algorithm:
      1. Precompute all 4‑bit binary rows.
      2. Group rows by their sum.
      3. Use backtracking with pruning to generate all magic squares.
      4. Select one at random.

    This avoids brute‑forcing all 2^16 grids and is efficient.
    ============================================================
*/

#define ROWS 16
#define SIZE 4

/* Generate all 4-bit binary rows */
void generate_binary_rows(int rows[ROWS][SIZE]) {
    for (int n = 0; n < ROWS; n++) {
        for (int i = 0; i < SIZE; i++)
            rows[n][SIZE - 1 - i] = (n >> i) & 1;
    }
}

/* Store all magic squares found */
typedef struct {
    int squares[500][SIZE][SIZE];
    int count;
} MagicList;

/* Backtracking search */
void search_magic(int target, int (*candidates)[SIZE], int cand_count,
                  MagicList *list, int square[SIZE][SIZE],
                  int col_sums[SIZE], int row_index) {

    if (row_index == SIZE) {
        /* Check diagonals */
        int main_diag = 0, anti_diag = 0;
        for (int i = 0; i < SIZE; i++) {
            main_diag += square[i][i];
            anti_diag += square[i][SIZE - 1 - i];
        }

        if (main_diag == target && anti_diag == target) {
            /* Save square */
            for (int r = 0; r < SIZE; r++)
                for (int c = 0; c < SIZE; c++)
                    list->squares[list->count][r][c] = square[r][c];

            list->count++;
        }
        return;
    }

    for (int i = 0; i < cand_count; i++) {
        int feasible = 1;

        /* Column pruning */
        for (int c = 0; c < SIZE; c++) {
            if (col_sums[c] + candidates[i][c] > target) {
                feasible = 0;
                break;
            }
        }
        if (!feasible) continue;

        /* Place row */
        for (int c = 0; c < SIZE; c++) {
            square[row_index][c] = candidates[i][c];
        }

        int old_cols[SIZE];
        for (int c = 0; c < SIZE; c++) {
            old_cols[c] = col_sums[c];
            col_sums[c] += candidates[i][c];
        }

        search_magic(target, candidates, cand_count, list, square, col_sums, row_index + 1);

        /* Undo */
        for (int c = 0; c < SIZE; c++)
            col_sums[c] = old_cols[c];
    }
}

/* Generate all magic squares */
MagicList generate_all_magic_squares() {
    MagicList list = { .count = 0 };

    int rows[ROWS][SIZE];
    generate_binary_rows(rows);

    /* Group rows by sum */
    int grouped[5][ROWS][SIZE];
    int group_count[5] = {0};

    for (int i = 0; i < ROWS; i++) {
        int sum = rows[i][0] + rows[i][1] + rows[i][2] + rows[i][3];
        int idx = group_count[sum]++;
        for (int j = 0; j < SIZE; j++)
            grouped[sum][idx][j] = rows[i][j];
    }

    /* Try all target sums */
    for (int target = 0; target <= 4; target++) {
        int square[SIZE][SIZE];
        int col_sums[SIZE] = {0};

        search_magic(target, grouped[target], group_count[target],
                     &list, square, col_sums, 0);
    }

    return list;
}

int main() {
    srand((unsigned)time(NULL));

    MagicList list = generate_all_magic_squares();

    if (list.count == 0) {
        printf("No magic squares found.\n");
        return 0;
    }

    /* Pick one at random */
    int idx = rand() % list.count;

    printf("Random 4×4 binary magic square:\n");
    for (int r = 0; r < SIZE; r++) {
        for (int c = 0; c < SIZE; c++)
            printf("%d ", list.squares[idx][r][c]);
        printf("\n");
    }

    return 0;
}


/*
run:

Random 4×4 binary magic square:
0 1 0 1 
0 1 0 1 
1 0 1 0 
1 0 1 0 

*/

 



answered 2 days ago by avibootz
0 votes
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

/*
    ============================================================
    Generate a random 4×4 binary magic square (0/1 only).

    A valid square must satisfy:
      • All rows have the same sum.
      • All columns have the same sum.
      • Both diagonals have that same sum.

    This program:
      1. Represents each 4×4 grid as a 16‑bit integer.
      2. Converts each mask into a 4×4 square.
      3. Checks whether it is magic.
      4. Collects all valid squares.
      5. Chooses one uniformly at random.
    ============================================================
*/

typedef int Square[16];   /* 16 cells, row‑major order */

/* Build a square from a 16‑bit mask */
void buildSquareFromMask(unsigned mask, Square sq) {
    for (int i = 0; i < 16; ++i)
        sq[i] = (mask >> i) & 1;
}

/* Check whether a square is magic */
int isMagic(const Square sq, int *magicSum) {
    int rowSum[4] = {0}, colSum[4] = {0};
    int mainDiag = 0, antiDiag = 0;

    for (int r = 0; r < 4; ++r) {
        for (int c = 0; c < 4; ++c) {
            int v = sq[r * 4 + c];
            rowSum[r] += v;
            colSum[c] += v;
            if (r == c)         mainDiag += v;
            if (r == 3 - c)     antiDiag += v;
        }
    }

    *magicSum = rowSum[0];

    for (int r = 0; r < 4; ++r)
        if (rowSum[r] != *magicSum) return 0;

    for (int c = 0; c < 4; ++c)
        if (colSum[c] != *magicSum) return 0;

    return (mainDiag == *magicSum && antiDiag == *magicSum);
}

/* Collect all magic squares */
int collectAllMagicSquares(Square *out) {
    int count = 0;

    for (unsigned mask = 0; mask < 65536u; ++mask) {
        Square sq;
        buildSquareFromMask(mask, sq);

        int sum;
        if (isMagic(sq, &sum)) {
            for (int i = 0; i < 16; ++i)
                out[count][i] = sq[i];
            count++;
        }
    }

    return count;
}

/* Print a square */
void printSquare(const Square sq) {
    int sum;
    isMagic(sq, &sum);

    for (int r = 0; r < 4; ++r) {
        for (int c = 0; c < 4; ++c)
            printf("%d ", sq[r * 4 + c]);
        printf("\n");
    }

    printf("Magic sum: %d\n", sum);
}

int main() {
    /* Collect all valid magic squares */
    Square all[4096];
    int count = collectAllMagicSquares(all);

    if (count == 0) {
        printf("No magic squares found.\n");
        return 1;
    }

    /* Choose one at random */
    srand((unsigned)time(NULL));
    int idx = rand() % count;

    printf("Found %d valid 4×4 binary magic squares.\n", count);
    printf("Randomly selected one:\n\n");

    printSquare(all[idx]);

    return 0;
}


/*
run:

Found 34 valid 4×4 binary magic squares.
Randomly selected one:

0 1 0 1 
0 1 0 1 
1 0 1 0 
1 0 1 0 
Magic sum: 2

*/

 



answered 1 day ago by avibootz

Related questions

...