魔方python
Magic square python
我正在编写一个程序,该程序读取文件中的一行并确定该行是否构成 Lo Shu 幻方。在这个魔方中,行的和、列的和、对角线的和必须等于 15,并且每个数字 1-9 在方块中只能出现一次。这是我目前所拥有的:
def main():
for line in open("Magic Square Input.txt"):
items = line.split(" ")
items = [int(x) for x in items]
result = [items[0:3], items[3:6], items[6:9]]
isMagic(result)
def isMagic(result):
checks1 = ''
for x in result:
for y in range(3):
if sum (result[y][y] for y in range(3)) == 15:
if sum(x[y] for x in result) == 15:
checks1 = checkDupe(result)
else:
checks1 = 'Invalid'
else:
checks1 = 'Invalid'
print(checks1)
def checkDupe(result):
checks1 = ''
for i in range(0,8):
counter = 0
for j in result:
if (j == i):
counter += 1
if counter > 0:
checks1 = 'Invalid'
else:
checks1 = 'Valid'
return checks1
main()
我的文本文件内容如下:
4 3 8 9 5 1 2 7 6
8 3 4 1 5 9 6 7 2
6 1 8 7 5 3 2 9 4
6 9 8 7 5 3 2 1 4
6 1 8 7 5 3 2 1 4
6 1 3 2 9 4 8 7 5
5 5 5 5 5 5 5 5 5
每行的前三个数字代表正方形的顶行,接下来的三个是中间行,最后三个是底行。我遇到的问题是前三个方块是有效的,而后四个方块应该是无效的。但是我的代码一直为我打印的是
Valid
Valid
Valid
Valid
Valid
Invalid
Valid
有人可以告诉我哪里搞砸了吗?我是 python 的新手,我已经盯着它看了好几个小时试图理解它。
我的版本没有将项目拆分成行
data = '''4 3 8 9 5 1 2 7 6
8 3 4 1 5 9 6 7 2
6 1 8 7 5 3 2 9 4
6 9 8 7 5 3 2 1 4
6 1 8 7 5 3 2 1 4
6 1 3 2 9 4 8 7 5
5 5 5 5 5 5 5 5 5'''
def main():
for line in data.split("\n"):
# create list with all numbers
items = list(map(int, line.split()))
print(is_magic(items))
def is_magic(items):
# --- dups ---
#print('dups')
#print(len(set(items)) == 9)
#for x in range(1, 10):
# print(x, x in items)
if len(set(items)) != 9:
return 'Invalid'
# --- rows ---
#print('rows')
for x in range(0, 9, 3):
l = items[x:x+3]
#print(l, sum(l) == 15)
if sum(l) != 15:
return 'Invalid'
# --- cols ---
#print('cols')
for x in range(3):
l = [items[x], items[x+3], items[x+6]]
#print(l, sum(l) == 15)
if sum(l) != 15:
return 'Invalid'
# --- diags ---
#print('diags')
l = [items[0], items[4], items[8]]
#print(l, sum(l) == 15)
if sum(l) != 15:
return 'Invalid'
l = [items[2], items[4], items[6]]
#print(l, sum(l) == 15)
if sum(l) != 15:
return 'Invalid'
# --- OK ---
return 'Valid'
main()
我不得不进行一些重大更改,但您的 checkDupe 方法似乎无法正常工作。您也只检查了一个对角线而不是两个。另外,请注意,不是使用 check1 变量保存答案是否有效,而是简单地 returns 'Invalid' 如果有任何错误,这通常会使代码更清晰并大大简化问题。如果永远不会返回 'Invalid',那么该方法只是 returns 'Valid' 最后。
def main():
for line in open("Magic Square Input.txt"):
items = line.split(" ")
items = [int(x) for x in items]
result = [items[0:3], items[3:6], items[6:9]]
print isMagic(result)
def isMagic(result):
# check duplicates
if(checkDupe(result) == 'Invalid'):
return 'Invalid'
# diagonals
if sum (result[y][y] for y in range(3)) != 15:
return 'Invalid'
# other digonals
if sum (result[2 - y][2 - y] for y in range(3)) != 15:
return 'Invalid'
# rows and columns
for i in range(3):
if sum(result[i][y] for y in range(3)) != 15:
return 'Invalid'
if sum(result[x][i] for x in range(3)) != 15:
return 'Invalid'
return 'Valid'
def checkDupe(result):
for x in range(1,9):
if(not x in (result[0]+result[1]+result[2])):
return 'Invalid'
return 'Valid'
main()
为了帮助您,我应该开始说您的代码很难阅读。由于您是 Python 的新手,很快您就会发现 Python 的主要好处之一是其清晰的语法,这使得弄清楚一段代码在做什么变得非常容易。话虽这么说,我解决了你的问题,使用与你相同的逻辑,但使代码更具可读性并使用一些 Python 技巧使解决方案更短更清晰。
def main():
"""Open the file, parse the input and check if it is a magic cube"""
with open("Magic Square Input.txt") as f:
for line in f.readlines():
numbers = line.split(" ")
cube = [int(x) for x in numbers]
is_magic(cube)
def is_magic(cube):
"""Check if cube is magic.
There are two conditions that must be satisfied:
1 - There must not be any repetitions of the numbers
2 - All vertical/horizontal/diagonal sums must be 15
"""
if not dupe(cube) and check_sum(cube):
print ('Valid')
else:
print ('Invalid')
def dupe(cube):
"""Check if there are repetitions in the cube."""
if len(cube) == len(set(cube)):
return False
return True
def check_sum(cube):
"""Check if all vertical/horizontal/diagonal sums are 15"""
if vertical_check(cube) and horizontal_check(cube) and diagonal_check(cube):
return True
def vertical_check(cube):
if sum(cube[0:9:3]) == sum(cube[1:9:3]) == sum(cube[2:9:3]) == 15:
return True
return False
def horizontal_check(cube):
if sum(cube[0:3]) == sum(cube[3:6]) == sum(cube[6:9]) == 15:
return True
return False
def diagonal_check(cube):
if sum(cube[0:9:4]) == sum(cube[2:7:2]) == 15:
return True
return False
main()
希望您能从代码中的注释中理解解决方案。如果不是这种情况,请再次post这里。
如果你从一个平面列表开始,这个问题就更容易思考了:
[4, 3, 8, 9, 5, 1, 2, 7, 6]
然后算出您需要检查哪些索引。一共只有八个:
indexes = (
(0, 1, 2), (3, 4, 5), (6, 7, 8), # rows
(0, 3, 6), (1, 4, 7), (2, 5, 8), # cols
(0, 4, 8), (2, 4, 6), # diag
)
有了这个设置,检查功能变得非常简单:
def main():
for line in open('Magic Square Input.txt'):
square = [int(n) for n in line.split()]
if len(set(square)) != len(square):
print('Invalid: Duplicates')
else:
for idx in indexes:
if sum(square[i] for i in idx) != 15:
print('Invalid: Sum')
break
else:
print('Valid')
这里我创建了示例方法来解决这个问题。在这种方法中,我们维护以下列表
- lstAvailableNumbers:可用号码列表(在您的情况下为 1-9)
- lstTraversedNumbers:遍历的数字列表(一旦遍历一个项目,它就被移动到这个列表中)
- 重复号码列表(所有重复号码将添加到此列表)
- 重复号码索引(将存储重复号码的索引,以便用于替换不存在的号码
- 还return更换的费用
出于调试目的,我还添加了打印语句来检查不同列表的值
def createMagicSquare(s):
lstAvailableNumbers = list()
lstAvailableNumbers=[1,2,3,4,5,6,7,8,9]
lstTraversedNumbers=set()
lstDuplicateNumbers=list()
dictDuplicateNumberIndex = dict()
lstMissingNumbers=set()
cost=0
for item in range(len(s)):
for colItem in range(len(s[item])):
num= s[item][colItem]
#print('Print traversed number - ' )
#print(num)
#print(lstTraversedNumbers)
if(num in lstAvailableNumbers):
#print('Inside if condition for num in lstAvailableNumbers ' )
lstAvailableNumbers.remove(num)
#print(num)
if(num in lstTraversedNumbers):
#print('Inside if condition for num in lstTraversedNumbers ' )
#print(num)
lstDuplicateNumbers.append(num)
lstIndexPosition =[]
lstIndexPosition.append(item)
lstIndexPosition.append(colItem)
dictDuplicateNumberIndex[num]=lstIndexPosition
lstTraversedNumbers.add(num)
#print(lstTraversedNumbers)
else:
lstDuplicateNumbers.append(num)
lstIndexPosition =[]
lstIndexPosition.append(item)
lstIndexPosition.append(colItem)
dictDuplicateNumberIndex[num]=lstIndexPosition
i=0
#print("Available Numbers -")
#print(lstAvailableNumbers)
#print("Traversed Numbers -")
#print(lstTraversedNumbers)
#print("Duplicate Numbers -")
#print(lstDuplicateNumbers)
#print("Duplicate Number index -")
#print(dictDuplicateNumberIndex)
for item in lstAvailableNumbers:
itemToReplace= lstDuplicateNumbers[i]
value= dictDuplicateNumberIndex[itemToReplace]
s[value[0]][value[1]] = item
i+=1
cost += abs(itemToReplace - item)
#print(cost)
return cost
def magic_square(n):
num=(n*((n*n)+1))/2
print('\nThe Magic Number Is:-',num,'\n')
f=[]
for i in range(0,n):
a=[]
for j in range(0,n):
a.append(0)
f.append(a)
(x,i,p,q)=(n*n,1,int(n/2),n-1)
while x!=0:
if x==0:
(f[p][q],i,p,q,x)=(i,i+1,p-1,q+1,x-1)
continue
else:
if p==-1 and q==n:
p=0
q=n-2
if f[p][q]==0:
(f[p][q],i,p,q,x)=(i,i+1,p-1,q+1,x-1)
continue
else:
p=p+1
q=q-2
f[p][q]=i
i=i+1
p=p-1
q=q+1
x=x-1
continue
if p==-1:
p=n-1
if f[p][q]==0:
(f[p][q],i,p,q,x)=(i,i+1,p-1,q+1,x-1)
continue
else:
p=p+1
q=q-2
f[p][q]=i
i=i+1
p=p-1
q=q+1
x=x-1
continue
if q==n:
q=0
if f[p][q]==0:
(f[p][q],i,p,q,x)=(i,i+1,p-1,q+1,x-1)
continue
else:
p=p+1
q=q-2
f[p][q]=i
i=i+1
p=p-1
q=q+1
x=x-1
continue
else:
if f[p][q]==0:
(f[p][q],i,p,q,x)=(i,i+1,p-1,q+1,x-1)
continue
else:
p=p+1
q=q-2
f[p][q]=i
i=i+1
p=p-1
q=q+1
x=x-1
continue
for i in range(len(f)):
for j in range(len(f[i])):
print(f[i][j] ,end = " ")
print("\n")
输入
magic_square(5)
输出
神奇的数字是:- 65.0
9 3 22 16 15
2 21 20 14 8
25 19 13 7 1
18 12 6 5 24
11 10 4 23 17
我正在编写一个程序,该程序读取文件中的一行并确定该行是否构成 Lo Shu 幻方。在这个魔方中,行的和、列的和、对角线的和必须等于 15,并且每个数字 1-9 在方块中只能出现一次。这是我目前所拥有的:
def main():
for line in open("Magic Square Input.txt"):
items = line.split(" ")
items = [int(x) for x in items]
result = [items[0:3], items[3:6], items[6:9]]
isMagic(result)
def isMagic(result):
checks1 = ''
for x in result:
for y in range(3):
if sum (result[y][y] for y in range(3)) == 15:
if sum(x[y] for x in result) == 15:
checks1 = checkDupe(result)
else:
checks1 = 'Invalid'
else:
checks1 = 'Invalid'
print(checks1)
def checkDupe(result):
checks1 = ''
for i in range(0,8):
counter = 0
for j in result:
if (j == i):
counter += 1
if counter > 0:
checks1 = 'Invalid'
else:
checks1 = 'Valid'
return checks1
main()
我的文本文件内容如下:
4 3 8 9 5 1 2 7 6
8 3 4 1 5 9 6 7 2
6 1 8 7 5 3 2 9 4
6 9 8 7 5 3 2 1 4
6 1 8 7 5 3 2 1 4
6 1 3 2 9 4 8 7 5
5 5 5 5 5 5 5 5 5
每行的前三个数字代表正方形的顶行,接下来的三个是中间行,最后三个是底行。我遇到的问题是前三个方块是有效的,而后四个方块应该是无效的。但是我的代码一直为我打印的是
Valid
Valid
Valid
Valid
Valid
Invalid
Valid
有人可以告诉我哪里搞砸了吗?我是 python 的新手,我已经盯着它看了好几个小时试图理解它。
我的版本没有将项目拆分成行
data = '''4 3 8 9 5 1 2 7 6
8 3 4 1 5 9 6 7 2
6 1 8 7 5 3 2 9 4
6 9 8 7 5 3 2 1 4
6 1 8 7 5 3 2 1 4
6 1 3 2 9 4 8 7 5
5 5 5 5 5 5 5 5 5'''
def main():
for line in data.split("\n"):
# create list with all numbers
items = list(map(int, line.split()))
print(is_magic(items))
def is_magic(items):
# --- dups ---
#print('dups')
#print(len(set(items)) == 9)
#for x in range(1, 10):
# print(x, x in items)
if len(set(items)) != 9:
return 'Invalid'
# --- rows ---
#print('rows')
for x in range(0, 9, 3):
l = items[x:x+3]
#print(l, sum(l) == 15)
if sum(l) != 15:
return 'Invalid'
# --- cols ---
#print('cols')
for x in range(3):
l = [items[x], items[x+3], items[x+6]]
#print(l, sum(l) == 15)
if sum(l) != 15:
return 'Invalid'
# --- diags ---
#print('diags')
l = [items[0], items[4], items[8]]
#print(l, sum(l) == 15)
if sum(l) != 15:
return 'Invalid'
l = [items[2], items[4], items[6]]
#print(l, sum(l) == 15)
if sum(l) != 15:
return 'Invalid'
# --- OK ---
return 'Valid'
main()
我不得不进行一些重大更改,但您的 checkDupe 方法似乎无法正常工作。您也只检查了一个对角线而不是两个。另外,请注意,不是使用 check1 变量保存答案是否有效,而是简单地 returns 'Invalid' 如果有任何错误,这通常会使代码更清晰并大大简化问题。如果永远不会返回 'Invalid',那么该方法只是 returns 'Valid' 最后。
def main():
for line in open("Magic Square Input.txt"):
items = line.split(" ")
items = [int(x) for x in items]
result = [items[0:3], items[3:6], items[6:9]]
print isMagic(result)
def isMagic(result):
# check duplicates
if(checkDupe(result) == 'Invalid'):
return 'Invalid'
# diagonals
if sum (result[y][y] for y in range(3)) != 15:
return 'Invalid'
# other digonals
if sum (result[2 - y][2 - y] for y in range(3)) != 15:
return 'Invalid'
# rows and columns
for i in range(3):
if sum(result[i][y] for y in range(3)) != 15:
return 'Invalid'
if sum(result[x][i] for x in range(3)) != 15:
return 'Invalid'
return 'Valid'
def checkDupe(result):
for x in range(1,9):
if(not x in (result[0]+result[1]+result[2])):
return 'Invalid'
return 'Valid'
main()
为了帮助您,我应该开始说您的代码很难阅读。由于您是 Python 的新手,很快您就会发现 Python 的主要好处之一是其清晰的语法,这使得弄清楚一段代码在做什么变得非常容易。话虽这么说,我解决了你的问题,使用与你相同的逻辑,但使代码更具可读性并使用一些 Python 技巧使解决方案更短更清晰。
def main():
"""Open the file, parse the input and check if it is a magic cube"""
with open("Magic Square Input.txt") as f:
for line in f.readlines():
numbers = line.split(" ")
cube = [int(x) for x in numbers]
is_magic(cube)
def is_magic(cube):
"""Check if cube is magic.
There are two conditions that must be satisfied:
1 - There must not be any repetitions of the numbers
2 - All vertical/horizontal/diagonal sums must be 15
"""
if not dupe(cube) and check_sum(cube):
print ('Valid')
else:
print ('Invalid')
def dupe(cube):
"""Check if there are repetitions in the cube."""
if len(cube) == len(set(cube)):
return False
return True
def check_sum(cube):
"""Check if all vertical/horizontal/diagonal sums are 15"""
if vertical_check(cube) and horizontal_check(cube) and diagonal_check(cube):
return True
def vertical_check(cube):
if sum(cube[0:9:3]) == sum(cube[1:9:3]) == sum(cube[2:9:3]) == 15:
return True
return False
def horizontal_check(cube):
if sum(cube[0:3]) == sum(cube[3:6]) == sum(cube[6:9]) == 15:
return True
return False
def diagonal_check(cube):
if sum(cube[0:9:4]) == sum(cube[2:7:2]) == 15:
return True
return False
main()
希望您能从代码中的注释中理解解决方案。如果不是这种情况,请再次post这里。
如果你从一个平面列表开始,这个问题就更容易思考了:
[4, 3, 8, 9, 5, 1, 2, 7, 6]
然后算出您需要检查哪些索引。一共只有八个:
indexes = (
(0, 1, 2), (3, 4, 5), (6, 7, 8), # rows
(0, 3, 6), (1, 4, 7), (2, 5, 8), # cols
(0, 4, 8), (2, 4, 6), # diag
)
有了这个设置,检查功能变得非常简单:
def main():
for line in open('Magic Square Input.txt'):
square = [int(n) for n in line.split()]
if len(set(square)) != len(square):
print('Invalid: Duplicates')
else:
for idx in indexes:
if sum(square[i] for i in idx) != 15:
print('Invalid: Sum')
break
else:
print('Valid')
这里我创建了示例方法来解决这个问题。在这种方法中,我们维护以下列表
- lstAvailableNumbers:可用号码列表(在您的情况下为 1-9)
- lstTraversedNumbers:遍历的数字列表(一旦遍历一个项目,它就被移动到这个列表中)
- 重复号码列表(所有重复号码将添加到此列表)
- 重复号码索引(将存储重复号码的索引,以便用于替换不存在的号码
- 还return更换的费用
出于调试目的,我还添加了打印语句来检查不同列表的值
def createMagicSquare(s):
lstAvailableNumbers = list()
lstAvailableNumbers=[1,2,3,4,5,6,7,8,9]
lstTraversedNumbers=set()
lstDuplicateNumbers=list()
dictDuplicateNumberIndex = dict()
lstMissingNumbers=set()
cost=0
for item in range(len(s)):
for colItem in range(len(s[item])):
num= s[item][colItem]
#print('Print traversed number - ' )
#print(num)
#print(lstTraversedNumbers)
if(num in lstAvailableNumbers):
#print('Inside if condition for num in lstAvailableNumbers ' )
lstAvailableNumbers.remove(num)
#print(num)
if(num in lstTraversedNumbers):
#print('Inside if condition for num in lstTraversedNumbers ' )
#print(num)
lstDuplicateNumbers.append(num)
lstIndexPosition =[]
lstIndexPosition.append(item)
lstIndexPosition.append(colItem)
dictDuplicateNumberIndex[num]=lstIndexPosition
lstTraversedNumbers.add(num)
#print(lstTraversedNumbers)
else:
lstDuplicateNumbers.append(num)
lstIndexPosition =[]
lstIndexPosition.append(item)
lstIndexPosition.append(colItem)
dictDuplicateNumberIndex[num]=lstIndexPosition
i=0
#print("Available Numbers -")
#print(lstAvailableNumbers)
#print("Traversed Numbers -")
#print(lstTraversedNumbers)
#print("Duplicate Numbers -")
#print(lstDuplicateNumbers)
#print("Duplicate Number index -")
#print(dictDuplicateNumberIndex)
for item in lstAvailableNumbers:
itemToReplace= lstDuplicateNumbers[i]
value= dictDuplicateNumberIndex[itemToReplace]
s[value[0]][value[1]] = item
i+=1
cost += abs(itemToReplace - item)
#print(cost)
return cost
def magic_square(n):
num=(n*((n*n)+1))/2
print('\nThe Magic Number Is:-',num,'\n')
f=[]
for i in range(0,n):
a=[]
for j in range(0,n):
a.append(0)
f.append(a)
(x,i,p,q)=(n*n,1,int(n/2),n-1)
while x!=0:
if x==0:
(f[p][q],i,p,q,x)=(i,i+1,p-1,q+1,x-1)
continue
else:
if p==-1 and q==n:
p=0
q=n-2
if f[p][q]==0:
(f[p][q],i,p,q,x)=(i,i+1,p-1,q+1,x-1)
continue
else:
p=p+1
q=q-2
f[p][q]=i
i=i+1
p=p-1
q=q+1
x=x-1
continue
if p==-1:
p=n-1
if f[p][q]==0:
(f[p][q],i,p,q,x)=(i,i+1,p-1,q+1,x-1)
continue
else:
p=p+1
q=q-2
f[p][q]=i
i=i+1
p=p-1
q=q+1
x=x-1
continue
if q==n:
q=0
if f[p][q]==0:
(f[p][q],i,p,q,x)=(i,i+1,p-1,q+1,x-1)
continue
else:
p=p+1
q=q-2
f[p][q]=i
i=i+1
p=p-1
q=q+1
x=x-1
continue
else:
if f[p][q]==0:
(f[p][q],i,p,q,x)=(i,i+1,p-1,q+1,x-1)
continue
else:
p=p+1
q=q-2
f[p][q]=i
i=i+1
p=p-1
q=q+1
x=x-1
continue
for i in range(len(f)):
for j in range(len(f[i])):
print(f[i][j] ,end = " ")
print("\n")
输入
magic_square(5)
输出
神奇的数字是:- 65.0
9 3 22 16 15
2 21 20 14 8
25 19 13 7 1
18 12 6 5 24
11 10 4 23 17