python 3.5.0 :::: MAGIC SQUARE - python

I'm trying to built a magic square:
A magic square is one divided in rows and columns, with a number in each position and which the sum of rows, columns and diagonals is the same.
Example (3x3 - numbers from 1 to 9):
8 3 4
1 5 9
6 7 2
I tried to use a matrix 3x3 and a vector with 9 indexes.
import random
#j(column)
matriz = [[1, 2, 3],#i(row)
[4, 5, 6],
[7, 8, 9]]
res = False
#DEFINE A FUNCTION TO CALCULATE ALL SUMS OF ALL SIDES
def magicsquare():
if matriz[0][0] + matriz[1][0] + matriz[2][0] == matriz[0][1] + matriz[1][1] + matriz[2][1] == matriz[0][2] + matriz[1][2] + matriz[2][2] == matriz[0][0] + matriz[0][1] + matriz[0][2] == matriz[1][0] + matriz[1][1] + matriz[1][2] == matriz[2][0] + matriz[2][1] + matriz[2][2] == matriz[0][0] + matriz[1][1] + matriz[2][2] == matriz[0][2] + matriz[1][1] + matriz[2][0]:
return res = True
else:
return res = False
#DEFINE A LOOP TO GENERATE RANDOM NUMBER UNTIL FIND THE ONES THAT
#SATISFY THE CONDITIONS OF A MAGIC SQUARE
seq = [1, 2, 3, 4, 5, 6, 7, 8, 9]
while res == False:
for i in range(2):
for j in range(2):
z = random.choice(seq)
matriz[i][j] = z
x = seq.index(z)
seq[x] = []
magicsquare()
print (matriz)
#---------------------------------------------------------------------------------------------------------------------------------------------------------------
res = False
def magicsquare():
if vetor[0] + vetor[1] + vetor[2] == vetor[3] + vetor[4] + vetor[5] == vetor[6] + vetor[7] + vetor[8] == vetor[0] + vetor[3] + vetor[6] == vetor[1] + vetor[4] + vetor[7] == vetor[2] + vetor[5] + vetor[8] == vetor[0] + vetor[4] + vetor[8] == vetor[2] + vetor[4] + vetor[6]:
return res == True
else:
return res == False
# 0 1 2 3 4 5 6 7 8
vetor = [1, 2, 3, 4, 5, 6, 7, 8, 9]
seq = [1, 2, 3, 4, 5, 6, 7, 8, 9]
if res == False:
for i in range(8):
w = random.choice(seq)
#Replace the value w in index i
vetor.insert(i, w)
#Eliminate the valyes already used
x = seq.index(w)
seq[x] =[]
magicsquare()
print (vetor)
The result is always: [1, 2, 3, 4, 5, 6, 7, 8, 9]
Can anyone help me built a magic square and tell what's wrong with my code?
Using Python 3.5.0

