纯度数


27

今天,我们来看一个与Collat​​z函数f有关的序列a

在此处输入图片说明

我们称形式为z,f(z),f(f(z)),...序列Collat​​z序列

我们序列中的第一个数字a(1)0。在反复施加f的情况下,它落入一个循环0→0→…

我们尚未看到的最小数字是1,使a(2)= 1。在重复使用f的情况下,它会进入一个循环1→4→2→1→…

现在我们已经在上面的循环中看到了数字2,所以下一个最小的数字是a(3)= 3,属于循环3→10→5→16→8→4→2→1→4→2→1 →…

在以上所有循环中,我们已经看到了45,因此下一个数字是a(4)= 6

现在,您应该明白了。一(N)是不是为所有任何在Collat​​z序列的一部分的最小数目一(1),...,A(N - 1)

编写一个给定正整数n返回a(n)的程序或函数。以字节为单位的最短代码获胜。


测试用例:

1  -> 0
2  -> 1
3  -> 3
4  -> 6
5  -> 7
6  -> 9
7  -> 12
8  -> 15
9  -> 18
10 -> 19
50 -> 114

(这是OEIS序列A061641。)


1
强制性OEIS
FryAmTheEggman

3
输入n可以从0开始吗?
路易斯·门多

a(n+1) = a(n) odd: 3*a(n)+1, or a(n) even: a(n)/2
Karl Napf '16

@LuisMendo对不起,我以某种方式错过了您的信息。不,要像挑战中那样重现确切的顺序。
orlp

如果a不是基于0的话,我不明白为什么您似乎在这里“基于0说话”:a(n) is the smallest number that was not part of any Collatz sequences for all a(0), …, a(n − 1).
daniero

Answers:


5

果冻20 19 字节

ḟ@JḢ×3‘$HḂ?ÐĿ;Ṛ
Ç¡Ṫ

在线尝试!验证所有测试用例

怎么运行的

Ç¡Ṫ              Main link. No explicit arguments. Default argument: 0
 ¡               Read an integer n from STDIN and do the following n times.
Ç                  Call the helper link.
  Ṫ              Tail; extract the last element of the resulting array.


ḟ@JḢ×3‘$HḂ?ÐĿ;Ṛ  Helper link. Argument: A (array)

  J              Yield all 1-based indices of A, i.e., [1, ..., len(A)]. Since 0
                 belongs to A, there is at least one index that does belong to A.
ḟ@               Filter-false swapped; remove all indices that belong to A.
   Ḣ             Head; extract the first index (i) that hasn't been removed.
           ÐĿ    Call the quicklink to the left on i, then until the results are no
                 longer unique. Collect all unique results in an array.
         Ḃ?      If the last bit of the return value (r) is 1:
       $           Apply the monadic 3-link chain to the left to r.
    ×3‘              Yield 3r + 1.
        H        Else, halve r.
              Ṛ  Yield A, reversed.
             ;   Concatenate the results array with reversed A.

n次迭代之后,a(n + 1)的值将在数组的开头。由于我们将新数组与旧数组的反向副本连接在一起,因此这意味着a(n)将在末尾。


9

Haskell,93 92字节

c x|x<2=[[0,2]!!x]|odd x=x:c(3*x+1)|1<2=x:c(div x 2)
([y|y<-[-1..],all(/=y)$c=<<[0..y-1]]!!)

用法示例:([y|y<-[-1..],all(/=y)$c=<<[0..y-1]]!!) 10-> 19

c x是Collat​​z周期x的作弊行为x == 1。主要功能遍历所有整数和保留那些没有c xx[0..y-1]。该定义几乎是直接实现的。由于Haskell索引运算符!!是从0开始的,所以我开始在-1前面添加一个(否则无用的)数字来固定索引。


4

MATL46 40字节

Oiq:"tX>Q:yX-X<`t0)to?3*Q}2/]h5M1>]Pv]0)

在线尝试!

说明

该代码具有一个外部for循环,该循环生成nCollat​​z序列,每次迭代均产生一个。每个序列由一个内部do...while循环生成,该内部循环计算新值并将其存储在序列向量中,直到获得a 10。当我们完成序列处理后,将向量反转并连接到包含所有先前序列值的全局向量。此向量可能包含重复值。序列向量的反转可确保在外循环的末尾,所需结果(最后一个序列的起始值)将在全局向量的末尾。

伪代码

1  Initiallization
2  Generate n sequences (for loop):
3    Compute initial value for the k-th sequence
4    Generate the k-th sequence (do...while loop)
5      Starting from latest value so far, apply the Collatz algorithm to get next value
6      Update sequence with new value 
7      Check if we are done. If so, exit loop. We have the k-th sequence
8    Update vector of seen values
9  We now have the n sequences. Get final result

注释代码

