不在序列中的整数之和的序列


28

背景

考虑定义如下的序列:

  • 第一个元素为0;第二个元素为0。
  • 第二个元素是4;
  • 从第三个元素开始,其值可以通过以下方式计算:
    • 取从0到序列的前一个元素的整数集(包括或不包括);
    • 从集合中删除序列中较早出现的所有整数;
    • 将集合的其余元素加在一起;那就是您想要的价值。

有趣的是,此序列似乎尚未在OEIS上

任务

编写一个程序或函数,将整数n作为输入,并输出序列的第n个元素。

测试用例

该序列的前几个元素是:

  • 0
  • 4
  • 6(1 + 2 + 3)
  • 11(1 + 2 + 3 + 5)
  • 45(1 + 2 + 3 + 5 + 7 + 8 + 9 + 10)
  • 969(1 + 2 + 3 + 5 + 7…10 + 12…44)
  • 468930(1 + 2 + 3 + 5 + 7 ... 10 + 12 ... 44 + 46 ... 968)

澄清说明

  • 从理论上讲,如果您的语言在具有无限大整数的语言变体上运行并且可以访问无限量的内存,则该程序应该能够处理任意n。(没有大数字的语言不太可能超出468930,但这不是对答案进行硬编码的借口。)
  • 您可以为序列选择基于0或基于1的索引(例如,取决于n = 1返回第一个元素,n = 2 返回第二个元素,依此类推;还是n = 0返回第一个元素,由您决定) ,n =第二个元素,依此类推)。
  • 对您使用的算法没有要求,也没有效率要求。您可以直接实现序列的定义(即使效率很低),也可以实现结果相同的另一种算法。

胜利条件

这是,所以最短的正确程序(以字节为单位)将获胜。


1
为什么不允许无限输出而不是输入呢?
约翰·德沃夏克

2
@JanDvorak:因为这迫使所有程序都使用生成每一项的算法;这种写问题的方法由答题者决定是否要这样做,或者是否要使用封闭形式的公式(假设有一个公式)。因此,它为解决问题提供了更多的策略选择。

1
我认为序列不存在,因为0,4是一个奇怪的偏移量
boboquack

1
@boboquack具有(0,3),(0,2),(1,4)或类似的变体,序列在经过几项后将保持不变。
丹尼斯

[math]标签对此有意义吗?
mbomb007 '17

Answers:


10

果冻13 12 9字节

rSạo4¥ð@¡

使用基于0的索引。

在线尝试!

怎么运行的

rSạo4¥ð@¡  Main link. No arguments. Implicit argument: 0

      ð    Collect everything to the left into a chain and start a new, dyadic one.
           The arity of the first chain is unknown at this point, as it isn't
           prefixed by ø, µ, or ð.
       @   Swap the arguments of the first chain. Swapping  arguments is only
           implemented for dyadic links, so this makes the chain dyadic.
        ¡  Read an integer n from STDIN and execute the chain n times. Taking the
           argument swap into account, the chain is executed first with 0 as left
           and right argument, then with the previous right argument as left
           argument and the previous return value as right argument.
           The return value of the last call is the return value of the quicklink
           and becomes the implicit output.

           Let's call the left argument x and the right argument y.
r            Range; yield [x, ..., y].
 S           Compute the sum of all integers in the range.
     ¥       Convert the two atoms to the left into a dyadic chain, and call that
             chain with arguments x and y.
   o4          Take the logical OR of x and 4, replacing a 0 with 4 and leaving
               positive integers untouched.
  ạ          Take the absolute difference of the sum to the left and the result of
             the logical OR to the right.

10

Python,66 60字节

感谢@Dennis削减了6个字节!

f=lambda n:n>2and(f(n-1)-~f(n-2))*(f(n-1)-f(n-2))/2or(5-n)*n

这不是有史以来最复杂的代码,但是它使用了我制定的公式:

在此处输入图片说明

x在右手边是f(n - 1),并且yf(n - 2)

说明:

a到的连续整数的总和b(包括)可以用以下公式描述:

