跳序列


19

请考虑以下顺序:

0 1 3 2 5 4 8 6 7 12 9 10 11 17 13 14 15 16 23 ...

看起来没有花样,对吗?运作方式如下。从开始0,跳n整数,n从开始1。那是序列中的下一个数字。然后,附加任何“已跳过”且尚未出现的按升序排列的数字。然后,增加n并从附加的最后一个数字开始跳转。重复此模式。

例如,当我们到达时11,我们在n=5。由于尚未n出现n=6,我们增加到,跳到17,然后追加13 14 15 16。我们的下一个跳跃是n=7,因此序列中的下一个元素是23

挑战

给定输入x,输出x该序列的第一x项,序列的第一项,或构建该序列的项的无限列表。您可以选择0或1索引。

I / O和规则

  • 输入和输出可以通过任何方便的方法给出。
  • 可以假定输入和输出适合您语言的本机数字类型。
  • 完整的程序或功能都是可以接受的。如果是函数,则可以返回输出而不是打印输出。
  • 禁止出现标准漏洞
  • 这是因此所有常用的高尔夫规则都适用,并且最短的代码(以字节为单位)获胜。


@JayCe我并不感到惊讶-这是一个很随意的序列。
AdmBorkBork

Answers:


24

JavaScript(ES7),41个字节

返回序列的第n个项,索引为0。

n=>(d=(n--*8-23)**.5)%1?n:'121'[n]^n-~d/2

在线尝试!

怎么样?

主要情况:ñ>3

该序列的前四个词很特殊,所以现在暂时将它们放在一边。

对于,序列如下所示:ñ>3

 n  | [4] 5 [6] 7 8 [ 9] 10 11 12 [13] 14 15 16 17 [18] 19 20 21 22 23 [24] 25 26 27 ...
----+------------------------------------------------------------------------------------
a(n)| [5] 4 [8] 6 7 [12]  9 10 11 [17] 13 14 15 16 [23] 18 19 20 21 22 [30] 24 25 26 ...
----+------------------------------------------------------------------------------------
 k  |  2  -  3  - -   4   -  -  -   5   -  -  -  -   6   -  -  -  -  -   7   -  -  - ...

我们可以注意到实际上有两个交错的子序列:

  • 大多数值属于子序列,我们只需拥有以下子序列:一种

    一种ñ=ñ-1个
  • 其他一些值属于子序列(在上图中用括号突出显示),其索引遵循算术序列3、3、4、6、9、13、18、24 ...,我们具有:

    ñķ=ñ+ķ-1个

    其中是主序列的索引,k是子序列B的索引。ñķ

主序列中的索引由下式给出:

ñķ=ķ2-ķ+62

给定,我们知道如果n是二次方程的整数解,则主序列中的对应项属于Bññ

X2-X+6-2ñ=0

其判别是:

Δ=1个-46-2ñ=8ñ-23

其正面解决方案是:

X=1个+Δ2

我们期望是整数。因此测试:Δ

(d = (n-- * 8 - 23) ** .5) % 1

特殊情况:0ñ3

对于,判别式为负,并将其平方根取为NaN。对于n = 3,判别式为1。因此,该序列的前四个方面都被认为属于该子序列ñ<3ñ=31个

如果我们仅应用标准公式n-〜d / 2,我们将得到:

-1个21个2323

代替:

01个32

这就是为什么我们这些XOR结果与分别。01个2 和 1个


10

外壳,12个字节

Θṁṙ_1C+ḣ2tNN

在线尝试!

输出为无限列表。是打印第一个N的版本。

说明

Θṁṙ_1C+ḣ2tNN–完整程序。不输入,输出到STDOUT。
         tN –构造从2开始的无限自然数列表。
      +ḣ2–并附加[1,2]。产量[1,2,2,3,4,5,6,7,8,9,10,11,...]。
     CN –将无穷大的正整数列表切成碎片
               大小。产量[[1],[2,3],[4,5],[6,7,8],[9,10,11,12],...]。
 ṁ–此后映射并展平结果。
  ṙ_1–将它们向右旋转1个单位。
               产量[1,3,2,5,4,8,6,7,12,9,10,11,...]
