是圣诞节的哪一天?


27

前言

在著名的颂歌《圣诞节的十二天》中,叙述者每天都会收到几份礼物。这首歌是累积性的 -在每节经文中,都会添加新的礼物,其数量要比之前的礼物多一个。一只Part,两只海龟鸽子,三只法国母鸡,等等。

在任何给定的诗句N处,我们都可以通过找到第N四面体数来计算歌曲中当前礼物的累积总和,从而得出结果:

Verse 1: 1
Verse 2: 4
Verse 3: 10
Verse 4: 20
Verse 5: 35
Verse 6: 56
Verse 7: 84
Verse 8: 120
Verse 9: 165
Verse 10: 220
Verse 11: 286
Verse 12: 364

例如,在第4节之后,我们有4 *(1 part)3 *(2斑鸠)2 *(3只法国母鸡)1 *(4只叫鸟)。通过总结这些,我们得到4(1) + 3(2) + 2(3) + 1(4) = 20

挑战

您的任务是编写一个程序或函数,给定一个表示存在数364≥p≥1的礼物的正整数,确定它是圣诞节的哪一天(圣诞节)。

例如,如果p = 286,我们就在圣诞节的第11天。但是,如果p = 287,则礼物的下一个负载已经开始,这意味着它是第12天。

从数学上讲,这是查找下一个四面体数,并返回其在整个四面体数序列中的位置。

规则:

  • 这是,因此最短的解决方案(以字节为单位)获胜。
  • 适用标准高尔夫漏洞。
  • 说到几天,您的程序必须为1索引。
  • 您提交的内容必须是完整的程序或功能,但不能是摘要。

测试用例

1   ->  1
5   ->  3
75  ->  7
100 ->  8
220 ->  10
221 ->  11
364 ->  12

5
万一它对任何人都有帮助,第n个四面体数也是前n个三角数之和。
DJMcMayhem

这可能会有所帮助:x=>{while(x>p)p+=r+=++i;return i},我敢肯定,可以像JavaScript这样的语言将其缩短。
17Me21年

1
这是有史以来最早的圣诞节挑战,对吗?:)
insertusernamehere

Answers:


7

果冻7 6 字节

多亏了丹尼斯(Dennis),使用了-1个字节(使用向量化的最小值«和第一个索引i

R+\⁺«i

在线试用

怎么样?

效率不是很高-在列表中按顺序计算第1至第n个四面体数,并返回等于或大于1的第一个从1开始的索引。

R+\⁺«i - main link: n
R      - range                          [1,2,3,4,...,n]
 +\    - cumulative reduce by addition  [1,3,6,10,...,sum([1,2,3,4,...n])] i.e. triangle numbers
   ⁺   - duplicate previous link - another cumulative reduce by addition
                                        [1,4,10,20,...,nth tetrahedral]
    «  - min(that, n)                   [1,4,10,20,...,n,n,n]
     i - first index of n (e.g. if n=12:[1,4,10,12,12,12,12,12,12,12,12,12] -> 4)

前7个byters使用降低范围[0,1,2,3,...,n-1]和计数四面体小于n: ,
Ḷ+\⁺<µS
Ḷ+\⁺<ḅ1
Ḷ+\⁺<ċ1
Ḷ+\⁺<¹S


19

Python,27个字节

lambda n:int((n*6)**.33359)

在线尝试!

直接公式,带有一些曲线拟合,与Level River St.发现的原始公式相同。

位移方程对大i**3-i==n*6接近。它解决了。根据需要让地板向下滚动,以补偿一对一的偏差。i**3==n*6ii=(n*6)**(1/3)

但是,边界上有6个输入,误差使该误差小于应该在其之上的整数。所有这些都可以通过稍微增加指数来解决,而不会引入更多错误。


Python,38个字节

f=lambda n,i=1:i**3-i<n*6and-~f(n,i+1)

n=i*(i+1)*(i+2)/6四面体数的公式可以更好地写i+1n*6=(i+1)**3-(i+1)。所以,我们找到最低i为此i**3-i<n*6。每次我们i从1开始递增时,递归调用都会添加1到输出中。从开始i=1而不是i=0补偿转变。


真好 我曾想过以这种方式打高尔夫球,但我没有这么做。不过,我会尝试转移;我们的答案仍然会有所不同。
0WJYxW9FMN

1
哇。您的新产品令人赞叹。
0WJYxW9FMN

1
26字节版本的364失败,不包括在测试范围内。**.33359工作一个额外的字节。
丹尼斯,

@丹尼斯谢谢。Python独家范围再次出现!
xnor

1
lambda n:n**.3336//.5501保存一些字节。
丹尼斯,

10

J,12个字节

2>.@-~3!inv]

