1
$\begingroup$

How to create a magic square if we know a date. Eg-22-04-2014 The first column should have 22 2nd-04 3rd-20 and 4th -14. I believe ramanujan created the same thing for his birthday but I don't know the method he used. Please help. Is there any method to do it? I tried doing it using the fact that the row diagonal 2*2 square sum should all be equal to the total sum of the first row in this case 22+4+20+14=60

$\endgroup$
  • $\begingroup$ Please be more specific : Which entries should the magic square have beside the given ones ? $\endgroup$ – Peter Aug 13 '14 at 21:36
2
$\begingroup$

Let the magic square be $\begin{bmatrix}a & b & c & d \\ x_1 & x_2 & x_3 & x_4 \\ x_5 & x_6 & x_7 & x_8 \\ x_9 & x_{10} & x_{11} & x_{12}\end{bmatrix}$ where $a,b,c,d$ represents the date.

The conditions that the rows, columns, and diagonals sum to $a+b+c+d$ gives us $9$ linear equations for $12$ variables. The resulting system has rank $8$.

Therefore, any solution can be obtained by taking a particular solution and adding a linear combination of $12-8 = 4$ "basis vectors" for the nullspace of the system.

The matrix $\begin{bmatrix}a & b & c & d \\ c & d & a & b \\ d & c & b & a \\ b & a & d & c\end{bmatrix}$ is a magic square with the correct top row.

The following $4$ matrices form a basis of the nullspace of the system (all rows, cols, diags sum to $0$):

$\begin{bmatrix}0 & 0 & 0 & 0\\ 2 & -1 & -1 & 0 \\ -2 & 1 & 1 & 0 \\ 0 & 0 & 0 & 0\end{bmatrix}$, $\begin{bmatrix}0 & 0 & 0 & 0\\ 1 & 0 & 0 & -1 \\ -1 & 0 & 0 & 1 \\ 0 & 0 & 0 & 0\end{bmatrix}$, $\begin{bmatrix}0 & 0 & 0 & 0\\ 1 & 0 & -1 & 0 \\ -1 & 1 & 0 & 0 \\ 0 & -1 & 1 & 0\end{bmatrix}$, $\begin{bmatrix}0 & 0 & 0 & 0\\ 2 & -1 & 0 & -1 \\ -1 & 1 & 0 & 0 \\ -1 & 0 & 0 & 1\end{bmatrix}$.

Take the first matrix and add any linear combination of the above four matrices to get a solution.

$\endgroup$
  • $\begingroup$ I think there should not be any number repeated also. Please see the ramanujan birth date magic square. $\endgroup$ – Jai Mahajan Aug 14 '14 at 6:22
0
$\begingroup$

Here is a solution in Perl, which makes no claim to optimization but does produce results. The algorithm uses a mixing strategy to obtain balanced squares. For today the fourteenth of August 2014 we get the following squares (initial segment shown)

$ ./md-shuffle.pl 14-08-2014
56
014 008 020 014
022 023 006 005
008 024 003 021
012 001 027 016

014 008 020 014
022 023 005 006
001 018 010 027
019 007 021 009

014 008 020 014
022 023 005 006
007 024 004 021
013 001 027 015

014 008 020 014
022 023 003 008
005 024 006 021
015 001 027 013

For Xmas eve we obtain

$ ./md-shuffle.pl 24-12-2014
70
024 012 020 014
009 021 022 018
007 004 023 036
030 033 005 002

024 012 020 014
009 021 007 033
022 034 008 006
015 003 035 017

024 012 020 014
009 021 005 035
022 036 008 004
015 001 037 017

Euler's birthday was 15-04-1707:

$ ./md-shuffle.pl 15-04-1707
43
015 004 017 007
004 018 014 007
011 009 002 021
013 012 010 008

015 004 017 007
004 010 009 020
005 008 016 014
019 021 001 002

Gauss's birthday was 30-04-1777:

$ ./md-shuffle.pl 30-04-1777
128
030 004 017 077
089 014 013 012
007 036 065 020
002 074 033 019

030 004 017 077
089 014 013 012
008 037 064 019
001 073 034 020

030 004 017 077
089 014 013 012
003 032 069 024
006 078 029 015

This is the code which it may be a useful exercise to study and improve. As I mentioned it really does admit improvement in several spots but demonstrates proof of concept.

