クリスマスの日は?


27

序文

よく知られているキャロル「クリスマスの十二日間」では、ナレーターに毎日いくつかのプレゼントが贈られます。歌は累積的です -各節で、新しいギフトが追加され、その前のギフトよりも1つ多くなります。1つのヤマウズラ、2つのカメの鳩、3つのフレンチヘンなど。

与えられた詩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ヤマウズラ)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のような言語では短くすることができると確信しています。
12Me21

1
これは、これまでで最も早いクリスマスの挑戦ですよね?:)
ここにユーザー名を挿入します

回答:


7

ゼリー7 6 バイト

デニスのおかげで-1バイト(ベクトル化された最小値«、および最初のインデックスを使用i

R+\⁺«i

TryItOnline

どうやって?

それほど効率的ではありません-リスト内の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*6i**3==n*6、大に近いi。に解決しi=(n*6)**(1/3)ます。必要に応じて床を切り下げ、1つずつ補正します。

ただし、境界上に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+1としてよりうまく書くことができますn*6=(i+1)**3-(i+1)。そこで、我々は最低見つけiたためi**3-i<n*6i1から増分するたびに、再帰呼び出しが1出力に追加されます。シフトを補うのではi=1なく、から開始しi=0ます。


いいね 私はこの方法でゴルフをすることを考えましたが、しませんでした。それにもかかわらず、私はシフトしてみます。それでも答えは異なります。
0WJYxW9FMN

1
わあ あなたの新しいものは素晴らしいです。
0WJYxW9FMN

1
26バイトバージョンは364で失敗し、テスト範囲から除外されます。**.333591バイト余分に機能します。
デニス

@デニスありがとう。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 a full featured MMO」のようになり、デニスが「Jelly、29 bytes」またはそのような愚かなものを投稿する予定です。
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

2番目の式は...と書くこともできます。

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

...ここで使用しているものです。

a(i - 1)k変数に実際に格納され、まで次の反復に渡されますk >= n

テストケース


これはこっそり短いです!よくやった。
FlipTack

@FlipTack私の最初の試みは、あなたが使用した式に基づいていました。計画を変更しなければなりませんでした。;-)
アーナウド

6

ルビー、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バイト

Lukeのおかげで-3バイト(関数をカリー化)

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

これは、このメタ投稿で説明されているように、名前のないラムダ関数に割り当てられfunc、呼び出されます。私の元の非カリー関数は次のようになります。func(220)()

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

期待どおりに1つの引数で呼び出された場合i = undefinednです。したがって、はより大きいことはありません。これ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)()
ルーク

@ルークの良い場所、私のカレー機能はそれほど短くありませんでした。それをあなた自身の答えとして投稿したくないのですか?
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

Mathematica、26バイト

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

名前のない関数は、非負の整数引数を取り、非負の整数を返します(ええ、1日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日、つまりこれまでの宇宙の年齢の約10倍です....


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)

@FlipTackのおかげで5バイト、@ xnorのおかげでさらに3 バイト節約されました


これが与えますf(220)=11、それはあるべきですf(220)=10
-xnor

ああ、私はPython 2を使用していました。これは、フロア分割を避けるために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 - 1することによりx、これを大幅に簡略化できます。

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入力に等しいか又はより大きい。

@xnorの答えに触発された13バイトのソリューション:

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、一日でRあるi番目の三角数、およびPあるi第四面体の数(プレゼントの数)。

他の言語でも同様の答えがあると思います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
回答を削除することで、ダウン投票を防ぐことができます。その後、回答を編集し、修正後に削除を取り消すことができます。
ライコニ

また、これでもチャレンジが要求することを行いません。の入力221はクラッシュします。
-FlipTack

TIOでこれをテストしましたが、すべての入力でクラッシュします。これは私の問題ですか、これは他の誰かに起こっていますか?

それは私のために働いた。もう一度テストします。
0WJYxW9FMN


1

Haskell、21 23バイト

floor.(**(1/3)).(*6.03)

編集:xnorが指摘したように、元の解決策(floor.(/0.82).(**0.4))はクリスマスの日の間は機能しませんでした


これは、例えば221のために、多くの入力に間違った答えを与える
XNOR

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にダイヤルダウンしましたが、最終テストケースで失敗します。


弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.