可能有一种更高级的方法,但这是使用J的内置函数反转的绝好机会。

在线尝试!

怎么运行的

2>.@-~3!inv]  Monadic verb. Argument: n

           ]  Right argument; yield n.
      3       Yield 3.
       !inv   Apply the inverse of the ! verb to n and 3. This yields a real number.
              x!y computes Π(y)/(Π(y-x)Π(x)), where Π is the extnsion of the 
              factorial function to the real numbers. When x and y are non-negative
              integers, this equals yCx, the x-combinations of a set of order y.
 >.@-~        Combine the ceil verb (>.) atop (@) the subtraction verb (-) with
              swapped arguments (~).
2             Call it the combined verbs on the previous result and 2.


7

果冻,7个字节

R‘c3<¹S

在线尝试!

怎么运行的

R‘c3<¹S  Main link. Argument: n

R        Range; yield [1, ..., n].
 ‘       Increment; yield [2, ..., n+1].
  c3     Combinations; yield [C(2,3), ..., C(n+1,3)].
    <¹   Yield [C(2,3) < n, ..., C(n+1,3) < n].
      S  Sum; count the non-negative values of k for which C(k+2,3) < n.

2
有时我想知道,果冻不能做什么?
草帽鸡

1
这些天之一,有人会喜欢“ Code Golf一个功能齐全的MMO”,而Dennis会张贴“ Jelly,29字节”或类似的东西。
corsiKa

6

JavaScript(ES6),33个字节

n=>(F=k=>k<n?F(k+3*k/i++):i)(i=1)

基于递归公式:

a(1) = 1
a(i) = (i + 3) * a(i - 1) / i

第二个表达式也可以写成...

a(i) = a(i - 1) + 3 * a(i - 1) / i

...这就是我们在这里使用的那个。

a(i - 1)实际上存储在k变量中,并传递到下一个迭代,直到k >= n

测试用例


偷偷摸摸的短!做得好。
FlipTack

@FlipTack我的第一次尝试是基于您使用的公式。我不得不改变计划。;-)
Arnauld

6

Ruby,26个字节

编辑:备用版本,仍为26个字节

->n{(n**0.3333*1.82).to_i}

原始版本

->n{((n*6)**0.33355).to_i}

利用的事实T(x) = x(x+1)(x+2)/6 = ((x+1)**3-(x+1))/6非常接近(x+1)**3/6

该函数只需乘以6,即可找到经过微调的立方根版本(需要5个小数位),然后将结果截断为整数。

测试程序和输​​出

f=->n{((n*6)**0.33355).to_i}
[1,4,10,20,35,56,84,120,165,220,286,364].map{|i|p [i,f[i],f[i+1]]}

[1, 1, 2]
[4, 2, 3]
[10, 3, 4]
[20, 4, 5]
[35, 5, 6]
[56, 6, 7]
[84, 7, 8]
[120, 8, 9]
[165, 9, 10]
[220, 10, 11]
[286, 11, 12]
[364, 12, 13]

0.3336似乎适用于原始版本。(编辑:没关系,丹尼斯指出我忘记了364。)
xnor

5

JavaScript,36 33字节

-3个字节,感谢Luke(使函数成为咖喱)

