新手·ing 发表于 2017-4-13 19:14:07

Python:每日一题 27(答题领鱼币)

九宫格即把1~9的数字填到3行3列的表格中,使每行每列和对角线的数字之和都相等,例如:



请编程做出所有的排列可能。

感谢@冬雪雪冬 提供的题目,大家有好题目也要贡献出来,有鱼币奖励

**** Hidden Message *****



欢迎小伙伴们,一起答题!
如果你有能力,欢迎加入我们!
已经上车老司机:@冬雪雪冬 @lumber2388779 @ooxx7788 @gopythoner
{:10_298:} 点我走上人生巅峰{:10_298:}
{:10_248:} 帅的人都上车了,而丑的人还在犹豫{:10_248:}

新手·ing 发表于 2017-4-13 19:56:48

@冬雪雪冬 @lumber2388779 @ooxx7788 @gopythoner
来来来~

jerryxjr1220 发表于 2017-4-13 20:01:25

Number 1 :

[

]

--------------------
Number 2 :

[

]

--------------------
Number 3 :

[

]

--------------------
Number 4 :

[

]

--------------------
Number 5 :

[

]

--------------------
Number 6 :

[

]

--------------------
Number 7 :

[

]

--------------------
Number 8 :

[

]

--------------------

#!/usr/bin/env python2
# -*- coding: utf-8 -*-
"""
Created on Thu Apr 13 19:40:58 2017

@author: jerry_xu
"""
import numpy
from itertools import permutations as pt
comb = pt(range(1,10), 9)

def check(lst):
    return True if sum(lst) == sum(lst) == sum(lst) == sum(lst) == sum(lst) == sum(lst) == sum(lst) == sum(lst) else False

i = 0
for each in comb:
    if check(each):
      c = numpy.array(each)
      c = c.reshape((3, 3))
      i += 1
      print 'Number %d :' % i
      print ''
      print c
      print ''
      print '-' * 20

ooxx7788 发表于 2017-4-13 20:41:58

本帖最后由 ooxx7788 于 2017-4-13 20:43 编辑

for a in range(1, 10):
    for b in range(1, 10):
      if b in :
            continue
      for c in range(1, 10):
            if c in :
                continue
            for d in range(1, 10):
                if d in :
                  continue
                for e in range(1, 10):
                  if e in :
                        continue
                  for f in range(1, 10):
                        if f in :
                            continue
                        for g in range(1, 10):
                            if g in :
                              continue
                            for h in range(1, 10):
                              if h in :
                                    continue
                              for i in range(1, 10):
                                    if i in :
                                        continue
                                    elif a + b + c == d + e + f == g + h + i == a + d + g == b + e + h == c + f + i == a + e + i == c + e + g:
                                        print('-'*5)
                                        print(a, b, c)
                                        print(d, e, f)
                                        print(g, h, i)
print('-'*5)


我就弄点简单粗暴的吧!
输出
-----
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
-----

小锟 发表于 2017-4-13 21:58:01

import itertools as t
a = t.permutations(range(1,10),9)
for i in a:
    i = list(i)
    if i+i+i==15 and i+i+i==15 and i+i+i==15 and i+i+i==15:
      if i+i+i==15 and i+i+i==15:
            print i












只能想到这种简单的{:9_240:}

新手·ing 发表于 2017-4-13 21:58:18

@冬雪雪冬 还不来!

sunnychou 发表于 2017-4-14 09:25:41

ooxx7788 发表于 2017-4-13 20:41
我就弄点简单粗暴的吧!
输出

厉害了,大叔{:10_254:}

冬雪雪冬 发表于 2017-4-14 09:46:28

说一下我的思路,使用穷举法,但做些优化。
1. 位置肯定是5。
2. 每行列对角线之后是15
所以将1~9除了5以外排列出4个,将其填到,,,位置,将10减去这个数排在相对的位置,如填1,则填9,当然这4个数要去除相互直接的和为10的。
再判断,之和为15且,,之和为15就可得到答案了。
这里为了方便没有采用二维列表,只用以为列表代替了。
import itertools
count = 1
for i in itertools.permutations((1, 2, 3, 4, 6 , 7, 8, 9), 4):
    list1 = * 9
    list1 = 5
    if len(set() & set(i)) == 0:
      for j in range(4):
            list1 = i
      for j in range(4):
            list1 = 10 - i
      if list1 + list1 + list1 == 15 and list1 + list1 + list1 == 15:
            print('No.%d'%count)
            for m in range(3):
                print(list1)
            print()
            count += 1
No.1




No.2




No.3




No.4




No.5




No.6




No.7




No.8



zhhmms 发表于 2017-4-14 11:36:01

学习学习。

dori233 发表于 2017-4-14 22:47:23

本帖最后由 dori233 于 2017-4-15 14:58 编辑


# -*- coding: utf-8 -*-

