返回等分序列序列的第n个数字


20

0.定义

一个序列是一个数字的列表。
一个系列是数字列表的总和。自然数
集包含所有“大于零的非负整数”。自然数j除数(在这种情况下)是自然数i,因此j ÷ i也是自然数。

1.前言

一对夫妇在这个网站的其他问题提等分的概念,或自然数的约数的序列这是不到一个确定友好数涉及计算这些除数的和,称为等分和或等分序列。每个自然数都有自己的等分和,尽管数字的等分和的值不一定是该数字唯一的。(示例,每个质数的等分和均为1。)

2.挑战

给定一个自然数n,返回n等分和序列的第th个数字。从1的序列开始的序列中的前几个序列是:

{0, 1, 1, 3, 1, 6, 1, 7, 4, 8, 1, 16, 1, 10, 9, 15, 1, 21, 1, 22, 11, 14, 1, 36, 6, 16, 13}

串联起来,它们看起来像:

0113161748116110915121122111413661613

根据您的喜好,输入可以是零索引或一索引。解决方案必须是能够返回第10,000位数字(最多输入999910000)的程序或函数。最短的解决方案胜出。

3.测试案例

正确的输入输出对应包括但不限于以下各项:

   0 or     1    ->    0
   4 or     5    ->    1
  12 or    13    ->    6
9999 or 10000    ->    7

“或”之前的数字是0索引的;以下数字为1索引。
可根据要求提供其他测试用例。

4.参考

OEIS 列出了数字及其等分和。


2
顺便说一句,尼斯挑战。:)
Martin Ender

1
如果语言不能管理10k字符字符串?(例如可怕的Oracle SQL 4k限制),如果答案是语言限制,答案是否有效?
Giacomo Garabello '16

@MartinEnder,谢谢!并感谢您的链接;很有启发性。有没有什么可以解释如何用有限的语言来回答问题的?我什么也找不到,但是我知道那并不意味着它不存在。:)

我可能已经很胖了,但是该系列中的数字如何计算?
汤姆·卡彭特

@TomCarpenter:对于第一个元素,取小于1的所有除数,然后将它们加在一起。(1是1的唯一除数,因此第一个元素最终为零。)第二个元素,小于2的2的除数(只有1适用于此)。第三,除数为3(仍仅为1);等等。4的除数是{1,2},并且1 + 2 == 3,所以第四个元素是3。我也花了一段时间才弄清楚;)

Answers:


6

05AB1E14 11 10字节

在约15秒内计算n = 9999。码:

ÌL€Ñ€¨OJ¹è

说明:

Ì           # Increment implicit input by 2
 L          # Generate the list [1 .. input + 2]
  ۄ        # For each, get the divisors
    ۬      # For each, pop the last one out
      O     # Sum all the arrays in the array
       J    # Join them all together
        ¹è  # Get the nth element

使用CP-1252编码。在线尝试!


6

Mathematica,51个字节