n=>f=i=>n<=i/6*-~i*(i+2)?i:f(-~i)

这是一个未命名的lambda函数,可以分配给该函数func并使用调用func(220)(),如本meta post中所述。我原来的非咖喱函数如下所示:

f=(n,i)=>n<=-~i*i/6*(i+2)?i:f(n,-~i)

此答案使用以下事实可以发现x个四面体数:

f(x)= x / 6(x + 1)(x + 2)

提交的工作方式是递归地增加i,并找到tetrahedral(i),直到大于或等于n(给定的礼物数量)为止。

当以预期的一个参数调用时i = undefined,因此不大于n。这意味着f(n,-~i)将执行并-~undefined计算为1,从而启动递归。


测试片段:

func = n=>f=i=>n<=i/6*-~i*(i+2)?i:f(-~i)

var tests = [1, 5, 75, 100, 220, 221, 364];
tests.forEach(n => console.log(n + ' => ' + func(n)()));


我正要发布完全相同的答案。打我2分钟。做得好!
路加福音

您可以通过以下操作节省3个字节:n=>g=i=>n<=i/6*++i*++i?i-2:g(~-i)。你会这样称呼f(2)()
路加福音

@Luke好地方,我的咖喱功能不是那么短。您确定不想将其发布为自己的答案吗?
FlipTack

不,如果我们使用其他公式,我会这样做,但是现在我们的解决方案几乎相同。我希望可以帮助您达到与Arnauld相同的水平。;-)
路加福音

3
i=>n<=i美丽;-)
ETHproductions

3

MATL12 11字节

`G@H+IXn>}@

在线尝试!

说明

`       % Do...while
  G     %   Push input, n
  @     %   Push iteration index (1-based), say m
  H     %   Push 2
  +     %   Add
  I     %   Push 3
  Xn    %   Binomial coefficient with inputs m+2, 3
  >     %   Is n greater than the binomial coefficient? If so: next iteration
}       %   Finally (execute after last iteration, before exiting the loop)
  @     %   Push last iteration index. This is the desired result
        % End (implicit)
        % Display (implicit)

2

05AB1E,10个字节

XµNÌ3c¹‹_½

在线尝试!

说明

Xµ          # loop until counter equals 1
  NÌ3c      # binomial_coefficient(iteration_index+2,3)
      ¹     # push input
       ‹_   # not less than
         ½  # if true, increment counter
            # output last iteration index

1
哇,binom比聪明的人聪明得多[N2Ý+P6÷¹Q#N>
魔术章鱼缸

2

Pyke,11个字节

#3RL+B6f)lt

在这里尝试!

#3RL+B6f)   -  while rtn <= input as i:
 3RL+       -     i+j for j in range(3)
     B      -    product(^)
      6f    -   ^/6
         lt - len(^)-1

2

Mathematica,26个字节

(0//.i_/;i+6#>i^3:>i+1)-1&

未命名函数采用非负整数参数并返回非负整数(是的,它也适用于day 0)。我们想要找到i输入#最多的最小整数i(i+1)(i+2)/6,这是第一i天给出的礼物数量的公式。通过轻度的代数欺骗,不等式# ≤ i(i+1)(i+2)/6等于(i+1) + 6# ≤ (i+1)^3。因此,结构0//.i_/;i+6#>i^3:>i+1以a开头,0并且1只要i+6#>i^3满足测试就不断增加;然后(...)-1&减去1在末尾(而不是在不等式内使用带括号的字节)。

如果我们继续圣诞节的12天,我们可以在大约65536天之前处理内置的递归限制以//.中止该过程,这大约是4.7 * 10 ^ 13天,大约是迄今为止宇宙年龄的十倍....


2

J,9个字节

I.~3!2+i.

在线尝试!

这比使用阶乘的逆运算效率更低,但碰巧更短。

例如,如果输入整数为n = 5,则设置范围[2, n+1]

2 3 4 5 6 choose 3
0 1 4 10 20

这些是前5个四面体数字。下一步是确定n属于哪个间隔(天)。有n +1 = 6个间隔。

0 (-∞, 0]
1 (0, 1]
2 (1, 4]
3 (4, 10]
4 (10, 20]
5 (20, ∞)

那么n = 5属于区间3,即(4, 10]结果为3。

说明

I.~3!2+i.  Input: integer n
       i.  Range [0, n)
     2+    Add 2 to each
   3!      Combinations nCr with r = 3
I.~        Interval index of n

2

Python,43个字节

f=lambda n,i=0:n*6>-~i*i*(i+2)and-~f(n,i+1)

保存5个字节感谢@FlipTack和另外3感谢@xnor


这给出了f(220)=11,应该是f(220)=10
xnor

哦,我使用的是Python2。这需要Python 3来避免地板分割,尽管也许您可以在另一侧进行乘法运算以使其与版本无关。
xnor

我想你可以做到 and-~f(n,i+1)and f(n,i+1)or i。奇怪的是,当递归计算一个变量而不是返回它,而是递归地增加输出时,它通常会更短。
xnor

2

Japt,12个字节

1n@*6§X³-X}a

在线测试!一次验证所有测试用例

怎么运行的

1n@*6§X³-X}a  // Implicit: U = input integer
  @       }a  // Find the smallest non-negative integer X which satisfies this condition:
      X³-X    //   (X ^ 3) - X
     §        //   is greater than or equal to
   *6         //   U * 6.
