消除连续数字

时间:2019-06-04 21:06:29

标签: python

如果您的数字范围为1-49,可以选择6个数字,则将有近1400万个组合。使用当前的脚本,我目前仅剩下720万个组合。在剩余的720万个组合中,我要消除所有3、4、5、6,双和三连贯数字。 示例:

  • 连续3次:1、2、3,x,x,x
  • 连续4次:3、4、5、6,x,x
  • 连续5次:4、5、6、7、8,x
  • 连续6个:5、6、7、8、9、10
  • 两次连续分开:1、2、5、6、14、18
  • 三连冠:1、2、9、10、22、23

注意:还必须消除诸如1、2、12、13、14、15之类的组合,否则它们将与要消除双重和三重连续组合的规则相冲突。

我正在寻找720万个剩余组合中有多少个组合具有连续的零个数字(全部混合)和只有一对连续的双子。

谢谢!

import functools

_MIN_SUM     = 120
_MAX_SUM     = 180
_MIN_NUM     = 1
_MAX_NUM     = 49
_NUM_CHOICES = 6
_MIN_ODDS    = 2
_MAX_ODDS    = 4

@functools.lru_cache(maxsize=None)
def f(n, l, s = 0, odds = 0):
    if s > _MAX_SUM or odds > _MAX_ODDS:
        return 0
    if n == 0 :
        return int(s >= _MIN_SUM and odds >= _MIN_ODDS)
    return sum(f(n-1, i+1, s+i, odds + i % 2) for i in range(l, _MAX_NUM+1))


result = f(_NUM_CHOICES, _MIN_NUM)

print('Number of choices = {}'.format(result))

2 个答案:

答案 0 :(得分:0)

虽然我的回答应该起作用,但我认为有人可能能够提供更快的解决方案。

考虑以下代码:

not_allowed = []
for x in range(48):
    not_allowed.append([x, x+1, x+2])

# not_allowed = [ [0,1,2], [1,2,3], ... [11,12,13], ... [47,48,49] ]
my_numbers = [[1, 2, 5, 9, 11, 33], [1, 3, 7, 8, 9, 31], [12, 13, 14, 15, 23, 43]]
for x in my_numbers:
    for y in not_allowed:
        if set(y) <= set(x): # if [1,2,3] is a subset of [1,2,5,9,11,33], etc.
            # drop x

此代码将删除所有包含双连续号的实例,这是您真正需要检查的所有内容,因为三倍,四倍等均表示双连续。尝试实现这一点,让我知道它是如何工作的。

答案 1 :(得分:0)

最简单的方法可能是生成和过滤。我使用numpy尝试向量化尽可能多的向量:

np.subtract(combos[:, :-1], combos[:, 1:])

打破那条“魔术”线

  • 首先,我们从后五个项目中减去列表中的前五个项目,以获取它们之间的差异。我们使用itertools.combinations一次拍摄整个组合。请注意,np.abs(...)产生 sorted 组合,这取决于它们。
  • 接下来,我们采用这些差异的绝对值,以确保我们只查看带有1的数字之间的正距离。
  • 接下来,我们从此操作中获取 entire 数据集的指示,这些指示指示np.where(... == 1)[0](连续数字)与np.where之间的差异。请注意,np.bincount(...)返回一个元组,其中第一个项目是所有行,第二个项目是我们条件的所有对应列。这很重要,因为任何显示多次的行值都告诉我们该行中有多个连续数字!
  • 因此,我们用[5, 4, 4, 4, 3, 2, 1, 0]计算出每一行出现在结果中的次数,这将返回类似np.where(... <= 1)[0]的信息,指示组合数据集的每一行中有多少对连续。
  • 最后,我们仅使用'tags'抓取连续0或1个连续值的行号。

我正在返回的 way 组合比您似乎要显示的要多,但是我对此很有信心。一定要在评论中戳一下它,然后看看是否可以找到修复程序!

奖金,因为它们都是矢量化的,所以超级快!