该A010784序列的工作,并为顺序只包含数量有不同的数字。这是一个有限的数量。

我一直试图要做的就是找到了几个号码在这个序列的某些属性。
例如:6是一个不同的数量级为10。这可以找到如下:

  • 6x1=6
  • 6×2=12
  • 6x3=18
  • 6×4=24
  • 6×5=30
  • 6x6=36
  • 6x7=42
  • 6×8=48
  • 6×9=54
  • 6×10=60
  • 6x11=66(两个乱七八糟;这些都不是两个不同的数字。)

现在我试图在最高的数字,可用于几种程度的秩序。
让我们说的所有订单从1到20个。

我目前正在做的是循环从尽可能高的独特号码,这是9,876,543,210和最独特的数量级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
有帮助吗?

解决方案

肯定有更好的办法。你应该建立的数字底,即如果一些a1...ak(这些都是k位)不是数量级N因此,一个数字会出现两次在第一k数字的结果的任何被乘数2..N则也不是任何数量b1...bm a1...ak。这提供了一个明确快递归枚举的过程,因为它削减指数量的搜索空间的距离。细节留作一个锻炼。

再解释:

假定有一个程序

 magnitude(number_str)

计算幅度为数 number_str 代表在10-基础,以使该过程返回0 number_str 至少包含一个双人间发生的数字,如果1 number_str 拥有每个数字不同,但数乘以通过两种结果在一个数字发生多次,等等。

这个过程可以实现的条款的另外一个

 unique_digits(number_str)

这回真的,如果所有数字 number_str 都是独一无二的,否则错误的。

现在然后 magnitude 可以实施为

 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

现在这个 magnitude 过程可以改变一个 nocarry_magnitude 这改变了检查巧妙地:

 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

这个过程检查为多次发生的数字仅为许多最右边的数字(最低的一位数)的产品的循环,因为有数字在原来的输入。一个限制需要参数以确保程序终止,因为它可能是该过程在运行的一个无限的循环,否则。显然任何字符串 s 它认为,

 magnitude(s) <= nocarry_magnitude(s, M) for large M

例如,采取19号:

 19 * 1 = 19
 19 * 2 = 38
 19 * 3 = 57
 19 * 4 = 76
 19 * 5 = 95
 19 * 6 = 114 // magnitude("19") = 5
 19 * 7 = 133 // nocarry_magnitude("19", 100) = 6

什么我写了上述的简短说明的是,如果

 nocarry_magnitude(s, x) == k     for x > k

然后用于任何字符串获得通过postfixing s (分别表示这个的 x + s 下文),它坚持

 x : string of digits
 magnitude(x + s) <= nocarry_magnitude(x + s, m) <= nocarry_magnitude(s, m)
 when m >= magnitude(x + s)

第一不平等来从权利要求上述第二种是明显的定义 nocarry_magnitude.请注意,数量级(x+s) <=数量级(s)是一个非理在一般性例证

 magnitude( "56")  = 1  // 56 * 2 = 112
 magnitude("256")  = 12 // the first duplicate occurs at 3328

这是由于携带。 nocarry_magnitude 忽略了开展这就是为什么后缀的一串一直作为大nocarry级作任何的扩展它(向左,即较高的单位)。

现在然后你可以写一个显着快递过程,因为这对于寻找数字幅度至少M:

 search(str):
   if (str != ""):
     int n = nocarry_magnitude(str, M)
     if (n < M):
       return      # the optimization
     int k = magnitude(str)
     if (k >= M):
       store_answer(str)
   for d in ['1', '2', '3', '4', '5', '6', '7', '8', '9',
             '10', '20', '30', '40', '50', '60', '70', '80', '90']:
     search(d + str)

 search("")

这里有一个完整的Python执行情况(寻找级36):

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("")

和这里的一个运行,时间不超过一次;这找到答案'27'这似乎是独特的数量,提供的记录数量级36:

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

其他提示

这不仅仅是排列问题吗?对于给定的数量级M,您要做10cM。

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

您当然不需要全部检查并检查它们。只需设置一组并选择一个,然后选择另一个即可。更好的是,只需从头开始创建它们。首先执行以1开头的所有内容(10、12、13、14等),然后执行以2开头的所有内容,

您有两个问题:

1)遍历A010784序列。

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

2)计算数字的大小。

您可以使用以下代码段确定数字是否只有唯一的数字: 通用标签

如果您只是在寻找最高的数量,则可以削减一些分支机构。从6 x 11 = 66中,您还知道11的数量最多为5。一旦您知道数量大于等于5的更大数字,就可以跳过11。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top