1n            // Subtract 1 from the result.
              // Implicit: output result of last expression

这是其他一些答案正在使用的四面体公式的简化:

f(x) = (x)(x + 1)(x + 2)/6

通过替换x - 1x,我们可以大大简化此过程:

f(x) = (x - 1)(x)(x + 1) / 6
f(x) = (x - 1)(x + 1)(x) / 6
f(x) = (x^2 - 1)(x) / 6
f(x) = (x^3 - x) / 6

因此,正确的结果比最小整数小1 x,从而(x^3 - x) / 6大于或等于输入。

13字节的解决方案,灵感来自@xnor的答案

p.3335 /.55 f

@ETHproductions和我一起玩的其他一些解决方案

J+@*6§X³-X}a 
@*6§X³-X}a -1
@§X/6*°X*°X}a 
_³-V /6¨U}a -1
§(°V nV³ /6?´V:ß
§(°VV³-V /6?´V:ß

在这里测试。


1

SmileBASIC,43个字节

INPUT X
WHILE X>P
I=I+1
R=R+I
P=P+R
WEND?I

I是天,Ri第三角数,并且Pi第四面体数(礼物数)。

我认为用另一种语言回答类似: x=>{while(x>p)p+=r+=++i;return i}可能会很好。


?I最后要不要,不是吗?
尼克·马特奥

1

Python 3,48 46字节

f=lambda x,i=1:f(x,i+1)if(i+3)*i+2<x/i*6else i

@FlipTack Argh!我会在几秒钟内修复它。请没人投票。
0WJYxW9FMN

6
您可以通过删除答案来防止任何反对。然后,您将能够编辑答案,并在确定后取消删除它。
Laikoni

同样,这仍然不能满足挑战的要求。输入221将会使其崩溃。
FlipTack

我已经在TIO上对其进行了测试,并且所有输入均崩溃。这是我的问题,还是其他任何人都发生了?

它为我工作。我会再测试一次。
0WJYxW9FMN

1

Mathematica,31个 25字节

Floor@Root[x^3-x-6#+6,1]&


0

批处理,69字节

@set/an=d=t=0
:l
@set/at+=d+=n+=1
@if %t% lss %1 goto l
@echo %n%

手动计算四面体数。




0

QBIC,19个字节

这会盗用@xnor的公式:

:?int((a*6)^.33359)

我尝试将分辨率调低到.3336以保存一个字节,但是在最终的测试用例上失败了。


0

Bash + bc,44个字节

bc -l <<< "f=e(.33359*l($1*6));scale=0;f/1"
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.