def sum15():
    """先把相加等于15的组合找出来,1~9数字不能重复出现"""
    mun_list = []
    for i in range(1, 10):
      for x in range(1, 10):
            for z in range(1, 10):
                if (i+x+z == 15) and (len({i, x, z}) == 3):
                  mun_list.append()
    return mun_list


def ruled_out(mun_list):
    """组合数字变成横竖斜对角都相加等于15的九宫格,组合的可能性,添加到列表中"""
    ruled_list = []
    for m1 in mun_list:
      for m2 in mun_list:
            for m3 in mun_list:
                if len(set(m1) | set(m2) | set(m3)) == 9:
                  u1 = m1+m2+m3
                  u2 = m1+m2+m3
                  u3 = m1+m2+m3
                  i1 = m1+m2+m3
                  i2 = m1+m2+m3
                  if len({u1, u2, u3, i1, i2}) == 1:
                        # 生成了一个带格式的字符串,方便日后打印
                        ruled_list.append('\n\n%s\n%s\n%s\n\n======' % (m1, m2, m3))
    return ruled_list


# 开始工作
result_list = ruled_out(sum15())
file = open('九宫格结果.txt', 'w')
file.write('一共有%d种组合' % len(result_list))
file.writelines(result_list)
file.close()


输出结果: 九宫格结果.txt:↓
一共有8种组合





======





======





======





======





======





======





======





======

昨晚那个程序太不效率了,小改了一下,依然是用set的思路去解决.

老甲鱼与小甲鱼 发表于 2017-4-16 18:04:03

看题。。。。

ooxx7788 发表于 2017-4-16 20:56:46

其实我是看jerry用了itertools了,才选择用个暴力的方法。
用itertools生成全排列的情况下,不考虑排版的情况下,几乎可以写出一行解决的代码。

from itertools import permutations as pt

for each in pt(range(1, 10), 9):
    a, b, c, d, e, f, g, h, i = each
    if a + b + c == d + e + f == g + h + i == a + d + g == b + e + h == c + f + i == a + e + i == c + e + g:
      print('-' * 7, '\n', a, b, c, '\n', d, e, f, '\n', g, h, i)
print('-' * 7)

余欲渔 发表于 2017-4-17 11:39:18

这个大家基本用的都是一样的方法,我业不会其他方法 就不来骗鱼币了

willLin 发表于 2017-5-11 16:05:33

好难

solomonxian 发表于 2017-6-11 17:52:22

本帖最后由 solomonxian 于 2017-6-11 17:53 编辑

9! 种排列吗, 符合的就8种
# 只有把 5 放中间一种类型解法,并且和等于15,不过还是暴力破解看看吧

def check(a):
    """传入九宫格(列表),判定是否破解"""
    #print("a=", a)
    if a+a+a == a+a+a == a+a+a\
    == a+a+a == a+a+a == a+a+a\
    == a+a+a == a+a+a:
      print(a)

def permute(a_list):
    """闭包处理, 保存了使用方法 for 循环和两个环境变量"""
   
    outer = []# 记录每个九宫格排列结果
    counted = {"sudo": 0}# 计数器
    def extract(n,i):
      """递归处理, 从列表 n 中抽一个出来,剩余的元素再排列"""
      outer.append(i)
      if len(n) == 1:
            counted['sudo'] += 1
            check(outer)
      else:
            m = n[:]   # 复制品用于安全迭代
            m.remove(i)
            for j in m:
                extract(m, j)
      # 删去本次循环增加的 i ,保持9个元素
      outer.remove(i)
               
    for num in a_list:
      extract(a_list, num)
    print(counted)
   
a1 =
permute(a1)









{'sudo': 362880}

老司机带带我哟 发表于 2017-6-16 16:53:50

感谢楼主

Andrea 发表于 2017-6-21 21:15:47

q

达锅 发表于 2017-6-21 22:07:40


from itertools import permutations as qpl
#import time

#t=time.time()
comb=qpl(range(1,10),9)

all=[]
for i in comb:
    p=True
    for j in range(3):#判断横竖
      if i+i+i!=15 or i+i+i!=15:
            p=False
            break
    if p:
      if i+i+i==15 and i+i+i==15:#判断对角线
            all.append(i)
#print(time.time()-t)
x=''#格式化输出
for i in all:
    for j in range(3):
      x+=str(i)+str(i)+str(i)+'\n'
    x+='\n'
print(x)


实际上是同一个
276
951
438

294
753
618

438
951
276

492
357
816

618
753
294

672
159
834

816
357
492

834
159
672

达锅 发表于 2017-6-21 22:12:42

我觉得可以出一个题目:
给出20个(或者更多)的3*3的矩阵,判断哪些属于同一个类型,比比谁的代码效率快
比如本题的8个答案,可以通过水平翻转、垂直翻转、或者对角线翻转互相转换, 全部属于同一个类型

达锅 发表于 2017-6-21 22:22:12

小锟 发表于 2017-4-13 21:58
只能想到这种简单的

简单的最高效!{:9_236:}
页: [1] 2 3
查看完整版本: Python:每日一题 27(答题领鱼币)