鱼C论坛

 找回密码
 立即注册
查看: 6932|回复: 55

[技术交流] Python:每日一题 27(答题领鱼币)

[复制链接]
发表于 2017-4-13 19:14:07 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

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

215406s5nhq29vyz5ssvum.png

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


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

游客,如果您要查看本帖隐藏内容请回复




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

评分

参与人数 1贡献 +2 收起 理由
朝闻夕死 + 2 热爱鱼C^_^

查看全部评分

本帖被以下淘专辑推荐:

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2017-4-13 19:56:48 | 显示全部楼层
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-4-13 20:01:25 | 显示全部楼层
Number 1 :

[[2 7 6]
[9 5 1]
[4 3 8]]

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

[[2 9 4]
[7 5 3]
[6 1 8]]

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

[[4 3 8]
[9 5 1]
[2 7 6]]

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

[[4 9 2]
[3 5 7]
[8 1 6]]

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

[[6 1 8]
[7 5 3]
[2 9 4]]

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

[[6 7 2]
[1 5 9]
[8 3 4]]

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

[[8 1 6]
[3 5 7]
[4 9 2]]

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

[[8 3 4]
[1 5 9]
[6 7 2]]

--------------------
#!/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[0:3]) == sum(lst[3:6]) == sum(lst[6:9]) == sum(lst[0:9:3]) == sum(lst[1:9:3]) == sum(lst[2:9:3]) == sum(lst[0:9:4]) == sum(lst[2:7:2]) 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

评分

参与人数 1荣誉 +3 鱼币 +3 收起 理由
新手·ing + 3 + 3 支持楼主!

查看全部评分

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 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 [a]:
            continue
        for c in range(1, 10):
            if c in [a, b]:
                continue
            for d in range(1, 10):
                if d in [a, b, c]:
                    continue
                for e in range(1, 10):
                    if e in [a, b, c, d]:
                        continue
                    for f in range(1, 10):
                        if f in [a, b, c, d, e]:
                            continue
                        for g in range(1, 10):
                            if g in [a, b, c, d, e, f]:
                                continue
                            for h in range(1, 10):
                                if h in [a, b, c, d, e, f, g]:
                                    continue
                                for i in range(1, 10):
                                    if i in [a, b, c, d, e, f, g, h]:
                                        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
-----

评分

参与人数 1荣誉 +3 鱼币 +3 收起 理由
新手·ing + 3 + 3 支持楼主!

查看全部评分

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 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[0]+i[4]+i[8]==15 and i[2]+i[4]+i[6]==15 and i[0]+i[1]+i[2]==15 and i[0]+i[3]+i[6]==15:
        if i[1]+i[4]+i[7]==15 and i[3]+i[4]+i[5]==15:
            print i


[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]
只能想到这种简单的

评分

参与人数 1荣誉 +3 鱼币 +3 收起 理由
新手·ing + 3 + 3 支持楼主!

查看全部评分

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2017-4-13 21:58:18 | 显示全部楼层
@冬雪雪冬 还不来!
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-4-14 09:25:41 | 显示全部楼层
ooxx7788 发表于 2017-4-13 20:41
我就弄点简单粗暴的吧!
输出

厉害了,大叔
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

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

No.2
[2, 9, 4]
[7, 5, 3]
[6, 1, 8]

No.3
[4, 3, 8]
[9, 5, 1]
[2, 7, 6]

No.4
[4, 9, 2]
[3, 5, 7]
[8, 1, 6]

No.5
[6, 1, 8]
[7, 5, 3]
[2, 9, 4]

No.6
[6, 7, 2]
[1, 5, 9]
[8, 3, 4]

No.7
[8, 1, 6]
[3, 5, 7]
[4, 9, 2]

No.8
[8, 3, 4]
[1, 5, 9]
[6, 7, 2]

点评

我很赞同!: 5.0
我很赞同!: 5
厉害!  发表于 2017-4-14 17:39
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-4-14 11:36:01 | 显示全部楼层
学习学习。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 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([i, x, z])
    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[0]+m2[0]+m3[0]
                    u2 = m1[1]+m2[1]+m3[1]
                    u3 = m1[2]+m2[2]+m3[2]
                    i1 = m1[0]+m2[1]+m3[2]
                    i2 = m1[2]+m2[1]+m3[0]
                    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种组合

[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]

======

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

评分

参与人数 1荣誉 +3 鱼币 +3 收起 理由
新手·ing + 3 + 3 那也加分!

查看全部评分

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-4-16 18:04:03 | 显示全部楼层
看题。。。。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 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)

评分

参与人数 1荣誉 +3 鱼币 +3 收起 理由
新手·ing + 3 + 3 支持楼主!

查看全部评分

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 1 反对 0

使用道具 举报

发表于 2017-4-17 11:39:18 | 显示全部楼层
这个大家基本用的都是一样的方法,我业不会其他方法 就不来骗鱼币了
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-5-11 16:05:33 | 显示全部楼层
好难
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2017-6-11 17:52:22 | 显示全部楼层
本帖最后由 solomonxian 于 2017-6-11 17:53 编辑

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

def check(a):
    """传入九宫格(列表),判定是否破解"""
    #print("a=", a)
    if a[0]+a[1]+a[2] == a[3]+a[4]+a[5] == a[6]+a[7]+a[8]\
    == a[0]+a[3]+a[6] == a[1]+a[4]+a[7] == a[2]+a[5]+a[8]\
    == a[0]+a[4]+a[8] == a[2]+a[4]+a[6]:
        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 = [1,2,3,4,5,6,7,8,9]
permute(a1)
[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]
{'sudo': 362880}
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-6-16 16:53:50 | 显示全部楼层
感谢楼主
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-6-21 21:15:47 | 显示全部楼层
q
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 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[j]+i[j+3]+i[j+6]!=15 or i[j*3]+i[j*3+1]+i[j*3+2]!=15:
            p=False
            break
    if p:
        if i[0]+i[4]+i[8]==15 and i[2]+i[4]+i[6]==15:#判断对角线
            all.append(i)
#print(time.time()-t)
x=''#格式化输出
for i in all:
    for j in range(3):
        x+=str(i[j*3])+str(i[j*3+1])+str(i[j*3+2])+'\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
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-6-21 22:12:42 | 显示全部楼层
我觉得可以出一个题目:
给出20个(或者更多)的3*3的矩阵,判断哪些属于同一个类型,比比谁的代码效率快
比如本题的8个答案,可以通过水平翻转、垂直翻转、或者对角线翻转互相转换, 全部属于同一个类型
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-6-21 22:22:12 | 显示全部楼层
小锟 发表于 2017-4-13 21:58
只能想到这种简单的

简单的最高效!
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2025-1-16 13:52

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表