amount * average

其中amount(数字的数量)的描述如下:

((a - b) - 1)

并且average(所有数字的平均值)描述如下:

(a + b) / 2

因此,完整的公式现在是:

  ((a - b) - 1)(a + b) / 2
= (a - b - 1)(a + b) / 2

我们实现这个公式,最终公式的方法是替代af(n - 1)bf(n - 2),基本上计算所有新的条款的总和,并添加另一个f(n - 1)(现在a)上,这是历届的总和。

结合在一起,我们得到:

  a + ((a - b - 1)(a + b) / 2)
= a + ((a^2 + ab - ab - b^2 - a - b) / 2)
= a + ((a^2 - b^2 - a - b) / 2)
= (a^2 - b^2 - a - b + 2a) / 2
= (a^2 - b^2 + a - b) / 2
= ((a + b)(a - b) + (a - b)) / 2
= (a + b + 1)(a - b) / 2

更换axby,和变戏法似的,你必须公式上方。



9

Mathematica,49个48字节

±2=4;±1=0;±n_:=Tr@Range@±(n-1)-Tr@Array[±#&,n-1]
(* or *)
±2=4;±1=0;±n_:=-Tr@Array[(k=±#)&,n-1]+Tr@Range@k

使用CP-1252编码。定义功能PlusMinus (±)。1个索引。

说明

±2=4;±1=0;±n_:=Tr@Range@±(n-1)-Tr@Array[±#&,n-1]

±2=4;±1=0;                                        (* Define ±1 and ±2 *)
          ±n_:=                                   (* ±n equals ... *)
               Tr@Range@±(n-1)                    (* Sum of (1, 2, ..., ±(n-1)) ... *)
                              -Tr@Array[±#&,n-1]  (* Minus the sum of previous terms *)

8

绿洲,11字节

码:

+>bc-*2/640


说明:

为了可视化f n的关系,让我们以f 5为例。为了计算f 5,让我们看一下以下总和:

1 + 2 + 3 + 5 + 7 + 8 + 9 + 10

粗体部分与f 4相同。的7 + 8 + 9 + 10的部分是范围[F N-2 + 1,F n-1个 - 1]。这使公式f n-1 +Σ[f n-2 +1 ... f n- 1-1]Wolfram link):

f n = 0.5×(f n-1 2 -f n-2 2 + f n-1 -f n-2

可以重写为:

f n = 0.5×((f n-1 -f n-2)(f n-1 + f n-2)+(f n-1 -f n-2))

f n = 0.5×((f n-1 -f n-2)(f n-1 + f n-2 +1))

我们将在代码中使用的公式是:


代码说明

640部分为我们提供了基本案例:

a(0) = 0
a(1) = 4
a(2) = 6

将要执行的代码(定义a(n)):

+>bc-*2/

+          # Add a(n + 1) and a(n + 2) implicitly
 >         # Add one to get a(n + 1) + a(n + 2) + 1
  b        # Push a(n + 1)
   c       # Push a(n + 2)
    -      # Subtract from each other
     *     # Multiply with the previous result
      2/   # Halve the result

在线尝试!


3
说明?这使我比其他许多答案更好奇。

@ ais523我添加了一个解释。
阿德南

5

朱莉娅39 33 32字节

!n=n<3?5n-n^2:sum(!(n-2)+1:!~-n)

从0开始。

感谢@Dennis,节省了6个字节。

感谢@GlenO,保存了一个字节。

在线尝试!

先前答案1-基于:

!n=n<4?2(n>1)n:sum(!(n-2)+1:!~-n)

在线尝试!

先前的非高尔夫答案基于1:

f(n)=n<4?n<2?0:n*2:sum(f(n-2)+1:f(n-1))

在线尝试!


1
要节省额外的字节,请使用n<3?5n-n^2:而不是n<4?2(n>1)n:-注意,尽管如此,它会切换为使用基于0的索引。
Glen O

@GlenO谢谢,节省了1个字节!
rahnema1

4

JavaScript(ES6),47个字节

f=(n,b=4,a=6)=>n?--n?f(n,a,(a+b+1)*(a-b)/2):b:0

使用f(n) = sum(range(f(n-2) + 1, f(n-1) + 1))n> 2 的递归关系。


4

的PowerShell84 89 88 87字节

$OFS='+'
for($a=0,4;$a.Count-le($n="$args")){$a+=("$(1..$a[-1])"|iex)-("$a"|iex)}$a[$n]

在线尝试!

说明

基于0的索引。仅可正常使用n = 6(在我的Windows计算机上,它因的堆栈溢出而崩溃n = 7)。

使用与JungHwan Min的答案相同的方法(范围的总和减去先前项的总和)。

在PowerShell中对范围/数组求和的时间很长,因此我正在使用一种将数组与 +以创建一个长表达式(如1+2+3+4...etc),然后通过iexInvoke-Expression)发送它。

因为我需要做两次,-join所以我不用设置特殊变量$OFS,它代表输出字段分隔符。当对数组进行字符串化时,这是用于连接元素的字符。它默认为空格。因此,通过将其设置为+(一次),我可以将替换$a-join'+'|iex"$a"|iex

一个简单的for循环一直进行下去,直到序列计数小于或等于输入整数,然后返回第$nth个元素。


@AdmBorkBork非常好!我真的认为这值得一个明确的答案。该方法是如此不同,以至于如果使用它,我将感觉不像我自己。
briantist

1
@AdmBorkBork不错,+ 1,我确实从中学到了一件事:循环;后不需要for。以前从未意识到。
briantist

3

MATL17 16字节

OKi:"tP:yX-sv]G)

1使用基于索引的索引。代码效率很低。因为n = 6它已经超出了在线编译器的内存限制。

在线尝试!

怎么运行的

O       % Push 0
K       % Push 4
i       % Input n
:"      % Do the following n times
  t     %   Push a copy of the top array (or number)
  P:    %   Range from 1 to the last element of array
  y     %   Push a copy of the second-top number/array
  X-    %   Set difference
  s     %   Sum
  v     %   Concatenate everything into a column vector
]       % End
G)      % Get n-th entry of the array. Implicity display

对于20个字节,以下版本避免了内存限制。但是仍然存在数据类型限制(double类型只能保证整数可以精确地表示到2^53),因此结果最多n = 8只能有效。

OKi:"t0)tQ*2/ys-v]G)

也可以在线尝试


2

Haskell,42个字节

f 0=0
f 1=4
f 2=6
f n=sum[1+f(n-2)..f$n-1]

在线尝试!

这直接实现复发,对n>2f(n)等于f(n-1)加开区间的距离之和f(n-2)f(n-1)这又是从等于半开区间的总和f(n-2),以f(n-1)包容性。

f(0) = 0
f(1) = 4
f(2) = 6 = 1+2+3
f(3) = 11 = 1+2+3+5 = 6 + 5 = 6 + sum]4,6[ = f(2)+ sum]f(1),f(2)[ = sum]f(1),f(2)]
...
f(n) = sum]f(n-2),f(n-1)] = sum[f(n-2)+1,f(n-1)]