Array[##&@@IntegerDigits[Tr@Divisors@#-#]&,#][[#]]&

一个未命名的函数,它接受并返回一个整数,并使用基于1的索引。10000立即处理输入。

说明

这是定义的非常简单的实现,它利用了第一个n除数之和总是足以确定第n个数字的事实。像往常一样,打高尔夫球的Mathematica的阅读顺序有点有趣:

Array[...&,#]...&

这将生成一个列表,其中列出了将左侧未命名函数应用于所有i1n包括的值的结果。

...Tr@Divisors@#-#...

我们从计算的除数开始i,将它们相加Tr并相减,i以便它只是小于的除数之和i

...IntegerDigits[...]...

这会将结果转换成其十进制数字的列表。

##&@@...

这样就删除了“列表”头,从而所有数字列表都自动连接到的结果中Array。有关如何更多信息##工程,请参阅“的序列参数”一节中的这篇文章

...[[#]]

最后,我们n从结果中选择第th个数字。


4

Brachylog,40个字节

:2-I,?:?:1yrc:Im.;0.
:1e:2f+.
>.>0,?:.%0

这是1索引的,大约需要0.15秒,对于则需要N = 10015秒N = 1000。我目前正在运行N = 10000,一旦运行结束,我将报告运行时间(如果我的估算正确,则大约需要8个小时)

编辑:通过修复Brachylog中过早的约束传播,现在(在3字节长的代码上)花费大约2.5几分钟,10000但返回out of global stack错误。

说明

  • 主要谓词: Input = N

    :2-I,                 I = N - 2
         ?:?:1y           Find the N first valid outputs of predicate 1 with input N
               rc         Reverse and concatenate into a single number
                 :Im.     Output is the Ith digit of that number
                     ;    Or (I strictly less than 0)
                      0.  Output is 0
    
  • 谓词1:计算除数之和

    :1e                   Get a number between N and 1
       :2f                Find all valid outputs of predicate 2 with that number as input
          +.              Output is the sum of those outputs
    
  • 谓词2:将输出与输入的除数统一

    >.>0,                 Output is a number between Input and 0
         ?:.%0            Input is divisible by Output
    

1
您可以使用该-G选项分配更多的全局堆栈。默认值为128M。您可以使用例如:swipl -G2G使用2 GO。

4

Pyth,26 21 20 15字节

@sm`sf!%dTtUdSh

在线尝试。 测试套件。

使用基于0的索引。该程序为O(n²),在我的2008年计算机上,在大约14分钟内完成了n = 9999。


复杂的除数搜索是怎么回事?f!%dTr1d短得多(但也慢一些)
Jakube '16

@Jakube糟糕,修改了20字节解决方案的错误版本。
PurkkaKoodari'7

f!%TYtUT是我以前拥有的
PurkkaKoodari

@Jakube我改了。它仍在运行n = 9999,现在已超过5分钟:\
PurkkaKoodari

4

果冻,13 11 10字节

感谢@Adnan提供2个字节,感谢@Dennis提供1个字节。

ÆDṖSDµ€Fị@

在线尝试!

使用基于1的索引。在2秒内在线完成n = 10000。


ÆDṖSDµ€Fị@保存一个字节。
丹尼斯

@Dennis如此适用于整个第一条链吗?
PurkkaKoodari'7

@ Pietu1998:是的,准确地说:通常,在解析时将应用于chain.pop() if chain else chains.pop()。新开始的链为空,因此将使用最后完成的链。
林恩

3

PHP,90个字节

0索引

<?php for(;strlen($s)<=$a=$argv[1];$s.=$n)for($n=0,$j=++$i;--$j;)$i%$j||$n+=$j;echo$s[$a];

绝对不是微妙的,或者根本没有巧妙的方法。
而且,像往常一样,会产生三个被忽略的通知。


3

J,34个字节

{[:;1<@":@(-~>:@#.~/.~&.q:)@+i.@>:

它是零索引的,并使用以下公式计算除数之和。

式

说明

{[:;1<@":@(-~>:@#.~/.~&.q:)@+i.@>:  Input: n
                                >:  Increment n
                             i.@    Create the range [0, 1, ..., n]
    1                       +       Add one to each to get [1, 2, ..., n+1]
          (               )@        For each value
                        q:            Get the prime factors
                   /.~&.              For each group of equal prime factors
                #.~                     Raise the first to the first power, the second
                                        squared and so on, and sum them
             >:@                        Increment that sum
                      &.q:            Reduce the groups using multiplication
           -~                         Subtract the initial value from that sum
       ":@                            Convert each to a string
     <@                               Box each
 [:;                                Unbox each and concatenate the strings
{                                   Select the character from that string at index n
                                    and return it

2

MATL16 15字节

:"@@q:\~fsV]vG)

索引基于1。

最后一个测试用例在联机编译器中超时,但是使用脱机编译器确实可以在15秒内给出正确的结果。

在线尝试!

:         % Take input n. Push [1 2 ... n]
"         % For each k in [1 2 ... n]
  @       %   Push k
  @q:     %   Push [1 2 ... k-1]
  \       %   Modulo. Zero values correspond to divisors
  ~f      %   Indices of zeros. These are the divisors
  s       %   Sum
  V       %   Convert to string
]         % End for each
v         % Concatenate all stack contents vertically
G)        % Take n-th digit. Implicitly display

2

Haskell,52个字节

(([1..]>>= \n->show$sum[m|m<-[1..n-1],mod n m<1])!!)

用法示例:(([1..]>>= \n->show$sum[m|m<-[1..n-1],mod n m<1])!!) 12-> 6

它是该定义的直接实现:foreach n总和是除数,然后将其转换为字符串。连接所有这些字符串,并在请求的索引处选择元素。Haskell的懒惰仅需要n从无限列表中取多少秒[1..]


1

Python 3.5、103 93 92字节:

R=range;A=lambda f:''.join([str(sum([j for j in R(1,i)if i/j%1==0]))for i in R(1,f+1)])[f-1]

帖子中描述的方法非常简单的实现。

在线尝试!(爱迪生)

在在线编译器分配的5秒钟内不能完全完成输入10000,但是对于我的机器,它在大约8.5秒钟内就可以完成相同的输入。


1

八度,71字节

此仅八度音。它在MATLAB中不起作用。创建了一个虚拟函数,该函数可用于1索引数字。它可能可以进一步简化。今天晚上去看看。

@(x)c((c=num2str(arrayfun(@(n)sum(b(~rem(n,b=(1:n-1)))),1:x)))~=' ')(x)

您可以在此处尝试在线。

只需运行上面的命令,以a=或前缀(只是为了可以多次使用),然后再执行a(10000)或任何命令即可。计算第10000位数字为7大约需要7秒。


1

Java 8,220字节

import java.util.stream.IntStream;
char a(int n){return IntStream.range(1,n+2).map(i->IntStream.range(1,i).filter(k->i%k==0).sum()).mapToObj(Integer::toString).collect(java.util.stream.Collectors.joining("")).charAt(n);}

好吧,至少很快。平均需要0.3秒才能在我的计算机上获得第9999/10000个元素。它仅生成与指定索引一样多的等分和。这意味着在大多数情况下,该字符串将比您的索引稍长,因为某些等分和具有2个或多个数字,但是在大多数情况下,它仅生成所需长度的字符串。

用法:

public static void main(String[] args) {
    System.out.println(a(0));
    System.out.println(a(4));
    System.out.println(a(12));
    System.out.println(a(9999));
}

取消高尔夫:

public static void main(String[] args) {
    System.out.println(all(0));
    System.out.println(all(4));
    System.out.println(all(12));
    System.out.println(all(9999));
}

static int aliquotSum(int n) {
    return IntStream.range(1, n).filter(k -> n % k == 0).sum();
}

static IntStream sums(int n) {
    return IntStream.range(1, n + 2).map(i -> aliquotSum(i));
}

static String arraycat(IntStream a) {
    return a.mapToObj(Integer::toString).collect(java.util.stream.Collectors.joining(""));
}

static char all(int index) {
    return arraycat(sums(index)).charAt(index);
}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.