#! /usr/bin/perl -w
#

sub search {
    my ($sq, $sum, $sofar, $seen) = @_;

    if($sofar == 16){
        for(my $row=0; $row<4; $row++){
            for(my $col=0; $col<4; $col++){
                printf "%03d ", $sq->[$row][$col];
            }
            print "\n";
        }
        print "\n";

        return;
    }


    my $loc_col = $sofar % 4;
    my $loc_row = ($sofar - $loc_col) / 4;

    my $tries = [(1..$sum)];

    for(my $pos=$sum-1; $pos>=0; $pos--){
        my $targ = int rand($pos+1);

        my $tmp;
        $tmp = $tries->[$targ];
        $tries->[$targ] = $tries->[$pos];
        $tries->[$pos] = $tmp;
    }


    my $ind = 0;
    while($ind < scalar(@$tries)){
        my $nxt = $tries->[$ind];

        if(!exists($seen->{$nxt})){
            $seen->{$nxt} = 1;
            $sq->[$loc_row][$loc_col] = $nxt;

            my $no_admit = undef; my ($empty, $sval);

            for(my $row=0; $row<4; $row++){
                $empty = 0; $sval = 0;

                for(my $col=0; $col<4; $col++){
                    if($sq->[$row][$col] == -1){
                        $empty++;
                    }
                    else{
                        $sval += $sq->[$row][$col];
                    }
                }

                if(($empty == 0 && $sval != $sum) ||
                   ($empty > 0 && $sval >= $sum)){
                    $no_admit = 1;
                }
            }

            for(my $col=0; $col<4; $col++){
                $empty = 0; $sval = 0;

                for(my $row=0; $row<4; $row++){
                    if($sq->[$row][$col] == -1){
                        $empty++;
                    }
                    else{
                        $sval += $sq->[$row][$col];
                    }
                }

                if(($empty == 0 && $sval != $sum) ||
                   ($empty > 0 && $sval >= $sum)){
                    $no_admit = 1;
                }
            }

            $empty = 0; $sval = 0;

            for(my $diag=0; $diag<4; $diag++){
                if($sq->[$diag][$diag] == -1){
                    $empty++;
                }
                else{
                    $sval += $sq->[$diag][$diag];
                }
            }

            if(($empty == 0 && $sval != $sum) ||
               ($empty > 0 && $sval >= $sum)){
                $no_admit = 1;
            }


            $empty = 0; $sval = 0;

            for(my $diag=0; $diag<4; $diag++){
                if($sq->[$diag][3-$diag] == -1){
                    $empty++;
                }
                else{
                    $sval += $sq->[$diag][3-$diag];
                }
            }

            if(($empty == 0 && $sval != $sum) ||
               ($empty > 0 && $sval >= $sum)){
                $no_admit = 1;
            }


            if(!defined($no_admit)){
                search($sq, $sum, $sofar+1, $seen);
            }


            $sq->[$loc_row][$loc_col] = -1;
            delete $seen->{$nxt};
        }

        $ind++;
    }

}


MAIN: {
    my $date = shift || '31-12-2014';

    die "not a date" if
        $date !~ /^(\d\d)-(\d\d)-(\d\d)(\d\d)$/;

    my $first = [$1, $2, $3, $4];
    my $sum = $first->[0]+$first->[1]
        +$first->[2]+$first->[3];

    print "$sum\n";

    my $sq = []; push @$sq, $first;
    for(my $row=1; $row<4; $row++){
        push @$sq, [-1, -1, -1, -1];
    }

    my $seen = { 
        $first->[0] => 1, $first->[1] => 1,
        $first->[2] => 1, $first->[3] => 1
    };

    search($sq, $sum, 4, $seen);
}
$\endgroup$
  • $\begingroup$ I wanted it to be done physically as a sum and not by the computer but I am impressed. I guess we can do it in matlab also then. Ramanujan did not do it with the help of a computer. $\endgroup$ – Jai Mahajan Aug 14 '14 at 6:16

protected by Community Jan 25 '17 at 19:11

Thank you for your interest in this question. Because it has attracted low-quality or spam answers that had to be removed, posting an answer now requires 10 reputation on this site (the association bonus does not count).

Would you like to answer one of these unanswered questions instead?

Not the answer you're looking for? Browse other questions tagged or ask your own question.