上升和复位序列的第n个项


37

(挑战来自codingame.com上的多人游戏(代码冲突))

挑战

找到以下序列的第n个项:1, 1, 2, 1, 2, 3, 1, 2, 3, 4...或者,为了使其更明显,{1}, {1,2}, {1,2,3}, {1,2,3,4}...

该序列由1到x的连接范围组成,从1开始一直一直到无穷大。

规则/ IO

输入和输出可以是任何格式,只要可以区分即可。输入可以来自任何适当的来源:STDIN,文件等。

输入可以是0或1索引,并且必须在帖子中提及所选的索引。

您将必须至少处理结果(包括255)(包括255)(意味着0索引的最大输入为32640)。如果您的语言支持,则必须解决所有问题。

这是code-golf最短的字节数获胜!

测试用例(基于0的索引)

0 -> 1
1 -> 1
5 -> 3
10 -> 1
59 -> 5
100 -> 10
1001 -> 12


4
你应该添加一些较大的测试用例(59100,等)
FlipTack


反过来就是挑战。应对挑战的最佳答案无法逆转。@JarkoDubbeldam
devRicher

我知道@devRicher,只是把它放在那里并没有负面的意思。我自己的回答实际上是可逆的。相关!=重复。
2017年

Answers:


5

05AB1E,5个字节

该程序是0索引的,代码:

ÌLL¹è

说明:

Ì       # Double increment the input
 LL     # List of list on the input
   ¹è   # Get nth element

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


GNG¹¾¼QiN是一种迭代方法,但这更聪明。
Magic Octopus Urn

13

Haskell27 26字节

([z|k<-[1..],z<-[1..k]]!!)

在线尝试!

谢谢@DanD。为-1个字节!

这是一个匿名函数,仅返回第- n个元素即可创建无限序列:[[1..k]| k<-[1..]]生成list:的无限列表[[1],[1,2],[1,2,3],[1,2,3,4],...]。为了连接这些,我们可以写出[z|k<-[1..],z<-[1..k]]结果,[1,1,2,1,2,3,1,2,3,4,...]并最终(...!!)接受输入n(无意义表示法)并返回n-th项(从0开始)。


concat用更多的理解替换只节省1个字节:([z|k<-[1..],z<-[1..k]]!!)
Dan D.

12

JavaScript,29 28字节

-1个字节感谢Arnauld!

f=(n,m)=>n++<m?n:f(n+~m,-~m)

使用在OEIS上找到的0索引递归公式。

当与如预期1个参数调用时,第二的默认值,m将是undefined。但是,-~undefined返回1,这使我们可以m = 1在参数列表中没有显式的情况下进行递归滚动(感谢@Arnauld!)

测试代码段:

f=(n,m)=>n++<m?n:f(n+~m,-~m)

let examples = [0, 1, 5, 10, 15, 1000];

examples.forEach(function log(x) {
    console.log(x, " => ", f(x))
});


另外,对于相同的字节数,我们可以有一个curried函数,如下所示:

f=n=>m=>n++<m?n:f(n+~m)(-~m)

您可以使用f(5)()- 调用它-它返回一个函数,该函数在被调用时返回结果,如本meta post中所述


9

果冻,5字节,1索引

RRF³ị

在线尝试!

说明:

                                      (Assume N = 4 for the examples)
R      Generate a list of 1 to N      [1, 2, 3, 4]
 R     Generate new lists for each item on the previous list, with that item as N
                                      [[1], [1,2], ...]
  F    Flatten that list              [1, 1, 2, 1, 2, 3 ...]
   ³ị  Use the input number (³) as index (ị) on the list. 
       This is one-based:             [1, 1, 2, 1, 2, 3 ...] 
                                                ^

8

八度,39字节

@(z)z-(n=ceil((8*z+1)^.5/2-.5))*(n-1)/2

基于1的索引

说明:

考虑以下顺序:

1   1   2   1   2   3   1   2   3   4   1   2   3   4   5