O           % Push 0                                                          1
iq:         % Input n. Generate [1 2 ... n-1]                                 ·
"           % For loop: repeat n-1 times. Let k denote each iteration         2
  t         %   Duplicate vector of all seen values                           · 3
  X>Q       %   Take maximum, add 1                                           · ·
  :         %   Range from 1 to that: these are potential initial values      · ·
  y         %   Duplicate vector of all seen values                           · ·
  X-X<      %   Set difference, minimum: first value not seen                 · ·
  `         %   Do...while: this generates the k-th Collatz sequence          · 4
    t0)     %     Duplicate, push last value of the sequence so far           · · 5
    to      %     Duplicate, parity: 1 if odd, 0 if even                      · · ·
    ?       %     If odd                                                      · · ·
      3*Q   %       Times 3, plus 1                                           · · ·
    }       %     Else                                                        · · ·
      2/    %       Half                                                      · · ·
    ]       %     End if                                                      · · ·
    h       %     Concatenate new value of the sequence                       · · 6
    5M      %     Push the new value again                                    · · 7
    1>      %     Does it exceed 1? This is the loop condition                · · ·
  ]         %   End do...while. The loops ends when we have reached 0 or 1    · ·
  P         %   Reverse the k-th Collatz sequence                             · 8
  v         %   Concatenate with vector of previously seen values             · ·
]           % End for                                                         ·
0)          % Take last value. Implicitly display.                            9


3

Python 2,97 96字节

r,=s={-1}
exec'n=r=min({r+1,r+2,r+3}-s)\nwhile{n}-s:s|={n};n=(n/2,3*n+1)[n%2]\n'*input()
print r

利用3的所有倍数均为纯的事实。在Ideone上进行测试

怎么运行的

在第一行,r,=s={-1}设置s = {-1}(集合)和r = -1

接下来,我们从STDIN中读取一个整数,重复多次某个特定字符串,然后执行它。这等效于以下Python代码。

for _ in range(input())
    n=r=min({r+1,r+2,r+3}-s)
    while{n}-s:
        s|={n}
        n=(n/2,3*n+1)[n%2]

在每次迭代中,我们从找到不属于s{r + 1,r + 2,r + 3}的最小成员开始。在第一次迭代中,这将r初始化为0

在所有后续运行中,s可能(并且将包含)r + 1r + 2r + 3中的一些,但绝不会全部包含,因为3的所有倍数都是纯的。为了验证这一说法,观察到没有多重3的形式为3K + 1。即叶2M作为唯一可能的原像,这也是的倍数3。因此,m不能出现在Collat​​z序列中任何小于m的数字,因此是纯净的。

标识r并初始化n之后,我们应用的Collat​​z函数n=(n/2,3*n+1)[n%2],将n的每个中间值添加到的集合ss|={n}。一旦我们遇到已经在s中的数字n,将产生一个空集合,并且迭代停止。{n}-s

r的最后一个值是序列的所需元素。


1
除此之外,证明3的所有倍数都是纯的。看任何以3为模的Collat​​z序列。在3x + 1规则的任何应用之后,模为1。在x / 2规则的应用之后,mod 1变成2,而mod 2变成1。这两个规则都不会生成倍数除非起始值已经是3的较大倍数,否则将减半。但是那些还没有生成的更大的值,所以n = 0(mod 3)=> n是纯的。
orlp


1

Java,148个字节

int a(int n){if(n<2)return 0;int f=a(n-1),b,i,c;do{f++;for(b=1,i=1;i<n;i++)for(c=i==2?4:a(i);c>1;c=c%2>0?c*3+1:c/2)b=c==f?0:b;}while(b<1);return f;}

伊迪恩!(警告:归零优化导致指数复杂。)

将其从一个do...while循环转换为一个for循环将是高尔夫球手,但是我很难这样做。

像往常一样欢迎打高尔夫球。


数量不多,但是您可以将更改为,for(b=1,i=1;i<n;i++)以减少1个字节的距离for(b=1,i=0;++i<n;)。顺便说一句,我知道为什么您的ideone缺少50个测试用例,但是为什么它也缺少10个?它可以毫无问题地处理它。
凯文·克鲁伊森

@KevinCruijssen因为格式不好。
Leaky Nun

不是最好的改进,但我没有花太多时间...(147字节)int a(int n){if(n<2)return 0;int f=a(n-1),b=0,i,c;for(;b<1;){f++;for(b=1,i=1;i<n;i++)for(c=i==2?4:a(i);c>1;c=c%2>0?c*3+1:c/2)b=c==f?0:b;}return f;}

1

Perl6,96

my @s;my $a=0;map {while ($a=@s[$a]=$a%2??3*$a+1!!$a/2)>1 {};while @s[++$a] {}},2..slurp;$a.say;

基于Perl 5的答案。由于Perl6语法比Perl5语法宽容度稍长,但是我现在就解决这个问题。


0

PHP,233124字节

<?$n=$argv[1];for($c=[];$n--;){for($v=0;in_array($v,$c);)$v++;for(;$n&&!in_array($v,$c);$v=$v&1?3*$v+1:$v/2)$c[]=$v;}echo$v;

+4功能:

function a($n){for($c=[];$n--;){for($v=0;in_array($v,$c);)$v++;for(;$n&&!in_array($v,$c);$v=$v&1?3*$v+1:$v/2)$c[]=$v;}return$v;}

0

Perl 5-74字节

map{0 while 1<($a=$c[$a]=$a%2?$a*3+1:$a/2);0 while$c[++$a]}2..<>;print$a+0

这是一个非常简单的解决方案。它将Collat​​z函数重复应用于该变量,然后将已看到该值的值$a存储在数组@c中,然后在达到0或1后递增,$a直到该值尚未出现为止。重复此操作等于输入负2的次数,最后$a输出的值。


0

Mathematica,134个字节

f=If[EvenQ@#,#/2,3#+1]&;a@n_:=(b={i=c=0};While[i++<n-1,c=First[Range@Max[#+1]~Complement~#&@b];b=b~Union~NestWhileList[f,c,f@#>c&]];c)

易于阅读的格式:

f = If[EvenQ@#, #/2, 3#+1] &;                        Collatz function
a@n_ := (                                            defines a(n)
  b = {i = c = 0};                                   initializations
                                                       b is the growing sequence
                                                       of cycles already completed
  While[i++ < n - 1,                                 computes a(n) recursively
    c = First[Range@Max[# + 1]~Complement~# & @b];   smallest number not in b
    b = b~Union~NestWhileList[f, c, f@# > c &]       apply f to c repeatedly
                                                       until the answer is smaller
                                                       than c, then add this new
                                                       cycle to b
    ]
  ; c)                                                 output final value of c
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.