Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 过滤A010784序列的最快方法_Python_Algorithm_Filter_Oeis - Fatal编程技术网

Python 过滤A010784序列的最快方法

Python 过滤A010784序列的最快方法,python,algorithm,filter,oeis,Python,Algorithm,Filter,Oeis,OEIS的A010784序列仅包含具有不同数字的数字。这是一个有限的数量 我一直试图在这个序列中找到几个具有特定属性的数字。 例如:6是一个明显的10级数字。具体如下: 6x1=6 6x2=12 6x3=18 6x4=24 6x5=30 6x6=36 6x7=42 6x8=48 6x9=54 6x10=60 6 x 11=66(两个6;它们不是两个不同的数字。) 现在,我正在尝试几个数量级的最高数字。 假设从1到20的所有订单 我目前正在做的是从最高可能的不同数(9876543210)和最高

OEIS的A010784序列仅包含具有不同数字的数字。这是一个有限的数量

我一直试图在这个序列中找到几个具有特定属性的数字。
例如:6是一个明显的10级数字。具体如下:

  • 6x1=6
  • 6x2=12
  • 6x3=18
  • 6x4=24
  • 6x5=30
  • 6x6=36
  • 6x7=42
  • 6x8=48
  • 6x9=54
  • 6x10=60
  • 6 x 11=66(两个6;它们不是两个不同的数字。)
现在,我正在尝试几个数量级的最高数字。
假设从1到20的所有订单

我目前正在做的是从最高可能的不同数(9876543210)和最高唯一数(震级1)循环到一个非常低的数。
这种方法感觉效率极低。至少对我来说是这样

我很确定我遗漏了一些关于因子分解的东西,这些东西应该可以让事情变得更快

def unique_num(num):
    # Check whether number is unique.
    return Boolean

def unique_num_magnitude(num):
    # Check of which magnitude the unique number is
    return Integer

# Dictionary with the current highest values
# for each magnitude.
values = {1: 987654321...}

# Set limits
upper_limit = 9876543210
lower_limit = 1

for numbers in range(upper_limit, lower_limit, -1):
    unique = unique_num(num) # Boolean
    if (unique):
        magnitude = unique_num_magnitude(num)
        if (values[magnitude] < num):
            values[magnitude] = num
def unique_num(num):
#检查编号是否唯一。
返回布尔值
def唯一数量大小(num):
#检查唯一数字的大小
返回整数
#具有当前最高值的字典
#对于每个量级。
值={1:987654321…}
#设限
上限=9876543210
下限=1
对于范围内的数字(上限、下限,-1):
唯一=唯一数(num)#布尔值
如果(唯一):
震级=唯一震级(num)
如果(值[幅值]
这不只是一个排列问题吗?对于给定的震级
M
是否为10cM

例如,对于震级2,有多少种方法可以从0..9中选择2位?(实际上,它应该是1..9中的一个和0..9中的一个,其中第二个数字与第一个数字不匹配。)


你当然不需要把它们全部检查一遍。设置一个集合,选择一个,然后选择另一个。更好的是,从头开始创建它们。首先做所有以1开头的事情(10、12、13、14等),然后做所有以2开头的事情,等等。

这不只是一个排列问题吗?对于给定的震级
M
是否为10cM

例如,对于震级2,有多少种方法可以从0..9中选择2位?(实际上,它应该是1..9中的一个和0..9中的一个,其中第二个数字与第一个数字不匹配。)

你当然不需要把它们全部检查一遍。设置一个集合,选择一个,然后选择另一个。更好的是,从头开始创建它们。首先做以1开头的事情(10、12、13、14等),然后做以2开头的事情,等等。你有两个问题:

1) 在A010784序列上迭代

使用itertools.permutations生成连续的可能数字

2) 计算一个数字的大小

您可以通过以下代码片段确定数字是否只有唯一的数字:

def unique_num(x):
    return len(str(x)) == len(set(str(x))
你有两个问题:

1) 在A010784序列上迭代

使用itertools.permutations生成连续的可能数字

2) 计算一个数字的大小

您可以通过以下代码片段确定数字是否只有唯一的数字:

def unique_num(x):
    return len(str(x)) == len(set(str(x))

如果你只是在寻找最高的数字,你可以砍一些树枝。从
6x11=66
中,您还知道11的大小最多为5。一旦你知道了一个更高的数值,其大小>=5,你就可以跳过11。

如果你只是在寻找最高的数值,你可以剪切一些分支。从
6x11=66
中,您还知道11的大小最多为5。一旦你知道了一个更大的数字,其大小>=5,你就可以跳过11。

确定有更好的方法。您应该自下而上构建数字,即,如果数字a1…ak(这些是k位)的大小不是N,因此任何被乘数2…N的结果的前k位内都会出现两次数字,那么任何数字b1…bm a1…ak都不是。这提供了一个绝对更快的递归枚举过程,因为它减少了指数级的搜索空间。细节留给OP作为练习

详细解释:

假设有一个程序

 magnitude(number_str)
它计算以10为基数表示的数字的大小,因此,如果
number\u str
至少包含一个双精度数字,则过程返回0;如果
number\u str
每个数字都不同,则返回1,但将数字乘以2会导致数字多次出现,等等

此程序可以在另一个程序中执行

 unique_digits(number_str)
如果
number\u str
中的所有数字都是唯一的,则返回true,否则返回false

现在,
magnity
可以实现为

 magnitude(number_str):
   n = str_to_int(number_str)
   k = n
   i = 0
   while (unique_digits(int_to_str(k))):
     k = k + n
     i = i + 1
   return i
现在,此
幅值
程序可以更改为
nocarry\u幅值
,从而微妙地更改检查:

 nocarry_magnitude(number_str, limit):
   l = length(number_str)
   assert (l > 0)
   n = str_to_int(number_str)
   k = n
   i = 0
   while (unique_digits(right_substring(int_to_str(k), l))):
     k = k + n
     i = i + 1
     if (i == limit):
       break
   return i
此过程仅检查循环中产品最右边的数字(最低顺序数字)中多次出现的数字,其数量与原始输入中的数字数量相同。需要一个limit参数来确保过程终止,否则该过程可能在无限循环中运行。显然,对于任何字符串
s
,它都是这样的

 magnitude(s) <= nocarry_magnitude(s, M) for large M
 x : string of digits
 magnitude(x + s) <= nocarry_magnitude(x + s, m) <= nocarry_magnitude(s, m)
 when m >= magnitude(x + s)
我在上面的简短描述中写道,如果

 nocarry_magnitude(s, x) == k     for x > k
然后对于通过后固定
s
获得的任何字符串(用下面的
x+s
表示),它保持

 magnitude(s) <= nocarry_magnitude(s, M) for large M
 x : string of digits
 magnitude(x + s) <= nocarry_magnitude(x + s, m) <= nocarry_magnitude(s, m)
 when m >= magnitude(x + s)
这是由携带引起的
nocarry_magnity
忽略进位,这就是为什么字符串的后缀总是与它的任何扩展(向左,即高阶数字)一样大

现在,您可以编写一个更快的递归过程,用于搜索大小为l的数字
def unique_digits(s):
    r = (len(list(s)) == len(set(s)))
    return r

def magnitude(s):
    n = int(s)
    k = n
    assert n > 0
    i = 0
    while (unique_digits(str(k))):
        k = k + n
        i = i + 1
    return i

def nocarry_magnitude(s, limit):
    l = len(s)
    assert l > 0
    n = int(s)
    assert n > 0
    k = n
    i = 0
    while (unique_digits(str(k)[-l:])):
        k = k + n
        i = i + 1
        if (i >= limit):
            break
    return i

M = 36

def search(s):
    if (not(s == "")):
        n = nocarry_magnitude(s, M)
        if (n < M):
            return
        k = magnitude(s)
        if (k >= M):
            print "Answer: %s |" % s,
            i = int(s)
            k = i
            n = 1
            while (n <= M):
                print k,
                k = k + i
                n = n + 1
            print
    for d in ['1', '2', '3', '4', '5', '6', '7', '8', '9',
              '10', '20', '30', '40', '50', '60', '70', '80', '90']:
        search(d + s)

search("")
Answer: 27 | 27 54 81 108 135 162 189 216 243 270 297 324 351 378 405
             432 459 486 513 540 567 594 621 648 675 702 729 756 783
             810 837 864 891 918 945 972