Θ–前面加0。产量[0,1,3,2,5,4,8,6,7,12,9,10,11,...]

7

Haskell,43个字节

0:1:3:2:5!3
a!n=a:[a-n+2..a-1]++(a+n)!(n+1)

在线尝试!

定义一个无限列表:

  0:1:3:2:(5!3)
 0:1:3:2:5:4:(8!4)
 0:1:3:2:5:4:8:6:7:(12!5)
 0:1:3:2:5:4:8:6:7:12:9:10:11:(17!6)
 0:1:3:2:5:4:8:6:7:12:9:10:11:17:13:14:15:16:(23!7) 

4

果冻,15字节

+‘ɼṪRṙ-œ|@
0Ç¡ḣ

这是一个完整的程序,给定n,将打印序列的前n个项目。

在线尝试!

怎么运行的

0Ç¡ḣ        Main link. Argument: n

0           Set the return value to 0.
 Ç¡         Call the helper link n times, first with argument 0, then n-1 times
            with the previous return value as argument.
   ḣ        Head; extract the first n items of the last return value.


+‘ɼṪRṙ-œ|@  Helper link. Argument: A (array)

 ‘ɼ         Increment the value in the register (initially 0) and yield it.
+           Add that value to all items in the sequence.
   Ṫ        Tail; extract the last item.
    R       Range; map k to [1, .., k].
     ṙ-     Rotate -1 units to the left, yielding [k, 1, ..., k-1].
       œ|@  Perform multiset union of A and the previous return value.

3

C(gcc),73 67 64字节

t,d;f(x){for(t=4,d=2;d<x;t+=d++)x-t||(d+=x+=d);t=x<4?x^x/2:x-1;}

在线尝试!

定义一个函数f,该函数采用0索引nn在序列中产生th号。

我们可以分析以下序列:

f(n)  = n   where n = 0, 1

f(2)  = 3   // 2 and 3 are swapped
f(3)  = 2

f(4)  = 5   // (+2,+3)
f(6)  = 8   // (+3,+4)
f(9)  = 12  // (+4,+5)
f(13) = 17  // (...)
...

f(n)  = n-1 // for all cases not yet covered

首先我们处理中间部分:

for(t=4,d=2;d<x;t+=d++)x-t||(d+=x+=d);

请注意,左侧的参数(4、6、9、13,...)遵循以下模式:首先添加两个,然后添加三个,然后添加四个,依此类推。我们从循环的每个迭代开始t=4并添加d(从2开始),并d在此过程中递增。

循环的主体更有趣。请记住,我们要映射4到5、6到8、9到12等。那只是添加d-1if xt。但是,此逻辑位于最后一种情况之前f(n) = n - 1,因此我们知道最后要减去1。因此,我们可以简单地添加dif x == tx-t||(x+=d))。但是,在此之后,我们还需要立即跳出循环-因此,我们将添加到d外观上看起来很荒谬d+=x+=d,这总是会使d<x条件失败。

这涵盖了除前四个值以外的所有内容。用二进制查看它们,我们得到:

00 -> 00
01 -> 01
10 -> 11
11 -> 10

因此,我们想翻转if的最后一位2 <= x < 4。这是通过完成的x^x/2x/2给出第二个最低有效位,因此如果该数字为2或3,则将其与原始数字异或会翻转最后一位。


3

果冻 13  10 字节

-3感谢Dennis(使用0索引从累积和设置和最终减量中节省2)

Ḷ»2Äi+_>2$

接受整数(0索引的n)的单子链接,该整数返回整数a(n)

在线尝试!或看一个测试套件


真好!我有ḶÄ+3i+’,但不知道如何处理极端情况。
丹尼斯

我也有Ḷ»ạ¥3Ḋ3,2;-像感觉应该有此位更简洁。
乔纳森·艾伦

Ḷ»2Äi+_>2$使用从0开始的索引,节省3个字节。
丹尼斯

哦,太棒了!我陷入了1指数土地。
乔纳森·艾伦


2

MATL,22字节

1y:"t0)@+h5M:yX-h]qw:)