如果我们计算子序列的元素数

1   2        3          4               5         

因此,对三角形使用高斯公式, 我们可以为z形成公式:

z=n*(n+1)/2

这是一个二次方程,如果我们求解n

n=(sqrt(8*z+1)-1)/2

在线尝试!


7

Haskell,25个 24字节

(!!)$[1..]>>= \x->[1..x]

用法示例:((!!)$[1..]>>= \x->[1..x]) 10-> 1在线尝试!

将匿名的make-a-list-from-1到x函数\x->[1..x](内置的enumFromTo 1列表长1个字节)映射到无限列表[1..],并将结果列表串联为一个列表。!!选择第n个元素。

感谢@flawr一个字节。


我认为您可以使用来缩短它(!!)$[1..]>>= \x->[1..x]。有时我真的希望有一种简短的,毫无意义的写作方式\x->[1..x]:)
更加模糊的

PS:为什么不添加“ 在线试用”!链接?
瑕疵

@flawr:很好,谢谢!在线尝试使用ghc(或Prelude)的旧版本,并且大多数答案<$>都在范围内。您知道使用最新版本的任何在线Haskell编译器/解释器吗?haskell.org仅允许使用表达式,您不能创建指向您输入代码的链接。
nimi

1
啊,让我告诉@Dennis更新它,他是TIO的创造者:)
瑕疵的

6

八度,39字节

