• 【Python】一行代码打印八皇后问题所有解


    【Python】一行代码打印八皇后问题所有解

    起因

    群友们在群里聊天,其中一名群友在群里发了一张截图,如下:

    看到 Scala 这门语言可以一行代码打印八皇后问题所有解,我想知道 Python 是否也可以。

    (注1:上图中的代码不止一行,但是把换行符全部删掉依旧可以运行)

    (注2:上图中的代码只能打印一种解,是因为取的 next,稍微改改就能打印所有解,无需增加行数)

    问题

    按照国际象棋的规则,皇后可以攻击与之处在同一行或同一列或同一斜线上的棋子,八皇后问题研究的是如何将 8 个皇后放置在 8×8 的棋盘上,并且使皇后彼此之间不能相互攻击。

    解法

    既然有现成的答案,咱们就在它的基础上改一改吧:

    from itertools import combinations, permutations
    
    print('\n\n'.join(['\n'.join([' '.join(['皇' if j == k else '_' for k in range(8)]) for j in i]) for i in filter(lambda x: all([a + b != c + d and a + d != b + c for ((a, b), (c, d)) in combinations(enumerate(x), 2)]), permutations(range(8)))]))
    
    • 1
    • 2
    • 3

    输出:

    皇 _ _ _ _ _ _ _
    _ _ _ _ 皇 _ _ _
    _ _ _ _ _ _ _ 皇
    _ _ _ _ _ 皇 _ _
    _ _ 皇 _ _ _ _ _
    _ _ _ _ _ _ 皇 _
    _ 皇 _ _ _ _ _ _
    _ _ _ 皇 _ _ _ _
    
    皇 _ _ _ _ _ _ _
    _ _ _ _ _ 皇 _ _
    _ _ _ _ _ _ _ 皇
    _ _ 皇 _ _ _ _ _
    _ _ _ _ _ _ 皇 _
    _ _ _ 皇 _ _ _ _
    _ 皇 _ _ _ _ _ _
    _ _ _ _ 皇 _ _ _
    
    省略……
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    (注3:itertools 是 Python 内置模块,因此忽视 import 语句的话,确实是一行)

    总结

    首先,生成 0 到 7 的全排列,对于全排列中的每一种排列都可看作一个有 8 个 int 类型元素的 tuple,而全排列则是该 tuple 的 list,元素的值与下标分别作为皇后们的横纵坐标,保证了皇后们在同一行与同一列上唯一。

    接着,对每一种排列,将皇后们两两组合,在 lambda 函数中检测是否不处于同一条对角线上,若全部组合都通过判断则代表这是其中一种解,否则丢弃这种排列。

    最后,将所有解转换成文本打印出来,非常巧妙的一种解题方法。

    我们还可以拓展到 N 皇后问题,把代码中的 8 替换成 N 即可,在 N 不太大时仍然可以很好的运行,若 N 非常大,建议采用更高效的算法。

  • 相关阅读:
    [ROS]在VS Code下编写代码,汇总问题及解决办法
    第二篇------Virtual I/O Device (VIRTIO) Version 1.1
    一文看懂推荐系统:召回02:Swing 模型,和itemCF很相似,区别在于计算相似度的方法不一样
    【C++】容器string的构造函数和迭代器
    (学习日记)2022.8.12
    路由----router
    分布式/微服务---第九篇
    56个Python技巧,轻松掌握Python高效开发!可以收藏~
    Spring 源码学习笔记10——Spring AOP
    java 代理模式(静态代理、动态代理、JDK动态代理、CGLIB动态代理)详解
  • 原文地址:https://blog.csdn.net/tqydyqt/article/details/126756489