输出n序列的第一项。

在线尝试!

说明

1         % Push 1
y         % Implicit input: n. Duplicate from below
":        % For each k in [1 2 ... n]
  t0)     %   Duplicate sequence so far. Get last entry, say m
  @+      %   Add k: gives m+k
  h       %   Concatenate horizontally
  5M      %   Push m+k again
  :       %   Range [1 2 ... m+k]
  y       %   Duplicate from below
  X-      %   Set difference
  h       %   Concatenate horizontally
]         % End
q         % Subtract 1, element-wise
w         % Swap. Brings original copy of n to the top
:)        % Keep the first n entries. Implicit display

最后,我喜欢笑脸,现在我希望所有的MATL程序都以微笑结束。:)
sundar-恢复莫妮卡

@sundar是的,我很高兴这是MATL中一个相对常见的习惯用法:-D
Luis



1

QBasic,58个字节

DO
b=r+j
?b
r=b
FOR x=a+1TO b-1
?x
r=x
NEXT
a=b
j=j+1
LOOP

无限期输出。您可能想要SLEEP 1在循环中添加一个内部或使其成为LOOP WHILE b<100类似对象,以便查看结果。

这基本上只是实现规范。请注意,我们返回的数字始终是最近跳入的数字和之前跳出的数字之间的数字。因此,我们将这些界限存储为a和,b并使用FOR循环来打印它们之间的所有数字。



1

R,70个字节

function(e){for(i in 1:e)F=c(setdiff((F+i):1-1,F),F[1]+i,F);rev(F)[e]}

在线尝试!

  • 1索引
  • -4字节使用F常量,感谢@JAD建议
  • @Giuseppe建议,-5字节反转列表
  • -2字节由于@JAD建议而在for循环中删除了无用的花括号
  • -2个字节使用setdiff代替x[x %in% y]

先前版本(79字节)



@JAD:我总是忘了使用F / T ...我不能帮助它,我也倾向于避免“不安全代码”:d
digEmAll

1
反向构造列表5 bytes会保存并引起一堆警告!
朱塞佩

如果F/T未在函数定义中重新定义,这甚至也不安全。它不会(IIRC)修改F/T
JAD 2013年


1

Python 2,123字节

def f(z):[s.extend([s[-1]+n]+[x for x in range(s[-1]+1,s[-1]+n)if not x in s]) for n in range(1,z)if len(s)<z];return s    

在线尝试!

给定输入x,输出序列的前x个项,

我正在学习Python,而这一挑战使事情变得更加有趣。

编辑:刮一些空白


欢迎来到PPCG!您可以在中删除更多空间for n in range(1,z) if len(s) < z]; return sfor n in range(1,z)if len(s)<z];return s
Laikoni

0

果冻,16字节

RÄṬŻk²Ḋ$ṙ€-Ø.;Fḣ

在线尝试!

比现有的Jelly答案长一个字节,但是可以打一点。RÄṬŻk²Ḋ$可能会更短。

18字节

RÄṬŻk²Ḋ$‘ṙ€1FŻŻỤ’ḣ

更长但又不同。



0

Perl 6,52个字节

(0,{((^max @_)∖@_).min.?key//(1+@_[*-1]+$++)}...*)

在线尝试!

这是使用...运算符的生成器表达式。它看起来在之前序列缺口@_通过((^max @_)∖@_).min.?key

      @_  # prior sequence values         [0,1,3]
  max @_  # largest prior sequence value       3
 ^        # the Range 0..max @_            0,1,2
(       )∖@_  # set subtract prior seq     -0,1  -> (2=>True)
            .min  # smallest unseen value  2=>True
                .?key  # set yields pairs  2

?是必要的,其不具有初始值.key。如果未找到间隙,则将n(在$变量中)添加到列表中的最后一个值,再加上一个0表示错误的错误。


0

Python 3,104个字节

def f(x):
 n=a=0
 l=list(range(x*x))
 while n<x:print(l[a+n],*l[a+2-(n<3):a+n],end=' ');a=a+n-(a>0);n+=1

在线尝试!

给定输入x,输出前x个“序列”

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.