@(n){v=1:n,A=triu(v'+0*v),A(A>0)(n)}{3}

在线尝试!

这使用了替代方法。

例如,n=1这将A=triu(v'+0*v)创建矩阵

1   1   1   1
0   2   2   2
0   0   3   3
0   0   0   4

当删除所有零元素并通过添加列时,A(A>0)我们得到以下序列:

1   1  2  1  2  3  1  2  3  4

然后,只需提取该n序列的-th项即可。


5

Python39 36字节

-3个字节感谢Dennis!

使用基于1的索引的递归lambda。

f=lambda n,m=1:n*(n<=m)or f(n-m,m+1)

在线尝试!

我们使用跟踪当前的“上升”大小m。如果n小于或等于m,则它适合当前的“上升”,因此我们将其返回。但是,如果它的量比较大m,我们采取m远离它,比加1 m和递归调用函数(移动到下一个上升)。


5

R,25个字节

i=scan();sequence(1:i)[i]

索引从1开始。


我今天看到了这个sequence问题,并想知道是否有人提交了答案,并且很高兴看到这个问题。
朱塞佩


4

Mathematica,27个 24字节

感谢@MartinEnder 3个字节!

((r=Range)@r@#<>1)[[#]]&

1个索引。这会引发可以忽略的错误。

说明

((r=Range)@r@#<>1)[[#]]&
  r=Range                 (* Store Range function in r *)
           r@#            (* Create list {1..n} *)
 (r      )@               (* For each element, generate {1..n} *)
              <>1         (* Join the lists and append a 1; throws errors *)
(                )[[#]]&  (* Take the nth element *)

2
Join@@太贵了;)((r=Range)@r@#<>1)[[#]]&
Martin Ender

@MartinEnder Woah,滥用StringJoin未被评估的事实……我喜欢
JungHwan Min

4

brainf * ck,78个字节

,>+<[>[->>+>+<<<]>>>[-<<<+>>>]<<+[->->+<<]>[<<->>>[-<<+>>]<[-]]>[-]<<<+<-]>>+.

接受输入(从0开始)并将其输出为字节值。

您可以在这里进行测试

输入要求\十进制数字前(例如\1010)。如果输出是可打印的ASCII字符,则应该看到它。否则,点击查看内存->最终转储。打印的值在第三个单元格中(单元格编号2)。

说明:

单元格0(INPUT):是输入,每次通过循环减1。

单元格1(RESET):每次等于TERM时加1。为此,每次循环时我们加1,如果不相等,我们减1。

单元2(TERM):每个循环加1,如果与RESET匹配则设置为0。为此,仅当此单元格不等于RESET时,才将值从HOLD复制回。

单元格3(等于):用于检查RESET和TERM是否相等。

单元格4(保持):用于在相等检查之后将RESET和TERM的值复制回去。

,>+<              # get input and put a 1 in RESET
[                 # for INPUT to 0
  >[->>+>+<<<]    # copy RESET to EQUAL and HOLD
  >>>[-<<<+>>>]   # copy HOLD back into RESET
  <<+             # add 1 to TERM
  [->->+<<]       # subtract TERM from EQUAL and copy it to HOLD
  >[              # if RESET and TERM were not equal
    <<-           # subtract 1 from RESET
    >>>[-<<+>>]   # copy HOLD back to TERM
    <[-]          # zero out EQUAL
  ]               # end if
  >[-]            # zero out HOLD
  <<<+            # add 1 to RESET (this cancels out the subtraction if
                  #     RESET did not equal TERM)
  <-              # subtract 1 from INPUT
]>>+.             # end for and add 1 because the sequence resets to 1 not 0

做得好!我将对此进行测试,并在之后颁发赏金。介意添加解释吗?:)
Yttsi'1

@TuukkaX我正在研究:)今晚有时间时,我将尝试添加更多内容。
莱利

似乎可以工作:)赏金计划可在20小时内提供。
Yttsi '17

@TuukkaX请记住,赏金应该在整整7天都可用以引起注意,然后在最后一天颁发。
mbomb007 '01

@ mbomb007嗯。我宣布,将把赏金授予第一个提交解决方案的人,这意味着赏金的竞争已经结束。但是,其他人的行为与您提到的相同,这是弥补我失去的观点的一种好方法。谢谢:)
Yytsi'1


3

R,43 41字节

编辑:通过使用A002262 + 1(索引0,找到了一个较短的递归方法):

f=function(n,m=1)`if`(n<m,n+1,f(n-m,m+1))

旧版:

n=scan();n-choose(floor((1+sqrt(8*n))/2),2)

OEIS的1索引公式。


在线尝试!它似乎工作正常。:)
R. Kap's

与您的解决方案相比,我设法节省了一些字节。看我的答案。
JAD

3

Perl 6,21个字节

{map(|^*,^∞)[$_]+1}

0索引。在线尝试!

这个怎么运作:

{                 }  # A lambda.
         ^∞          # Range from 0 to Inf-1. (Same byte count as 0..*, but cooler.)
 map( ^*,  )         # Map each number n to the range 0..(n-1),
     |               # And slip each range into the outer list.
            [$_]     # Index the sequence with the lambda argument.
                +1   # Add 1.

Perl 6,21个字节

{[\,](1..*).flat[$_]}

0索引。在线尝试!

这个怎么运作:

{                   }  # A lambda.
      1..*             # Range from 1 to infinity.
 [ ,](    )            # Fold it with the comma operator,
  \                    # and return all intermediate results, e.g. (1), (1,2), (1,2,3)...
           .flat       # Flatten the sequence.
                [$_]   # Index it with the lambda argument.

2

这些解决方案都不能像JungHawn Min的解决方案那么短,但是它们是替代方法,我想这就是。两者都是未命名函数,均接受(1索引)正整数输入并返回正整数。

Mathematica,30个字节

-#^2-#&@⌈√(2#)-3/2⌉/2+#&

该函数的实际数学公式!更加可读的(部分地通过平移3字节字符):

# - ((#^2 + #) / 2 &)[Ceiling[Sqrt[2 * #] - 3/2]] &

Ceiling[Sqrt[2 * #] - 1/2]告诉我们输入引用的是哪个子列表,然后从中减去一个以告诉我们哪个子列表在到达输入之前结束;然后((#^2 + #) / 2 &)计算在我们关心的子列表中所有子列表中有多少个元素,然后从输入中减去这些元素#以获得答案。(有些会注意到熟悉的公式(#^2 + #) / 2#第三角数; Ceiling[Sqrt[2 * #] - 1/2]在本质上是反函数)。

Mathematica,32个字节

If[#2<=#,#2,#0[#+1,#2-#]]&[1,#]&

递归解,与Billywob的答案和其他答案基本相同。


2

Brain-Flak,46个字节

零索引

(<>()){(({}())[()]){({}[()])<>}{}}<>([{}()]{})

在线尝试!

堆栈清理,48个字节

(<>()){(({}())[()]){({}[()])<>}{}}{}<>([{}()]{})

在线尝试!

说明

这是模函数的修改版本。代替使用常数作为除数,每次从除数中减去除数时都会增加除数(每次外循环迭代一次)。

带注释的代码

(<>())       # Switch to the opposite stack and push 1 (the initial divisor)
{            # (outside loop) While top of stack is not 0...
  (          # Push...
    ({}())   # Push the divisor plus 1
  [()])      # ...minus one (ie push a copy of the original divisor
  {          # (inner loop) While the top of stack does not equal zero
    ({}[()]) # Decrement the top of the active stack
    <>       # Switch stacks
  }{}        # (inside loop) End loop and pop zero off the top of stack)
}            # (outside loop) End loop
<>           # Switch stacks (to the one with the divisor)
([{}()]{})   # Calculate the result

2

Java 8,85 73 55字节

n->f(n,1)+1int f(int n,int m){return n<m?n:f(n-m,m+1);}

具有OEIS中提供的公式的0索引递归方法:

a(n) = 1 + A002262(n)
A002262a(n)=f(n,1)带有f(n,m) = if n<m then n else f(n-m,m+1)

在这里尝试。


旧答案(85 56字节):

n->{int m=~-(int)Math.sqrt(8*n+1)/2;return n-m*-~m/2+1;}

使用了OEIS中提供的其他0索引公式:

第n个项是n - m*(m+1)/2 + 1,在那里m = floor((sqrt(8*n+1) - 1) / 2)

在这里尝试。



1

MATL,8个字节

:"@:]vG)

该解决方案使用基于1的索引

MATL Online上尝试

说明

        Implicitly grab input (N)
:       Create an array from [1...N]
"       For each element (A) in this array...
  @:    Create an array from [1....A]
]       End for loop
v       Vertically concatenate everything on the stack
G       Explicitly grab the input again
)       And use it to index into the vertically concatenated array
        Implicitly display the result

1
并不是很重要,但是如果您移动v之后的话,代码会更快]
Luis Mendo

1
@LuisMendo啊好点!我喜欢短快!
Suever

但是,这是一个短路,当然!:-)
Luis Mendo

1

QBIC,21字节,1索引

:[a|[b|~q=a|_Xc\q=q+1

说明:

:      Get 'a' from the cmd line
[a|    FOR (b = 1; b <= a; b++) This creates an outer loop from 1 to N
[b|    FOR (c = 1; c <= b; c++) This creates an iteration, yielding the 1, 12, 123 pattern
       'q' stores how many terms we've seen. It starts at 1 b default.
~q=a   if we are at the desired term (q == a)
|_Xc   Then quit, and print 'c' (the current number in the sequence)
\q=q+1 Else, increase 'q' and run again.

稍微有趣一点的方法,但是要长10个字节:

:{~b+q>=a|_xa-b|\b=b+q┘q=q+1

该程序连续计算此括号内和之前所有数字(1 at loop 1, 3 at loop 2, 6 at loop 3 ...)的总数。当该计数器超过搜寻索引N时,则从当前括号中返回X,其中X为N减去计数器的先前值。


1

Ruby,30个字节

->n{(0..n).find{|x|0>=n-=x}+n}

基于1的索引


1

R,37个字节

n=scan();for(i in 2:n)T=c(T,1:i);T[n]

从中获取输入n,并为第一个n序列创建序列。这使得它在输入较高时效率低下,但应该没问题。然后n,它返回第一个索引为1的条目。

使用由出发与序列一个可爱的小伎俩T,这是TRUE1默认。



1

Brainfuck,141个字节

我知道我为赏金而为时已晚,但我只是想看看我想到的算法最终会占用多少字节。

该程序为零索引。

,>+<[[->>+>+<<<]>>[-<<+>>]<[->+>>+<<<]>[-<+>]>>+[[-<->>+<]>[-<+>]<<<<]>>[>>>]>[.[<<<]]<<<<<<<[[-]>>>[-<+<<+>>>]<[->+<]<<<<<]>>>[>>>]<<<]>[.>]

在线尝试

  • 选择“ 动态(无限)内存”,否则它将不起作用
  • 要测试输入值> 255,将像元大小(位)更改为1632
  • 口译员解释了如何进行输入。对于十进制输入使用\5的输入5
    • 可以测试输入的最大十进制值为 \999
    • 十六进制输入可以达到很高的像元大小。

说明:

这显示了按步骤分解的程序,显示了输入时发生的情况5#被放置在解释器理想的内存转储位置。

如果运行此版本,则可能要在char:处#使用转储内存复选框。这将在击中时转储内存#,使您可以在磁带上出现无法打印的字符时查看其值,或者查看所需的任何步骤会发生什么。指针所在的单元格将以粗体显示。

,>+<                       (5) 1
[[->>+>+<<<]>>[-<<+>>]       5 1 (0) 5
<[->+>>+<<<]>[-<+>]>>+       5 1 0 5 (2)
[[-<->>+<]>[-<+>]<<<<] (0) 0 4 1 0 3 2 0 0
>>[>>>]                      4 1 0 3 2 0 (0) 0
                             1 1 0 (0) 2 0
>[.#[<<<]]<<<<                4 1 0 (3) 2 0 0 0
<<<[[-]>>>[-<+<<+>>>]<[->+<]<<<<<]>>> (3) 1 0 3 2 0 0 0
[>>>]<<<]>[.#>]

Tape structure:
    (cell_1 cell_2 temp), (cell_1 cell_2 temp), ...

Take Input;
If not zero:
  copy last pair to the right and add one to its cell_2
  subtract each cell_2 from each cell_1 (leaving each cell_2 intact)
  move checking from left to right: 
    If cell_1 is zero and cell_2 isn't:
      print cell_2
    Else:
      copy last cell_1 back, overwriting each previous cell_1
Else:
  right one and print result

在线尝试

  • 选择“ 动态(无限)内存”,否则它将不起作用
  • 在char中转储内存: #

笔记:

  • 要在不允许移动到起始单元格左侧的另一个解释器上运行它(这就是我使用动态内存的原因),请在>开始处放入一堆。所需的数量可能会根据输入值而有所不同,但为O(1)。

1

tinylisp(repl),90个字节(0索引)

(d r(q((n j x)(i n(i(e j x)(r(s n 1)1(s x(s 0 1)))(r(s n 1)(s j(s 0 1))x))j
(q((n)(r n 1 1

或者,非竞争(使用发布此挑战后提交的功能),80字节

(d r(q((n j x)(i n(i(e j x)(r(s n 1)1(a x 1))(r(s n 1)(a j 1)x))j
(q((n)(r n 1 1

第一行定义了一个辅助函数r,第二行是一个未命名的函数,它接受n并返回序列的第n个项。我将其指定为repl提交,因为repl在每一行的末尾自动完成括号,而不仅仅是在程序末尾。有了这些注意事项,这是一个经过修改的版本,可以在“ 在线试用”中使用,并且这是一个针对输入0到54 的非高尔夫版本

说明

我将在此处使用非竞争版本。唯一的区别是正式版本必须将加法实现为两个减法。

(d r           Define r to be:
 (q(           A lambda function (= a list of two elements, quoted to prevent evaluation):
  (n j x)       Arguments n, j (the range counter), and x (the range limit)
  (i n          If n is truthy, i.e. nonzero:
   (i(e j x)     If counter equals limit:
    (r            Call r recursively on:
     (s n 1)       n-1
     1             counter reset to 1
     (a x 1))      limit increased by 1
    (r           Else, call r recursively on:
     (s n 1)       n-1
     (a j 1)       counter increased by 1
     x))           same limit
   j))))        Else, we're done; return the counter value

(q(            Lambda function:
 (n)            Argument n
 (r n 1 1)))    Call r with n, counter = 1, range limit = 1

1

C,54个字节

不是最短的C解决方案,但它具有以恒定时间运行的优点(没有循环,只有数学)。它使用基于零的索引:

x;f(n){x=floor(sqrt(8*n+1)-1)/2;return 1+n-x*(x+1)/2;}

取消高尔夫:

int f(int n) {
    int x = floor(sqrt(8*n+1)-1)/2; //calculate the number of the current subsequence (zero based)
    return 1+n-x*(x+1)/2;   //x*(x+1)/2 is the zero based index of the `1` starting the subsequence
}

测试:

#include <math.h>
#include <assert.h>
#include <stdio.h>

x;f(n){x=floor(sqrt(8*n+1)-1)/2;return 1+n-x*(x+1)/2;}

int main(){
    int i;
    for(i = 0; i < 10; i++) printf("%d ", f(i));
    printf("\n");

    assert(f(0) == 1);
    assert(f(1) == 1);
    assert(f(5) == 3);
    assert(f(10) == 1);
    assert(f(59) == 5);
    assert(f(100) == 10);
    assert(f(1001) == 12);
}

1

C,103字节

对于初学者来说还可以,我认为:)。

int main(){int n,c,i,j;scanf("%d",&n);while(c<n){for(i=1;i<=j;i++){c++;if(c==n)printf("%d",i);}j++;}}

或格式化的方式

#include <stdio.h>

int main() {
    int n,c,i,j;
    scanf("%d",&n);
    while(c<n) 
    {
        for(i=1;i<=j;i++)
        {
            c++;
            if(c==n) printf("%d",i);
        }
        j++;
    }
}

1
如果声明n,c,i,j为全局变量,则可以确保将它们初始化为0,而对于本地变量则不是这样。
feersum '02

我知道它会包含这样的无经验错误。n是输入或序列中的第n个数字,c是一个计数器,i并且j是循环元素;j将是1然后2然后3,而i将是1然后1,2然后1,2,3,依此类推。@ Qwerp-Derp
Mohammad Madkhanah

我不确定我是否完全理解您的意思,但是无论我将它们声明为全局变量还是局部变量,此代码中的初始值均为0。请更正我,如果我错了0 =)。@feersum
Mohammad Madkhanah

否,未初始化的局部变量没有被设置为0。stackoverflow.com/questions/15268799/...
feersum

1

dc,21字节,基于0的索引

?d8*1+v1-2/d1+*2/-1+p

在线尝试直流程序!

说明:

?      Push input number n.
d      Duplicate n at the top of the stack.
8*1+   Replace n at the top of the stack with 8n+1.
v      Replace 8n+1 at the top of the stack with the floor of its square root.
1-2/   Subtract 1, and divide by 2 (ignoring any fractional part).

现在,堆栈的顶部保留最大三角形数的索引k,该三角形数<= n。

d1+*2/ Compute k(k+1)/2, which is the greatest triangular number <= n.
-      Subtract n-(the greatest triangular number <= n). The first n is on the stack in position 2, because the input number n was duplicated at the top of the stack at the very beginning of the program, and only one of the values was popped and used (until now).
1+     Add 1 because the desired sequence starts over again at 1 (not 0) at every triangular number.
p      Print the answer.

此dc程序可以转换为具有竞争力的bash脚本:

Bash + Unix实用程序,28字节,基于0的索引

dc -e"?d8*1+v1-2/d1+*2/-1+p"

在线尝试bash程序!


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.