2

Haskell,31个字节

m#s=m:s#sum[m+1..s]
((0:4#6)!!)

用法示例:((0:4#6)!!) 6-> 468930在线尝试!

简单递归,可跟踪m到目前为止的最大元素和下一个值s


每当我遇到新的挑战时,总会有人比我做过的XD更好地回答过haskell的问题
theonlygusti

我总是遇到一些数学难题,想想:“嘿,终于可以尝试haskell了!” CMD- F'Haskell'-哦,等等,这个答案...等等,什么?放弃haskell
theonlygusti

2

JavaScript中,123个 119字节

(a,i=x=y=0)=>{r=[0,4];while(r.length<a){x++;y=0;for(i=0;i<r[x];i++){if(!r.includes(i)){y+=i;}}r.push(y)}return r[a-1];}

在线尝试!此解决方案基于1 f(1) => 0


2

Perl 6  52 49 44  35个字节

{(|(0,4 X 0),{[+](^.[0])-.[1],.[0]+.[1]}...*)[$_;0]}

试试吧

{(0,(4,0),{[+](^.[0])-.[1],.[0]+.[1]}...*)[$_;0]}

试试吧

{(0,(4,0),{[+](^.[0])-.[1],.sum}...*)[$_;0]}

试试吧

{(0,4,6,{[+] $^a^..$^b}...*)[$_]}

试试吧

展开:

{ # bare block lambda with implicit parameter 「$_」

  (
    # generate a sequence

    0, 4, 6,      # seed the sequence

    {             # lambda with placeholder parameters 「$a」 「$b」
      [+]         # reduce with 「&infix:<+>」
          $^a     # n-2
          ^..     # Range that excludes the first value
          $^b     # n-1
    }
    ...           # keep generating values until
    *             # never stop

  )[ $_ ]         # get the value that was asked for (0 based index)
}

2

PowerShell77 73字节

param($n)$a=0,4;1..$n|%{$a+=(0..$a[-1]|?{$_-notin$a})-join'+'|iex};$a[$n]

在线尝试!

实现定义的算法,并且索引为0。输入6太多,TIO无法处理。

设置$a为一个数组[0,4]。从循环1来输入$n。在循环中,我们采用从0最大数字到最大数字的范围$a[-1],并使用Where-Object子句|?{...}仅提取那些不存在的数字。该数字数组-join+s 一起被ed ,然后馈入iex(的缩写Invoke-Expression,类似于eval)。然后将该值数组连接到的末尾$a。最后,我们退出循环,并$n在数组中取第th个数字。该数字留在管道上,并且输出是隐式的。



1

批处理,108字节

@if %1==0 echo 0&exit/b
@set/ab=4,a=6
@for /l %%i in (2,1,%1)do @set/ac=(a+b+1)*(a-b)/2,b=a,a=c
@echo %b%

我的JavaScript回答的端口。


1

dc,47个字节

?d1-scd/4*dd[d1+*2/r-dsn+dlnlc1-dsc0<x]sxlc0<xp

可以使用所需的整数,最大为计算机的内存容量。

在线尝试!

基于0的索引,在stdin上输入,在stdout上输出。(stderr上也有输出,将被忽略。)

样品运行:

$ for ((j=0;j<12;j++)){ echo -n "$j ";dc -f sumseq.dc <<<"$j";echo;} 2>/dev/null
0 0

1 4

2 6

3 11

4 45

5 969

6 468930

7 109947436950

8 6044219445882138462810

9 18266294354989892462984673364511343859409730

10 166828754731567805766174036610844675771635260155825966927845486666328\
837158267993261860

11 139159167026428037700805570917048711514125048327321592278500415852500\
422178720517080334552793040951056255170819719745908378102737875659900\
61575545777065220385544711322919415

这与bash中的以下解决方案使用相同的算法,(更)易读:

纯bash,60个字节

for((n=s=$1?4:0,k=1;k<$1;k++,s+=(n=n++*n/2-s))){ :;}
echo $n

但是bash程序仅适用于最多7个输入,因为它超出了整数溢出范围。



0

C#-74个字节

int A(int f){int e=4,i=1,s=0;for(;i++<f;)e=e*-~e/2-(s+=e);return f>0?e:0;}

取消高尔夫:

int A(int f)
{
    int e = 4, 
        i = 1, 
        s = 0; // e is the last element, s is the sum of all previous elements
    for (; i++ < f; ) // calculate for indexes 1 through max (don't need the index, just a correct number of loop cycles)
        e = e * -~e / 2 - (s += e); // -~e => (e + 1), higher precedence to remove parentheses
    return f > 0 ? e : 0; //handle input 0 as a special case, which is 0
}

可能有一种方法可以将其转换为lambda以保存更多内容,或者使用.Aggregate函数。尽管目前我没有进口货,所以也许它还可以进口吗?


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.