Your randomizing code is wrong.
>>>
Traceback (most recent call last):
File "C:/Users/xiao/Desktop/ms.py", line 20, in <module>
magicsquare()
File "C:/Users/xiao/Desktop/ms.py", line 5, in magicsquare
if vetor[0] + vetor[1] + vetor[2] == vetor[3] + vetor[4] + vetor[5] == vetor[6] + vetor[7] + vetor[8] == vetor[0] + vetor[3] + vetor[6] == vetor[1] + vetor[4] + vetor[7] == vetor[2] + vetor[5] + vetor[8] == vetor[0] + vetor[4] + vetor[8] == vetor[2] + vetor[4] + vetor[6]:
TypeError: unsupported operand type(s) for +: 'int' and 'list'
>>> vetor
[9, 4, 8, 2, 3, [], [], [], 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>>
random module has a method called shuffle for shuffling a list. If you have no idea about your code, just use random.shuffle.
Plus, there are 2 ways to stop the while loop. The first way is to change the global variable res in function magicsquare:
def magicsquare():
global res
if ...:
res = True
else:
res = False
The other way is to return the condition in magicsquare:
import random
vetor = [1, 2, 3, 4, 5, 6, 7, 8, 9]
def magicsquare():
return vetor[0]+vetor[1]+vetor[2]==\
vetor[3]+vetor[4]+vetor[5]==\
vetor[6]+vetor[7]+vetor[8]==\
vetor[0]+vetor[3]+vetor[6]==\
vetor[1]+vetor[4]+vetor[7]==\
vetor[2]+vetor[5]+vetor[8]==\
vetor[0]+vetor[4]+vetor[8]==\
vetor[2]+vetor[4]+vetor[6]
while not magicsquare():
random.shuffle(vetor)
print (vetor)

def forEvenNumber(n):
arr = [[(n * y) + x + 1 for x in range(n)] for y in range(n)]
for i in range(0, n // 4):
for j in range(0, n // 4):
arr[i][j] = (n * n + 1) - arr[i][j];
for i in range(0, n // 4):
for j in range(3 * (n // 4), n):
arr[i][j] = (n * n + 1) - arr[i][j];
for i in range(3 * (n // 4), n):
for j in range(0, n // 4):
arr[i][j] = (n * n + 1) - arr[i][j];
for i in range(3 * (n // 4), n):
for j in range(3 * (n // 4), n):
arr[i][j] = (n * n + 1) - arr[i][j];
for i in range(n // 4, 3 * (n // 4)):
for j in range(n // 4, 3 * (n // 4)):
arr[i][j] = (n * n + 1) - arr[i][j];
print("\nSum of all row, column and diagonals = ",
n * (n * n + 1) // 2, "\n")
for i in range(n):
for j in range(n):
print('%2d ' % (arr[i][j]), end=" ")
print()
def forOddNumber(n):
mgsqr = [[0 for x in range(n)]
for y in range(n)]
r = n // 2
c = n - 1
num = 1
while num <= (n * n):
if r == -1 and c == n:
c = n - 2
r = 0
else:
if c == n:
c = 0
if r < 0:
r = n - 1
if mgsqr[int(r)][int(c)]:
c = c - 2
r = r + 1
continue
else:
mgsqr[int(r)][int(c)] = num
num = num + 1
c = c + 1
r = r - 1
print("\nSum of all row, column and diagonals = ",
n * (n * n + 1) // 2, "\n")
for i in range(0, n):
for j in range(0, n):
print('%2d ' % (mgsqr[i][j]), end='')
print()
print("\nWELCOME:)\n")
n = int(input("Please Enter Number of Rows and Column (n*n): "))
if n%2==0:
forEvenNumber(n)
else:
forOddNumber(n)
print("\nThank You :)")

try my code..
box = []
num = [1, 2, 3,
4, 5, 6,
7, 8, 9]
val = []
for i in num:
for j in num:
for k in num:
if ((i+j+k) == 15) and i != j and j != k and k != i:
val.append((i, j, k))
def check_sum(lst: list):
rtn = []
res = 0
lst = lst[0]
for c in range(3):
for r in range(3):
res += lst[r][c]
if res == 15:
rtn.append(True)
else:
rtn.append(False)
res = 0
res = 0
for x in range(3):
for y in range(3):
if x == y:
res += lst[x][y]
if res == 15:
rtn.append(True)
else:
rtn.append(False)
res = 0
for x in range(3):
for y in range(3):
if x+y == 2:
res += lst[x][y]
if res == 15:
rtn.append(True)
else:
rtn.append(False)
return all(rtn)
def is_unique(a, b, c):
st = set()
for x in a:
st.add(x)
for x in b:
st.add(x)
for x in c:
st.add(x)
if len(st) == 9:
return True
else:
return False
def print_box(b):
for row in b[0]:
print(row)
print()
for i in val:
for j in val:
for k in val:
if is_unique(i, j, k):
box.append([i, j, k])
if check_sum(box):
print_box(box)
if len(box) == 1:
box.clear()
output is:
(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)

Related

check if key is present in every segment of size k in array?

def findxinkindowSize(arr, x, k, n) :
i = 0
while i < n :
j = 0
# Search x in segment
# starting from index i
while j < k :
if arr[i + j] == x :
break
j += 1
# If loop didn't break
if j == k :
return False
i += k
# If n is a multiple of k
if i == n :
return True
j = i - k
# Check in last segment if n
# is not multiple of k.
while j < n :
if arr[j] == x :
break
j += 1
if j == n :
return False
return True
# Driver Code
if __name__ == "__main__" :
arr = [ 3, 5, 2, 4, 9, 3,
1, 7, 3, 11, 12, 3 ]
x, k = 3, 3
n = len(arr)
if (findxinkindowSize(arr, x, k, n)) :
print("Yes")
else :
print("No")
Above code works good for the array of size 3, 6, 9, 12, ... i.e multiples of size of k (segment size), but for the array arr = [3, 5, 2, 4, 9, 3, 1, 7] which is of size 8 there is an error in the line if arr[i + j] == x : shows out of index.
Is there any better solution for this problem?
This is a simple approach using slicing.
Iterate through every slice of size k and check if x is present in that slice or not.
def findxinkindowSize(arr, x, k, n):
for i in range(0, n, k):
if x not in arr[i: i+k]:
return False
return True
This code doesn't give IndexError.

how to collect all elements that has same value into array with python?

I am finding the longest path with my data and my code is collecting the longest path in each node.
def dfs(node, adj, dp, vis):
vis[node] = True
for i in range(0, len(adj[node])):
if not vis[adj[node][i]]:
dfs(adj[node][i], adj, dp, vis)
dp[node] = max(dp[node], [node] + dp[adj[node][i]], key=lambda x: len(x))
def findLongestPathFromEachNode(adj, n):
dp = [[x] for x in range(n)]
vis = [False] * (n + 1)
for i in range(1, n + 1):
if not vis[i]:
dfs(i, adj, dp, vis)
return dp[1:]
n = 6
adj = [[] for i in range(n + 1)]
addEdge(adj, 1, 2)
addEdge(adj, 1, 3)
addEdge(adj, 3, 2)
addEdge(adj, 2, 4)
addEdge(adj, 2, 5)
addEdge(adj, 3, 4)
addEdge(adj, 3, 5)
and I got this results
In[29]:
paths = findLongestPathFromEachNode(adj, n)
paths
Out[29]:
[[1, 3, 2, 4], [2, 4], [3, 2, 4], [4], [5]]
while I expect to see the results as
[[1, 3, 2, 4], [1, 3, 2, 5], [2, 4], [2, 5], [3, 2, 4], [3, 2, 5], [4], [5]]
due to longest paths in each node are reached to node 5 too.
any suggestion?
The core idea to your question is to store not the single path in dp but the array of paths: dp = [[[x]] for x in range(n)].
Then in your dfs we will compare our new possibly longer paths with any instance from dp[node]. For example with zero index because we can guarantee that it will always exist: if len(dp[node][0]) < 1 + len(dp[adj[node][i]][0]): and elif len(dp[node][0]) == 1 + len(dp[adj[node][i]][0]):.
Also, we will need to append a node to every new path in the dp:
if len(dp[node][0]) < 1 + len(dp[adj[node][i]][0]):
dp[node] = []
for path in dp[adj[node][i]]:
dp[node].append([node] + path)
elif len(dp[node][0]) == 1 + len(dp[adj[node][i]][0]):
for path in dp[adj[node][i]]:
dp[node].append([node] + path)
All in all, it will be:
def dfs(node, adj, dp, vis):
vis[node] = True
for i in range(0, len(adj[node])):
if not vis[adj[node][i]]:
dfs(adj[node][i], adj, dp, vis)
if len(dp[node][0]) < 1 + len(dp[adj[node][i]][0]):
dp[node] = []
for path in dp[adj[node][i]]:
dp[node].append([node] + path)
elif len(dp[node][0]) == 1 + len(dp[adj[node][i]][0]):
for path in dp[adj[node][i]]:
dp[node].append([node] + path)
def findLongestPathFromEachNode(adj, n):
dp = [[[x]] for x in range(n)]
vis = [False] * (n + 1)
for i in range(1, n + 1):
if not vis[i]:
dfs(i, adj, dp, vis)
return dp[1:]
n = 6
adj = [[] for i in range(n + 1)]
addEdge(adj, 1, 2)
addEdge(adj, 1, 3)
addEdge(adj, 3, 2)
addEdge(adj, 2, 4)
addEdge(adj, 2, 5)
addEdge(adj, 3, 4)
addEdge(adj, 3, 5)

Find LowCost path and print

I am trying to print the path for the LowCost script I found here the code
Find LowCost I change some small stuff only.
The script works but it gives me only the final cost; I want it also to give me the path I have taken.
Here is an example:
[ [1, 2, 3],
[4, 8, 2],
[1, 5, 3] ]
so here how look like the path its get the 1,2,2,3:
1-2 3
.....\
4 8 2
......|
1 5 3
i want to print correc the path like Correct
path : [1,2,2,3]
low cost : 8
Now I get a very big path result and it's no correct Wrong !
path : [1, 1, 1, 1, 1, 3, 1, 1, 1, 3, 1, 1, 1, 1, 1, 5, 5, 5]
low cost : 8
Here is the code:
import sys
def mymin(a,b,c):
return min(min(a,b),c)
def minCostMain(cost, m, n):
result = []
def minCost(cost, m, n):
if (n < 0 or m < 0):
return sys.maxsize
elif (m == 0 and n == 0):
return cost[m][n]
else:
t1= minCost(cost, m-1, n-1)
t2= minCost(cost, m-1, n)
t3= minCost(cost, m, n-1)
v=mymin(t1,t2,t3)
#this dosen't work get more items
result.append(v)
return cost[m][n] + v
return minCost(cost, m, n),result
cost= [ [1, 2, 3],
[4, 8, 2],
[1, 5, 3] ]
lowcost,path= minCostMain(cost, 2, 2)
print "path : " + str(path)
print "low cost : " + str(lowcost)
ok now understand how its working i need to keep list in function and the self function return list no value and after i add the new item :) like this now i can get the path and the map where it's in list the number 1,2,2,3
import sys
def MyPrint(mlist):
mlist[0]=str(mlist[0]) + " = (0,0)"
sum=0
for item in mlist:sum+=int(item.split(" = (")[0])
print "*"*20
print "Sum = "+str(sum)
print "*"*20
print "map"
print "*"*20
for item in mlist:print item
def Min(x,y, z):
if (x[-1] < y[-1]):
return x if (x[-1] < z[-1]) else z
else:
return y if (y[-1] < z[-1]) else z
def minCost(cost, m, n):
if (n < 0 or m < 0):
return [sys.maxsize]
elif (m == 0 and n == 0):
return [cost[m][n]]
else:
arr=Min(minCost(cost, m-1, n-1),
minCost(cost, m-1, n),
minCost(cost, m, n-1))
arr.append(str(cost[m][n])+" = ("+str(m)+","+str(n)+")")
return arr
cost= [ [1, 2, 3],
[4, 8, 2],
[1, 5, 3] ]
x=minCost(cost, 2, 2)
MyPrint(x)
the result it's
********************
Sum = 8
********************
map
********************
1 = (0,0)
2 = (0,1)
2 = (1,2)
3 = (2,2)

range() function not producing expected result

I have a program:
def num4():
def tp(nums):
res = []
for i in range(len(nums)):
for j in range(i+1,len(nums)):
res.append(nums[i] + nums[j])
return res
nums = [ 1, 5, 7, -2 ]
print(tp(nums)
I walked through what it does, marked it up, and expected it to produce this result:
def tp(nums):
res = []
for i in range(len(nums)):
# startvalue = len(nums), stopvalue = 0, inc = 1
for j in range(i+1,len(nums)):
# startvalue = i + 1, stopvalue = len(nums) - 1, inc = 1
res.append(nums[i] + nums[j])
return res
nums = [ 1, 5, 7, -2 ]
print(tp(nums))
for i in range(4):
# range(4) = 1, 2, 3, 4
i = 1:
for j in range(i + 1, 4):
# range(1 + 1, 4) = 2, 3
res = [nums[1] + nums[2]] = 5 + 7 = 12
res = [nums[1] + nums[3]] = 5 - 2 = 3
i = 2:
for j in range(i + 1, 4):
# range(2+1, 4) = 3
res = [nums[2] + nums[3]] = 7 - 2 = 5
i = 3:
for j in range(i + 1, 4):
# range(3+1, 4) = n/a
res = [nums[3] + n/a] = -2
i = 4
for j in range(i + 1, 4):
# range(4+1, 4) = n/a
res = [nums[4] + n/a] = 1
PREDICTED OUTPUT: res = [ 12, 3, 5, -2, 1 ]
Instead, when I did this in a Python interactive session:
from ExamCheck1 import num4
num4()
It produced this output:
[6, 8, -1, 12, 3, 5]
I got the 12, 3, 5 right, but where did the 6, 8, -1 part come from? I'm very lost and confused.
The values you expect from the range function are a bit flawed. There are three possible ways you can use the range function:
range(x): Generates an array with values from 0 ~ x-1. So range(4) = [0,1,2,3]
range(x,y): Generates values from x ~ y-1. So range(1,4) = [1,2,3]
range(x,y,z): Generating values from x~y-1 in steps of z. So range(1,10,2) = [1, 3, 5, 7, 9]
Walk through your code with these values of range and it will make sense to you.

How to display all available variants in python?

If I have this simple code, how can I display all available variants ?
#Display all possible variants until reach input sum with coins of 2 and 5
#Not fixed: Output only first result !
#Input
summ = int(input("Enter sum: "))
two = 2
five = 5
#Calculations/Checks/Output
for i in range(0, two+1):
for j in range(0, five+1):
if (i*2 + j*5 == summ):
print(i, "*2 + ", j, "*5 = ", summ)
#End
For example:
Input: 17
Output:
1*2 + 3*5 = 17
6*2 + 1*5 = 17
But the code displays only the first result?
How can I fix this ?
Change the inputs of range:
summ = int(input("Enter sum: "))
two = 2
five = 5
for i in range(summ//two+1):
for j in range(summ//five+1):
if (i*2 + j*5 == summ):
print(i, "* 2 +", j, "* 5 =", summ)
You can use itertools, and a generator:
In [17]: def correct_sum_i(i, val):
...: sum_perm = [comb for comb in itertools.combinations_with_replacement([2,5],i) if sum(comb) == val]
...: return sum_perm[0] if sum_perm else None
...:
In [18]: val = 14
In [19]: next(correct_sum_i(i,val) for i in range(1000) if correct_sum_i(i, val))
Out[19]: (2, 2, 5, 5)
Edit: You probably also want to check for pathological cases where this is not possible, like 1,3 etc....
Edit: all sums
In [50]: def all_sums(char_set, sum_value):
...: def correct_sum_i(i):
...:
...: sum_perm = [comb for comb in itertools.combinations_with_replacement(char_set,i) if sum(comb) == sum_value]
...: return sum_perm if sum_perm else None
...:
...: assert min(char_set) > 0
...:
...: return list(correct_sum_i(i) for i in range(int(sum_value / min(char_set))+ 1) if correct_sum_i(i))
...:
In [51]: print (all_sums([2,5], 20))
[[(5, 5, 5, 5)], [(2, 2, 2, 2, 2, 5, 5)], [(2, 2, 2, 2, 2, 2, 2, 2, 2, 2)]]
this also gives you the desired behaviour for your case:
In [53]: print (all_sums([2,5], 17))
[[(2, 5, 5, 5)], [(2, 2, 2, 2, 2, 2, 5)]]

Categories