Codegolf Rainbow:整数配列の楽しみ


12

前書き:

ここに画像の説明を入力してください(出典:Wikipedia
虹を見ると、上から下まで常に色が付いています:
赤; オレンジ; 黄; 緑; 青い; インジゴ; バイオレット

これらの個々のリングを見ると、もちろん赤いリングは紫のリングよりも大きくなっています。
さらに、2つまたは3つの虹を同時に持つこともできます。

上記のすべてを組み合わせたものが、このチャレンジで使用されます。

チャレンジ:

正確にサイズ7の整数のリストを指定すると、各値は虹を形成するのに使用できる色の粒子を示し(最大のインデックスは赤を示し、最小のインデックスは紫を示します)、形成できる虹の量を出力します。

単一の整数虹には、少なくとも3xバイオレット、4xインディゴ、5xブルー、6xグリーン、7xイエロー、8xオレンジ、9xレッドが必要です。その上にある2番目の虹は、最初の虹の赤いリング(それらの間に1つのスペースを含む)よりもさらに大きくなるため、少なくとも11xバイオレット、12xインディゴ、13xブルー、14xグリーン、15xイエロー、16xオレンジが必要です、最初の虹が使用するものに加えて17x赤。3番目の虹は再び19xバイオレットで始まります。

例:

入力リスト:[15,20,18,33,24,29,41]
出力:2

どうして?15倍のバイオレットがあり、2つの虹には少なくとも3 + 11 = 14が必要です。20個のインディゴがあり、2つの虹に対して少なくとも4 + 12 = 16が必要です。など2つの虹に十分な色がありますが、3つの虹を形成するには十分ではないため、出力は2です。

チャレンジルール:

  • 入力配列の整数は、非負(>= 0)であることが保証されています。
  • 入力リストのサイズは正確に7であることが保証されています。
  • 虹が形成できないとき、出力します0
  • 入出力形式は柔軟です。STDINから取得できる10進数の整数のリストまたは配列にすることができます。出力は、任意の妥当な出力タイプの関数からの戻り値か、STDOUTに直接印刷できます。

n虹の量に必要な色の最小量:

Amount of Rainbows    Minimum amount per color
0                     [0,0,0,0,0,0,0]
1                     [3,4,5,6,7,8,9]
2                     [14,16,18,20,22,24,26]
3                     [33,36,39,42,45,48,51]
4                     [60,64,68,72,76,80,84]
5                     [95,100,105,110,115,120,125]
etc...

一般的なルール:

  • これはであるため、バイト単位の最短回答が優先されます。
    コードゴルフ言語では、非コードゴルフ言語で回答を投稿することを妨げないでください。「任意の」プログラミング言語の可能な限り短い答えを考えてみてください。
  • 回答には標準の規則が適用されるため、STDIN / STDOUT、適切なパラメーターと戻り値型、完全なプログラムを持つ関数/メソッドの使用が許可されます。あなたの電話。
  • デフォルトの抜け穴は禁止されています。
  • 可能であれば、コードのテストへのリンクを追加してください。
  • また、回答の説明を追加することを強くお勧めします。

テストケース:

Input:  [15,20,18,33,24,29,41]
Output: 2

Input:  [3,4,5,6,7,8,9]
Output: 1

Input:  [9,8,7,6,5,4,3]
Output: 0

Input:  [100,100,100,100,100,100,100]
Output: 4

Input:  [53,58,90,42,111,57,66]
Output: 3

Input:  [0,0,0,0,0,0,0]
Output: 0

Input:  [95,100,105,110,115,120,125]
Output: 5

Input:  [39525,41278,39333,44444,39502,39599,39699]
Output: 98

0,0,0,0,0,0,0しかし:((それは1ギャップロジックと適合しない)エッジケース
ジョナサン・アラン

回答:


8

Pyth、14バイト

thS.ef<b*+tkyy

テストスイート!

どうやって?

アルゴルティム

最初に、この答えの基になっている式を導き出しましょう。必要な量の色の粒子を与える関数を呼び出しましょう。ここで、nはレイヤーの数で、iは色のインデックスで、0から始まります。最初に、n 番目のレイヤーのみ(この場合、nは1から始まる)には、L n i = i + 3 + 8 n 1 色の粒子が必要です。これを念頭に置いて、それぞれの結果を合計しますC(n,i)ninthnL(n,i)=i+3+8(n1)各層 kのL k i L(k,i)k

C N i = i + 3 n+ 8

C(n,i)=(i+3)1st layer+(i+3+8)2nd layer++[i+3+8(n1)]nth layer
C N I = I + 3 のn + 8 N - 1 nは
C(n,i)=(i+3)n+8(0+1++n1)
C n i = n i + 3 + 4 n 4
C(n,i)=(i+3)n+8(n1)n2=(i+3)n+4n(n1)
C(n,i)=n(i+3+4n4)C(n,i)=n(4n+i1)

したがって、我々は今、可能層の最大数は、それを呼び出すことを知っている不等式満たさなければならない、C K IをI I、ここで、I iがあるI 番目の入力リストの要素。kC(k,i)IiIiith

実装

これは関数実装し、繰り返します(C.eし、入力リストに対して)をますはインデックス(0ベース)で、bは要素です。各値に対して、番組検索最初の正の整数Tは、そのため、B < C T I (の論理否定C T I B、我々は以前に推定状態)、次いで最小の結果とデクリメントを発見しますそれ。この方法では、代わりに最高の整数を探すのない条件を満たし、我々はその最低を検索しませんkbTb<C(T,i)C(T,i)b そこから1を引いて、オフセット1を補います。


3

パイソン264の 61バイト

lambda l:min(((16*v+i*i)**.5-i)//8for i,v in enumerate(l,-1))

オンラインでお試しください!


虹の各色は(3+i)+n*8レイヤーnと色に使用しますi(0 =紫など)

したがって、x層の合計は次のとおり(3*i)*x + 8*x*(x+1)です。

nを単純に解き、最小値を取ります。


保存済み:

  • -3バイト、ovsのおかげ

2
ああ、今私は...その応答を取得
ジョナサンFRECH


@ovs、ありがとう:)
TFeld

3

05AB1E18 17 16バイト

Magic Octopus Urnのおかげで-1バイト

[ND4*6Ý<+*¹›1å#N

オンラインでお試しください!

n個の虹に必要な色の量はn(4n + [-1、0、1、2、3、4、5])です。


[ND4*6Ý<+*¹›1å#N動作しますが、理由はわかりません。ただし、-1バイト。
魔法のタコ

よろしくお願いします!それは、カウンタ変数の代わりにループインデックスを使用するだけです。
Okx

私が行う必要はありません奇妙に思えN>ますが、持っていたのでthough-- ¾>前。
魔法のタコ

@MagicOctopusUrnカウンター変数を増やすコマンドは、カウンター変数をプッシュしません。
Okx

2

JavaScript(ES6)、49バイト

f=(a,n)=>a.some((v,k)=>v<4*n*n-~-k*n)?~n:f(a,~-n)

オンラインでお試しください!

どうやって?

Pnknk

P(n,k)=n(4n+(k1))=4n2+(k1)n

、すべての値を再帰的に試行しますnvkP(n,k

しかし、ゴルフの目的のために、私たちは最初からn === undefined負の値を使用しますn。不等式の右側はと評価されるため、最初の反復は常に成功しNaNます。したがって、最初の意味のあるテストは、の2番目のテストですn == -1



1

Excel VBA、78バイト

[A1:G1]VBEイミディエイトウィンドウの範囲から入力を受け取り、VBEイミディエイトウィンドウに出力する匿名関数。

[A2:G999]="=A1-(COLUMN()+8*ROW()-14)":[H:H]="=-(MIN(A1:G1)<0)":?998+[Sum(H:H)]

1

、21バイト

I⌊EA÷⁻X⁺X⊖κ²×¹⁶ι·⁵⊖κ⁸

オンラインでお試しください!リンクは、コードの詳細バージョンです。説明:各色で可能な虹の数を直接計算します。式Iは独立して導出されましたが、@ TFieldの式と同じであることが判明しました。

   A                   Input array
  E                     Map over values
          κ             Current index
         ⊖              Decrement
        X  ²            Square
               ι        Current index
            ×¹⁶         Multiply by 16
       ⁺                Add
      X         ·⁵      Square root
                   κ    Current index
                  ⊖     Decrement
     ⁻                  Subtract
    ÷               ⁸   Integer divide by 8
 ⌊                      Take the maximum
I                       Cast to string
                        Implicitly print


1

ゼリー、14 バイト

これは大変でした!

Ṃ+9s8Ṗ‘+\>Ż§ỊS

整数、可能な虹の数を生成する7つの整数のリストを受け入れる単項リンク。

オンラインでお試しください!または、テストスイートを参照してください。

どうやって?

残念ながら、ナイーブなメソッドは16バイトかかるようですが、そのようなメソッドの1つはですが Ṃɓ_J×¥H÷‘H<¬Ȧð€S、ここで使用されるメソッドははるかに効率的で短いことがわかります!

この方法は、紫外線バンドを含む、粒子数として十分なレインボースタックを構築します、可能なスタックごとに1を加算します。

可能かどうかのテストは、紫外線バンド粒子が必要であるがゼロが提供されていることを考えると、単一バンドのみが可能ではないことを確認することです。

Ṃ+9s8Ṗ‘+\>Ż§ỊS - Link list of integers    e.g. [0,0,0,0,0,0,0]        or [17,20,18,33,24,29,41]
Ṃ              - minimum                       0                         17
 +9            - add nine                      9                         26
   s8          - split into eights             [[1,2,3,4,5,6,7,8],[9]]   [[1,2,3,4,5,6,7,8],[9,10,11,12,13,14,15,16],[17,18,19,20,21,22,23,24],[25,26]]
     Ṗ         - discard the rightmost         [[1,2,3,4,5,6,7,8]]       [[1,2,3,4,5,6,7,8],[9,10,11,12,13,14,15,16],[17,18,19,20,21,22,23,24]]
      ‘        - increment (vectorises)        [[2,3,4,5,6,7,8,9]]       [[2,3,4,5,6,7,8,9],[10,11,12,13,14,15,16,17],[18,19,20,21,22,23,24,25]]
               -   (single rainbow counts, including ultra-violet bands, ready to stack)
       +\      - cumulative addition           [[2,3,4,5,6,7,8,9]]       [[2,3,4,5,6,7,8,9],[12,14,16,18,20,22,24,26],[30,33,36,39,42,45,48,51]]
               -   (stacked rainbow counts, including ultra-violet bands)
          Ż    - zero concatenate              [0,0,0,0,0,0,0,0]         [0,17,20,18,33,24,29,41]
               -   (we got given zero ultra-violet band particles!)
         >     - greater than? (vectorises)    [[1,1,1,1,1,1,1,1]]       [[1,0,0,0,0,0,0,0],[1,0,0,0,0,0,0,0],[1,1,1,1,1,1,1,1]]
               -   (always a leading 1 - never enough particles for the ultra-violet band)
           §   - sum each                      [8]                       [1,1,8]
               -   (how many bands we failed to build for each sacked rainbow?)
            Ị  - insignificant? (abs(X)<=1?)   [0]                       [1,1,0]
               -   (1 if we only failed to build an ultra-violet band for each sacked rainbow, 0 otherwise)
             S - sum                           0                         2
               -   (the number of rainbows we can stack, given we don't see ultra-violet!)

私は、Oxxのアルゴリズムを18バイトで圧縮するのは難しすぎたと思います...
Erik the Outgolfer


1

05AB1E、14バイト

žv*āÍn+tā-Ì8÷ß

オンラインでお試しください!

マップではなく、追加のループを必要としない閉じた形式のソリューション。これは、Pythの答えの式を05AB1Eのインデックス付け規則に一致するように適合させから、n、これはたまたまTFeldのアルゴリズムと一致します

Pythアルゴリズム⟶05AB1Eアルゴリズム

05AB1Eでこの課題を解決するために試すことができる多くの方法がありますので、それらのいくつかを試しましたが、これが最短であることが判明しました。05AB1Eが1-indexingを使用したことを念頭に置いて、Pythの回答から前述の式を適用すると、次のように関数を構築できます。

Cn=n+2+4nn1

入力の要素に等しく設定する()インデックスで そして、それを標準(2次)多項式表記で書くと、次のようになります。

4n2+n2=0

この等式は正確ではないことに注意してください(ただし、これをより正式に述べる方法は現在わかりません)、この方程式の解は浮動小数点数を生成しますが、正確な除算ではなくフロア除算を使用してこれを修正します後で。とにかく、私たちの議論を続けるために、あなたのほとんどはおそらくそのような方程式の解に非常に精通しているので、ここにそれがあります:

n12=2±22+168

なので 常にポジティブです 22+162ので、"ケースはあまり意味がありません。 2+2=42、これは負です 2 または 22+=4、これは一定です。したがって、我々はそれを結論付けることができますn によって与えられます:

n=2+22+168

これはまさにこの答えが実装する関係です。


1

C ++、127 125バイト

Kevin Cruijssenのおかげで2バイト削られました。

#include<cmath>
int f(int x[7]){size_t o=-1;for(int c=0,q;c<7;c++,o=o>q?q:o)q=(std::sqrt(--c*c-c+16*x[++c])-c+1)/8;return o;}

オンラインでお試しください!

この関数は、7つのintのCスタイルの配列を受け取り、intを返します。

アルゴリズムは非常に単純です(そして、既に何度も説明されているので、ここにもう1つの説明があります。主に私自身の視聴の喜びです)。させるc カラーインデックス(0c6)、形成するのに必要な粒子数 n番目 n1 その色の虹の部分は ycn=c+3+8n1、および形成する粒子の総量 n 色の虹の部分は Ycn=k=1nyck=nc+3+8nn12. Now we have a system of inequalities xcYc(n) (where xc is the elements of input array), which gives us a set of upper bounds on n:

n(c1)+(c1)2+16xc8
.

What is left is just iterate over xc and find the minimum.

Explanation:

#include <cmath> // for sqrt

int f (int x[7])
{
     // Note that o is unsigned so it will initially compare greater than any int
     size_t o = -1;
     // Iterate over the array
     for (int c = 0; c < 7; c++)
     {
         // calculate the bound
         int q = c - 1;
         q = (std::sqrt (q * q + 16 * x[c]) - q) / 8;

         // if it is less than previously found - store it
         o = o > q ? q : o;
     }
     return o;
 }

Hi there, welcome to PPCG! I don't know C++ too well, but I'm pretty sure you can golf this part: for(int c=0;c<7;c++){int q=c-1;q=(std::sqrt(q*q+16*x[c])-q)/8;o=o>q?q:o;} to this: for(int c=0,q;c<7;c++,o=o>q?q:o)q=(std::sqrt(--c*c-c+16*x[++c]))/8;. Also, could you perhaps provide a TIO-link with test code?
Kevin Cruijssen

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