Python Forum
How to eliminate magic squares formed by the same numbers, but permuted
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
How to eliminate magic squares formed by the same numbers, but permuted
#1
The magic squares that are formed with the first 9 numbers are:
[[6, 1, 8], [7, 5, 3], [2, 9, 4]]
[[2, 7, 6], [9, 5, 1], [4, 3, 8]] etc etc (8 magic squares with permutations)

I would like to eliminate the permutations, so that it is considered a single magic square, like this: [[6, 1, 8], [7, 5, 3], [2, 9, 4]]
It is very difficult to perform operations on memory data, that is, on the results of the processing.
I would like to work on the data in memory and make comparisons on fly
I'm asking how filter a single magic square, after the script has been processed
`
The code is:

from itertools import permutations
x=[1,2,3,4,5,6,7,8,9]
for a in permutations(x,9):
        if a[0]+a[1]+a[2]==15 and a[3]+a[4]+a[5]==15:
         if a[6]+a[7]+a[8]==15 and a[0]+a[3]+a[6]==15:
            if a[1]+a[4]+a[7]==15 and a[2]+a[5]+a[8]==15:
                if a[0]+a[4]+a[8]==15 and a[2]+a[4]+a[6]==15:
                    print(a[0:3])
                    print(a[3:6])
                    print(a[6:])
                    print()
Reply
#2
Maybe by creating 8 sets for each magic square, with each set being the triplets (row/column/diagonal)? And then you check to see if any of the sub-sets are different, to know if the overall square is different?
Reply
#3
Thank you Nilamo.
I wondered if, without prejudice to the code, there was a way to work on the output data. The object is not iterable and therefore does not allow the use of "set", or of "unique_everseen". In essence, I would like, after the script has provided the results, to act on the same by eliminating the permuted objects
Reply
#4
Instead of print()ing, build a list?
>>> from itertools import permutations
>>> def generate_squares():
...   x = list(range(1, 10))
...   for a in permutations(x, 9):
...     if a[0]+a[1]+a[2]==15 and a[3]+a[4]+a[5]==15:
...       if a[6]+a[7]+a[8]==15 and a[0]+a[3]+a[6]==15:
...         if a[1]+a[4]+a[7]==15 and a[2]+a[5]+a[8]==15:
...           if a[0]+a[4]+a[8]==15 and a[2]+a[4]+a[6]==15:
...             yield [a[:3], a[3:6], a[6:]]
...
>>> # quick test
...
>>> for square in generate_squares():
...   print(square)
...
[(2, 7, 6), (9, 5, 1), (4, 3, 8)]
[(2, 9, 4), (7, 5, 3), (6, 1, 8)]
[(4, 3, 8), (9, 5, 1), (2, 7, 6)]
[(4, 9, 2), (3, 5, 7), (8, 1, 6)]
[(6, 1, 8), (7, 5, 3), (2, 9, 4)]
[(6, 7, 2), (1, 5, 9), (8, 3, 4)]
[(8, 1, 6), (3, 5, 7), (4, 9, 2)]
[(8, 3, 4), (1, 5, 9), (6, 7, 2)]
Reply
#5
This doesn't answer the question, but you can simplify the code
rows = [
    (0, 1, 2), (3, 4, 5), (6, 7, 8),
    (0, 3 ,6), (1, 4, 7), (2, 5 ,8),
    (0, 4, 8), (2, 4, 6),]

if all(a[i] + a[j] + a[k] == 15 for i, j, k in rows):
    yield ...
About the algorithm, note that three corners of the magic square define completely the square because of the sum conditions. itertools.combinations() would be a better choice than itertools.permutations()
Reply
#6
This is a new code for magic square with same problem. I'm asking how filter a single magic square, after the script has been processed.
The output is:
2,7,6
9,5,1
4,3,8
----
2,9,4
7,5,3
6,1,8
----
3,8,7
10,6,2
5,4,9
----
3,10,5
8,6,4
7,2,9
----
4,3,8
9,5,1
2,7,6
----
4,9,2
3,5,7
8,1,6
----
5,4,9
10,6,2
3,8,7
----
5,10,3
4,6,8
9,2,7
----
6,1,8
7,5,3
2,9,4
----
6,7,2
1,5,9
8,3,4
----
7,2,9
8,6,4
3,10,5
----
7,8,3
2,6,10
9,4,5
----
8,1,6
3,5,7
4,9,2
----
8,3,4
1,5,9
6,7,2
----
9,2,7
4,6,8
5,10,3
----
9,4,5
2,6,10
7,8,3
----
I would output without repetition, like this:
2,7,6
9,5,1
4,3,8
-----
9,4,5
2,6,10
7,8,3

class MagicSquare :
    def __init__(self, coef) :
        self.mat = [ [ coef[i+j*3] for i in range(3) ] for j in range(3) ]
    def __str__(self) :
        return "\n".join ( [ ",".join( [ str(n) for n in row ] ) for row in self.mat ] )
    def __add__ (self, Square) :
        coef = []
        for i in range(3) :
            for j in range(3) :
                coef.append ( self.mat[i][j] + Square.mat[i][j])
        return MagicSquare(coef)
    def Sum_H_V_D(self):
        tout = [ sum ( lines ) for lines in self.mat ] + \
               [ sum ( self.mat[i][j] for i in range(3) ) for j in range(3) ] + \
               [ sum ( self.mat[i][i] for i in range(3) ) ] + \
               [ sum ( self.mat[2-i][i] for i in range(3) ) ]
        return tout
        return sorted(tout)
        
    def Coeff_unique(self):
        d = { }
        for lines in self.mat :
            for c in lines :
                d [c] = d.get(c,0) +1
        return len(d) == 9
        
    def is_magic(self):
        unique = self.Coeff_unique()
        if not unique : return False
        additions = self.Sum_H_V_D()
        return min(additions) == max(additions)
        return sorted(additions)
        
        
def all_magic_squares():
    res=[]
    lst=([1,2,3,4,5,6,7,8,9,10])
    
    
    print()
    
    for a1 in lst:
        for a2 in lst:
            for a3 in lst:
                for b1 in lst:
                    additions = a1 + a2 + a3
                    c1 = additions - a1 - b1
                    b2 = additions - a3 - c1
                    b3 = additions - b1 - b2
                    c2 = additions - a2 - b2
                    c3 = additions - c1 - c2
                    
                    M = MagicSquare([a1,a2,a3, b1,b2,b3, c1,c2,c3])
                    
                    
                    if M.is_magic()  and 0 < b2 < 91 and 0 < b3 < 91 and 0 < c1 < 91 and 0 < c2 < 91 and 0 < c3 < 91  and b1 in lst and b2 in lst and b3 in lst and c2 in lst and c3 in lst:
                        res.append (M)
                    
                        
                        print(M)
                        print ("----")
                            
                        
                        
                            
                        
    return res
   
    
res = all_magic_squares()
Reply
#7
Add this method to the square class. Then normalize the produced squares and remove repetitions
    def normalize(self):
        if self.mat[0][0] > self.mat[2][2]:
            self.mat = [row[::-1] for row in self.mat[::-1]]
        if self.mat[2][0] > self.mat[0][2]:
            self.mat = [list(row) for row in zip(*self.mat)]
        if self.mat[0][0] > self.mat[2][0]:
            self.mat = self.mat[::-1]
alternately, you can use
def is_magic_and_cool(self):
    return (self.is_magic() and
                self.mat[0][0] < min(self.mat[2][0], self.mat[2][2]) and self.mat[2][0] < self.mat[0][2])
and generate only magic and cool squares.
Reply
#8
Thanks 'It's work . Super speed
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  Eliminate entering QR - Whatsapp web automated by selenium akanowhere 1 3,096 Jan-21-2024, 01:12 PM
Last Post: owalahtole
  Why does newly-formed dict only consist of last row of each year? Mark17 6 799 Nov-17-2023, 05:28 PM
Last Post: Mark17
  magic related field in Django model sonh 1 1,242 Apr-24-2022, 12:37 PM
Last Post: sonh
  Need a little help with numpy array magic. pmf71 0 1,156 Dec-01-2021, 02:51 AM
Last Post: pmf71
  Magic Method Arithmetic Operators ClownPrinceOfCrime 3 2,328 Jan-10-2021, 03:24 PM
Last Post: ndc85430
  How to eliminate unwanted spaces Mohan 5 2,892 Jun-04-2020, 08:34 AM
Last Post: buran
  [gpxpy] "Error parsing XML: not well-formed (invalid token): line 1, column 1" Winfried 5 6,695 Jan-26-2020, 01:09 AM
Last Post: Winfried
  Print Numbers starting at 1 vertically with separator for output numbers Pleiades 3 3,744 May-09-2019, 12:19 PM
Last Post: Pleiades
  Magic method __str__ dan789 16 7,229 Dec-23-2018, 03:59 PM
Last Post: ichabod801
  [split] Bad magic number. What is it ? Douglas 2 5,274 Oct-22-2018, 10:38 AM
Last Post: Douglas

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020