ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

在KenKen拼图“乘法”域中查找所有可能的因素

2019-11-07 22:56:16  阅读:289  来源: 互联网

标签:prime-factoring partitioning python algorithm


KenKen拼图是一个拉丁方形,分为边缘连接的区域:单个单元格,同一行或同一列中的两个相邻单元格,以行或ell形式排列的三个单元格等.每个域都有一个标明目标的标签数字和单个算术运算(-* /),该运算将应用于域的单元格中的数字以产生目标数字. (如果域中只有一个单元格,则没有给出运算符,只有一个目标—平方将为您解决.如果运算符是-或/,则域中只有两个单元格.)难题在于(重新)构造与域的边界和标签一致的拉丁方. (我认为我一次看到了一个非唯一解决方案的困惑.)

单元格中的数字范围为1到拼图的宽度(高度);通常,拼图是一个侧面上有4到6个单元格,但可以考虑任意大小的拼图.已发布难题中的域(4×4或6×6)通常不超过5个单元格,但同样,这似乎不是硬性限制. (但是,如果难题只有一个领域,那么解决方案的数量就和该维度的拉丁方一样多…)

编写KenKen解算器的第一步是拥有可以在任何域中生成数字可能组合的例程,首先要忽略域的几何形状. (一个线性域,就像一个由三个单元格组成的行,在已解决的难题中不能有重复的数字,但是我们暂时忽略了这一点.)我已经能够编写一个Python函数来逐个处理加法标签:给它拼图的宽度,域中的像元数和目标总和,它会返回一个有效数字元组的列表,这些元组加到目标中.

我不知道乘法的情况.我可以得到一个字典,其中的键等于给定大小的拼图中给定大小的域中可达到的乘积,其值是包含给出乘积的因素的元组列表,但我无法解决这种情况例行程序,甚至不是一个坏程序.

将给定产品分解为素数似乎很容易,但是随后将素数列表划分为所需数量的因子会使我感到困惑. (我沉思了Knuth的TAOCP第4卷第3册,但是我还没有学会如何“增长”他的算法描述,所以我不知道他的集划分算法是否会作为起点.理解Knuth的描述可能是另一个问题!)

我很高兴为通用域和拼图大小预先计算“乘”式字典,只是将加载时间分配到开销上,但是这种方法似乎并不是处理一个侧面拼图100个单元的有效方法.域从2到50个单元格不等.

解决方法:

简化的目标:您需要枚举所有相乘在一起的整数组合,以形成一定的乘积,其中整数的数量是固定的.

为了解决这个问题,您所需要的只是对目标数进行素分解,然后使用组合方法从这些因子形成所有可能的子产品. (一旦您拥有所有可能的子产品,难题的其他一些约束也很容易包含,例如没有一个条目比max_entry大,并且您要使用固定数量的整数n_boxes_in_domain.)

例如,如果max_entry = 6,n_boxes_in_domain = 3,而target_number = 20:20产生(2,2,5);转到(2,2,5)和(1,4,5).

诀窍是形成所有可能的子产品,下面的代码执行此操作.它通过遍历形成所有可能的单对的因素,然后递归地进行操作,以给出所有单个或多个配对的所有可能的集合来工作. (这是效率低下的,但是即使数量很大,素数分解也很小):

def xgroup(items):
    L = len(items)
    for i in range(L-1):
        for j in range(1, L):
            temp = list(items)
            a = temp.pop(j)
            b = temp.pop(i)
            temp.insert(0, a*b)
            yield temp
            for x in xgroup(temp):
                yield x

def product_combos(max_entry, n_boxes, items):
    r = set()
    if len(items)<=n_boxes:
        r.add(tuple(items))
    for i in xgroup(items):
        x = i[:]
        x.sort()
        if x[-1]<=max_entry and len(x)<=n_boxes:
            r.add(tuple(x))
    r = [list(i) for i in r]
    r.sort()
    for i in r:
        while len(i)<n_boxes:
            i.insert(0, 1)
    return r

我将它留给您以生成主要因素,但这似乎适用于

max_entry=6, n_boxes=3, items=(2,2,5)
[2, 2, 5]
[1, 4, 5]

在更困难的情况下,例如target_number = 2106

max_entry=50, n_boxes=6, items=(2,3,3,3,3,13)
[2, 3, 3, 3, 3, 13]
[1, 2, 3, 3, 3, 39]
[1, 2, 3, 3, 9, 13]
[1, 1, 2, 3, 9, 39]
[1, 1, 2, 3, 13, 27]
[1, 1, 2, 9, 9, 13]
[1, 1, 1, 2, 27, 39]
[1, 3, 3, 3, 3, 26]
[1, 3, 3, 3, 6, 13]
[1, 1, 3, 3, 6, 39]
[1, 1, 3, 3, 9, 26]
[1, 1, 3, 3, 13, 18]
[1, 1, 3, 6, 9, 13]
[1, 1, 1, 3, 18, 39]
[1, 1, 1, 3, 26, 27]
[1, 1, 1, 6, 9, 39]
[1, 1, 1, 6, 13, 27]
[1, 1, 1, 9, 9, 26]
[1, 1, 1, 9, 13, 18]

标签:prime-factoring,partitioning,python,algorithm
来源: https://codeday.me/bug/20191107/2003731.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有