Posts: 11
Threads: 4
Joined: Sep 2018
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()
Posts: 3,458
Threads: 101
Joined: Sep 2016
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?
Posts: 11
Threads: 4
Joined: Sep 2018
May-08-2019, 08:13 PM
(This post was last modified: May-08-2019, 08:13 PM by frame.)
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
Posts: 3,458
Threads: 101
Joined: Sep 2016
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)]
Posts: 4,784
Threads: 76
Joined: Jan 2018
May-08-2019, 09:05 PM
(This post was last modified: May-08-2019, 09:06 PM by Gribouillis.)
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()
Posts: 11
Threads: 4
Joined: Sep 2018
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()
Posts: 4,784
Threads: 76
Joined: Jan 2018
May-09-2019, 09:12 AM
(This post was last modified: May-09-2019, 09:19 AM by Gribouillis.)
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.
Posts: 11
Threads: 4
Joined: Sep 2018
Thanks 'It's work . Super speed
|