你迷路了吗?


31

您的任务是实现整数序列A130826

一个Ñ是最小的正整数,使得一个ñ - N的是整个多3和的约数的数量的两倍(一个ñ - N)/ 3给出了Ñ 术语在由弗拉菲乌斯产生的序列的第一个差异约瑟夫斯筛。

迷路了吗?好吧,这实际上很容易。

所述flavius约瑟夫筛定义如下的整数序列。

  1. 从正整数序列开始,设置k = 2

  2. 除去每ķ 序列的整数,开始与ķ

  3. 递增k并返回到步骤2。

f n是永不删除的n 整数(1索引)。

如果-像往常一样- σ 0(k)的表示整数的正除数的数ķ,我们可以定义一个Ñ为最小的正整数,使得0((一个ñ - N)/ 3)= F n + 1个 -f n

挑战

写一个程序或函数,它接受一个正整数Ñ作为输入,并打印或返回一个ñ

适用标准规则。愿最短的代码获胜!

工作的例子

如果我们删除正整数的第二个元素,则剩下

 1  3  5  7  9 11 13 15 17 19 21 23 25 27 29 31 33 35 37 39 ...

除去剩余的每三个元素后,我们得到

 1  3  7  9 13 15 19 21 25 27 31 33 37 39 ...

现在,删除第四个元素,然后删除第五个元素,然后删除第六个元素

 1  3  7 13 15 19 25 27 31 37 39 ...
 1  3  7 13 19 25 27 31 39 ...
 1  3  7 13 19 27 31 39 ...
 1  3  7 13 19 27 39 ...

最后一行显示项f 1f 7

这些术语的连续元素的区别是

 2  4  6  6  8 12

将这些前向差异除以2,我们得到

 1  2  3  3  4  6 

这些是目标除数计数。

  • 4是第一个整数ķ使得σ 0((K - 1)/ 3)= 1。事实上,σ 0(1)= 1
  • 8是第一个整数ķ使得σ 0((K - 2)/ 3)= 2。事实上,σ 0(2)= 2
  • 15是第一个整数ķ使得σ 0((K - 3)/ 3)= 3。事实上,σ 0(4)= 3
  • 16是第一个整数ķ使得σ 0((K - 4)/ 3)= 3。事实上,σ 0(4)= 3
  • 23是第一个整数ķ使得σ 0((K - 5)/ 3)= 4。事实上,σ 0(6)= 4
  • 42是第一个整数ķ使得σ 0((K - 6)/ 3)= 6。事实上,σ 0(12)= 6

测试用例

   n     a(n)

   1        4
   2        8
   3       15
   4       16
   5       23
   6       42
   7       55
   8      200
   9       81
  10       46
  11      119
  12      192
  13      205
  14   196622
  15    12303
  16       88
  17      449
  18      558
  19      127
  20     1748
  21   786453
  22       58
  23     2183
  24     3096
  25     1105
  26   786458
  27 12582939
  28      568
  29     2189
  30     2730

14
OEIS上的关键字:dumb(“不重要的序列”)。
orlp

15
哑?它可以拯救世界!
丹尼斯

3
那个双关语...
Mego

Answers:


7

果冻,30 29 27 25字节

感谢@Dennis通知我about Æd,节省了2个字节,另外2个字节用于合并两个链。

RUð÷‘Ċ×µ/
‘Ç_ÇH0Æd=¥1#×3+

在线尝试!

这可能是我与Jelly玩过的最有趣的事情。我从第二行开始,它使用OEIS上的公式从n计算f n,并且非常漂亮。

说明

RUð÷'Ċ×µ / Helper链接来计算F n。参数:n
R获取数字[1..n]
 U反转
        /按“舍入至下2个倍数”减少:
   ÷除以下一个数字
    '跳过倍数的增量
     ĊCeil(向上舍入)
      ×乘以下一个数字

'Ç_ÇH0Æd=¥1#×3 +主链接。参数:n
增量n
 Ç计算F n + 
   1Ç计算F n
  _ 减去
    H除以2
     0 1#从0开始,找到(a n -n)/ 3 的第一个候选
                   满足...
      AEDσ 0((一Ñ -n)/ 3)
        = =(F n + 1 -F n)/ 2
            ×3乘以3可将(a n -n)/ 3变成n -n
              +加n将n -n变成n

3

Python 2中121个 119 118字节

n=input();r=range(1,4**n);d=s,=r*1,
for k in r:del s[k::k+1];d+=sum(k%j<1for j in r)*2,
print d.index(s[n]-s[n-1])*3+n

运行时间应大致为O(16 n,内存使用量为O(4 n。替换4**n5<<n-我认为足够了-可以大大改善这一点,但是我不相信它适用于任意大的n值。

在线尝试!

渐近行为和的上限ñ

定义b Ñ作为(一个ñ - N)/ 3,即,最小的正整数ķ使得σ 0(K)=½(F n + 1个 - ˚F Ñ

作为对OEIS页,指出˚F Ñ〜¼πn 2,所以˚F N + 1 - ˚F Ñ〜¼π第(n + 1)2 - ¼πn 2 =¼π(2N + 1)〜½πn

这样,½(f n + 1 -f n)〜¼πn。如果实际的数是素数p,以最小的正整数p除数是2 P-1 ,所以b Ñ可以近似为2 Ç Ñ,其中Ç Ñ〜¼πn

因此b Ñ <4 Ñ将保持足够大的Ñ,鉴于2 ¼πn <2 Ñ <<(2 Ñ2 = 4 Ñ,我确信没有反例。

怎么运行的

n=input();r=range(1,4**n);d=s,=r*1,

这为我们的迭代过程设置了一些参考。

  • n是用户输入:正整数。

  • r是列表[1,...,4 n -1]

  • sr的副本。

    重复一次列表r*1会创建一个浅表副本,因此修改s不会修改r

  • d被初始化为元组(多个)

    这个第一个值并不重要。所有其他将保留正整数的除数计数。

for k in r:del s[k::k+1];d+=sum(k%j<1for j in r)*2,

对于从14 n -1的每个整数k,我们执行以下操作。

  • del s[k::k+1]接受s中从第(k + 1)开始的(k + 1)整数,并从s中删除该切片。

    这是将Flavius Josephus筛子的初始间隔存储为s的直接方法。它将计算比所需的n +1个初始项更多的内容,但是使用单个for循环来同时更新sd可以节省一些字节。

  • d+=sum(k%j<1for j in r)*2,计数如何的许多元素ř鸿沟ķ均匀并追加0(k)的d

    由于d被作为一个单元组初始化,0(K)存储在索引ķ

print d.index(s[n]-s[n-1])*3+n

此认定的所述第一索引˚F N + 1 - ˚F Ñd,这是最小的ķ使得0(K)= F n + 1个 - ˚F Ñ,然后计算一个Ñ3K + 1和输出结果。


2

爪哇8, 336305303287283个 279字节

多亏了Kritixi Lithos,删除了57个字节

打高尔夫球

class f{static int g(int s,int N){return s<1?N+1:g(s-1,N+N/s);}static int h(int k){int u=0,t=1,i;for(;u!=(g(k,k)-g(k,k-1))/2;t++)for(i=1,u=0;i<=t;)if(t%i++<1)u++;return 3*t-3+k;}public static void main(String[]a){System.out.print(h(new java.util.Scanner(System.in).nextInt()));}}

不打高尔夫球

class f {
    static int g(int s,int N){return s < 1 ? N + 1 : g(s - 1, N + N / s);}

    static int h(int k) {
        int u = 0, t = 1, i;
        // get the first number with v divisors
        while(u != (g(k, k) - g(k, k - 1))/2){
            u = 0;
            for (i = 1; i <= t; i++)
                if (t % i < 1) u++;
            t++;
        }
        // 3*(t-1)+k = 3*t+k-3
        return 3 * t + k - 3;
    }

    public static void main(String[] a) {
        System.out.print(h(new java.util.Scanner(System.in).nextInt()));
    }
}

我认为将命令行参数解析int为比比使用短java.util.Scanner。但是,即使您正在使用扫描仪,你可以做System.out.print(h(new java.util.Scanner().nextInt())),并删除之前的线
Kritixi LITHOS

@KritixiLithos thx,现在解决……
Bobas_Pett

在内部int h(),您可以将其更改为int v = (g(k,k)-g(k,k-1))/2,u = 0,t = 1;。您可以将if语句(位于for循环内)从if(t%i==0)更改为if(t%i<1)
Kritixi Lithos 16/12/27

此外,你可以改变你的函数g使用的三元运营商像回到return s==0?N+1:g(s-1,N+N/2)-ish
Kritixi LITHOS

2
@KritixiLithos哈哈,您现在应该将其作为您自己的单独解决方案发布
Bobas_Pett

1

数学,130个 116 106 103字节

3Catch@Do[f=#2⌈#/#2+1⌉&~Fold~Reverse@Range@#&;If[Tr[2+0Divisors@k]==f[#+1]-f@#,Throw@k],{k,∞}]+#&

要么

3Catch@Do[f=#2⌈#/#2+1⌉&~Fold~Reverse@Range@#&;If[2DivisorSum[k,1&]==f[#+1]-f@#,Throw@k],{k,∞}]+#&

最终几乎与@ Pietu1998的Jelly代码相同...

说明

Catch@

Catch无论是Throw-ed(抛出)。

Do[ ... ,{k,∞}]

无限循环; k1每次迭代开始并递增。

f= ...

分配f

Reverse@Range@#

查找{1, 2, ... , n}。扭转它。

#2⌈#/#2+1⌉&

输出ceil(n1 / n2 +1)* n2的函数

f= ... ~Fold~ ... &

分配f一个函数,将上述函数从上述两个步骤递归地应用到列表,将每个输出用作第一个输入,并将列表的每个元素用作第二个输入。初始的“输出”(第一个输入)是列表的第一个元素。

Tr[2+0Divisors@k]==f[#+1]-f@#

检查的除数​​的两倍是否k等于f(n + 1)-f(n)。

If[ ... ,Throw@k]

如果条件为TrueThrow则的值k。如果没有,继续循环。

3 ... +#&

将输出乘以3并加n。

130字节版本

Catch@Do[s=#+1;a=k-#;If[3∣a&&2DivisorSigma[0,a/3]==Differences[Nest[i=1;Drop[#,++i;;;;i]&,Range[s^2],s]][[#]],Throw@k],{k,∞}]&

1

Perl 6的154个 149 136 107字节

->\n{n+3*first ->\o{([-] ->\m{m??&?BLOCK(m-1).rotor(m+0=>1).flat!!1..*}(n)[n,n-1])/2==grep o%%*,1..o},^Inf}

取消高尔夫:

-> \n {                    # Anonymous sub taking argument n
  n + 3 * first -> \o {    # n plus thrice the first integer satisfying:
    (                      #
      [-]                  #
      -> \m {              # Compute nth sieve iteration:
        m                  # If m is nonzero,
          ?? &?BLOCK(m-1).rotor(m+0=>1).flat # then recurse and remove every (m+1)-th element;
          !! 1..*          # the base case is all of the positive integers
      }                    #
      (n)                  # Get the nth sieve
      [n,n-1]              # Get the difference between the nth and (n-1)th elements (via the [-] reduction operator above)
    ) / 2                  # and divide by 2;
    ==                     # We want the number that equals
    grep o %% *, 1..o      # the number of divisors of o.
  }
  ,^Inf
}

1

05AB1E35 34 39个字节

1Qi4ë[N3*¹+NÑg·¹D>‚vyy<LRvy/>îy*}}‚Æ(Q#

看起来很糟糕,运行时性能也很糟糕。输入产生小数值需要几秒钟。不要尝试14之类的数字;最终会找到结果,但要花很多时间。

说明

它作为2个顺序调用的程序工作。第一个计算˚F N + 1 - ˚F Ñ和第二一者来确定一个Ñ根据其定义,使用暴力破解的方法。

F n + 1 -F n会为每次迭代求值,即使它是循环不变的。它使代码时间效率低下,但使代码更短。

在线尝试!


我不确定我是否理解。为什么不能计算65,536以上的筛子?
丹尼斯

这是因为它会生成0到65536(žHL)之间的所有整数,然后过滤掉不满足筛分约束的值。我认为应该使用完全不同的方法完全重写该程序的第一部分,以使其可打高尔夫球。
2016年

除非有限制(例如固定宽度的整数)阻止您这样做,否则在给定足够的时间和内存的情况下,答案应适用于任何输入。
丹尼斯

这就是为什么我想出了另一种筛分算法。它可能是可打高尔夫球的,但我在05AB1E中没有发现更好的选择。但是,存在一个反例given enough time and memory,因为我已经看到其他问题的答案很慢,几乎无法说出它们是否产生了正确的输出。因此,我将筛分计算放在了循环之外,这花了我2个字节。
2016年

无需提高代码效率。您可以将“打高尔夫球/慢速”实施作为提交的内容,并包括“快/长”的注释。恐怕我必须坚持动态限制,即使它花费一个字节。
丹尼斯
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.