小石の山と山


8

私の仕事は、小石を三角形の山に積み上げることです。私はこれを1世紀だけ続けてきましたが、すでにかなり退屈です。最悪の部分は、すべての杭にラベルを付けることです。小石を最大サイズの山に分解する方法は知っていますが、山の数を最小限に抑えたいです。手伝ってくれますか?

仕事

整数を指定すると、それを最小数の三角数に分解し、その最小数を出力します。

三角形の数

三角数は、ある値について、最初のn自然数の合計として表すことができる数ですn。したがって、最初のいくつかの三角形の数は

1 3 6 10 15 21 28 36 45 55 66 78 91 105

例として、入力がであるとしましょう9。三角数ではないので、三角数の和として表現できません1。したがって、三角形の数の最小値は2であり、で取得でき[6,3]、の正しい出力が得られ2ます。

別の例として、入力がであるとしましょう12。最も明白な解決策は、貪欲なアルゴリズムを使用し、一度に最大の三角形の数を削除して[10,1,1]、の出力とを生成することです3。ただし、より適切な解決策があります:[6,6]、の正しい出力を生成します2

テストケース

in out
1 1
2 2
3 1
4 2
5 3
6 1
7 2
8 3
9 2
10 1
11 2
12 2
13 2
14 3
15 1
16 2
17 3
18 2
19 3
20 2
100 2
101 2
5050 1

ルール

  • 入力整数は1から言語の最大整数までです。
  • 私は小石で任意の言語をエミュレートできます。はそれを追跡する小石しか持っていないので、コードをできるだけ小さくしたいと思います。したがって、これはなので、各言語で最も短いコード優先されます。

小石でいっぱいのサンドボックス
fireflame241 2017



OEIS A057945と混同しないでください(最初の違いはで発生しますn = 12)。
マーティンエンダー2017

回答:


3

Retina57 49バイト

.+
$*
(^1|1\1)+$
1
(^1|1\1)+(1(?(2)\2))+$
2
11+
3

オンラインでお試しください!三三角数字への私の答えに基づいています。3行目^(^1|1\1)*$をゼロ入力をサポートするように変更します。編集:@MartinEnderのおかげで、8バイト(ただし、おそらくそれ以上)が節約されました。


1第2ステージではグループは必要ありません。グループ13第3ステージも必要ありません。
マーティンエンダー2017

そして、((?(2)1\2|1))に短縮できます(1(?(2)\2))
マーティンエンダー2017

実際には、次のような奇妙なことを行うと、さらに3バイト短くなります^((?<2>)(1\2)+){2}$。または^(()(?<2>1\2)+){2}$、必要に応じて。
マーティンエンダー2017

@MartinEnder最後のバージョンでは頭が痛くなりますが、リンクされた回答に2番目のコメントを使用できたので、とても良かったです。
ニール

最後のものは、奇妙な条件付き前方参照がないため、標準的なアプローチよりも実際には単純だと思います。
マーティンエンダー2017

1

Mathematica、53バイト

Min[Plus@@@Table[$($+1)/2,{$,#+1}]~FrobeniusSolve~#]&

このコードは非常に遅いです。この関数をテストする場合は、代わりに次のバージョンを使用してください。

Min[Plus@@@Table[$($+1)/2,{$,√#+1}]~FrobeniusSolve~#]&

Wolfram Sandboxでお試しください

説明

Min[Plus@@@Table[$($+1)/2,{$,#+1}]~FrobeniusSolve~#]&  (* input: n *)

           Table[$($+1)/2,{$,#+1}]                     (* Generate the first n triangle numbers *)
                                  ~FrobeniusSolve~#    (* Generate a Frobenius equation from the *)
                                                       (* triangle numbers and find all solutions. *)
    Plus@@@                                            (* Sum each solution set *)
Min                                                    (* Fetch the smallest value *)

1

ゼリー(フォーク)、9バイト

æFR+\$S€Ṃ

これは、非効率的なFrobeniusソルバアトムを実装したフォークに依存しています。最後に触れてからもう一年になるとは思えない。

説明

æFR+\$S€Ṃ  Input: n
æF         Frobenius solve with
     $     Monadic chain
  R          Range, [1, n]
   +\        Cumulative sum, forms the first n triangle numbers
      S€   Sum each
        Ṃ  Minimum

ダーンフロベニウスが原子を解くと、通常のジェリーソリューションよりも6バイト
も大きくなり

@EriktheOutgolfer私はそれを終えて、それを引っ張る必要があります。
マイル

1

R69 58バイト

function(n)3-n%in%(l=cumsum(1:n))-n%in%outer(c(0,l),l,"+")

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

説明:

function(n){
 T <- cumsum(1:n)             # first n triangular numbers  [1,3,6]
 S <- outer(c(0,T),T,"+")     # sums of the first n triangular numbers,
                              # AND the first n triangular numbers [1,3,6,2,4,7,4,6,9,7,9,12]
 3 - (n %in% S) - (n %in% T)  # if n is in T, it's also in S, so it's 3-2: return 1
                              # if n is in S but not T, it's 3-1: return 2
                              # if n isn't in S, it's not in T, so 3-0: return 3
}


0

JavaScript(ES6)、75 63 61バイト

f=(n,x=y=0)=>y<n+2?x*x+y*y-8*n-2+!y?f(n,x<n+2?x+1:++y):2-!y:3

どうやって?

次のプロパティを使用します。

  • フェルマーの多角形数定理によれば、正の整数は最大3つの三角形の数の合計として表すことができます。
  • 数値tは、8t + 1が完全な正方形である場合にのみ三角形です(これは、t = n(n + 1)/ 2を解くことによって簡単に証明できます)。

正の整数nが与えられた場合、以下を見つけることができるかどうかをテストすることで十分です。

  • x> 0、つまり 8n + 1 =x² n自体は三角形)
  • またはx> 0およびy> 0 、つまり8n + 2 =x²+y²nは2つの三角数の合計)

両方のテストが失敗した場合、nは3つの三角形の数値の合計でなければなりません。

f = (n, x = y = 0) =>                 // given n and starting with x = y = 0
  y < n + 2 ?                         // if y is less than the maximum value:
    x * x + y * y - 8 * n - 2 + !y ?  //   if x² + y² does not equal 8n + 2 - !y:
      f(                              //     do a recursive call with:
        n,                            //       - the original input n
        x < n + 2 ? x + 1 : ++y       //       - either x incremented or
      )                               //         y incremented and x set to y
    :                                 //   else:
      2 - !y                          //     return either 1 or 2
  :                                   // else:
    3                                 //   return 3

テストケース


0

MATL、15バイト

`G:Ys@Z^!XsG-}@

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

説明

`         % Do...while
  G:      %   Push range [1 2 3 ... n], where n is the input
  Ys      %   Cumulative sum: gives [1 3 6 ... n*(n+1)/2]
  @Z^     %   Cartesian power with exponent k, where k is iteration index
          %   This gives a k-column matrix where each row is a Cartesian tuple
  !Xs     %   Sum of each row. Gives a column vector
  G-      %   Subtract input from each entry of that vector. This is the loop 
          %   condition. It is truthy if it only contains non-zeros
}         % Finally (execute before exiting the loop)  
  @       %   Push iteration index, k. This is the output
          % End (implicit). Proceeds with next iteration if the top of the
          % stack is truthy

0

Kotlin176 154バイト

提出

{var l=it
var n=0
while(l>0){n++
val r=mutableListOf(1)
var t=3
var i=3
while(t<=l){r.add(t)
t+=i
i++}
l-=r.lastOrNull{l==it|| r.contains(l-it)}?:r[0]}
n}

美化

{
    // Make a mutable copy of the input
    var l=it
    // Keep track of the number of items removed
    var n=0
    // While we still need to remove pebbles
    while (l > 0) {
        // Increase removed count
        n++
        // BEGIN: Create a list of triangle numbers
        val r= mutableListOf(1)
        var t = 3
        var i = 3
        while (t<= l) {
            // Add the number to the list and calculate the next one
            r.add(t)
            t+=i
            i++
        }
        // END: Create a list of triangle numbers
        // Get the fitting pebble, or the biggest one if none fit or make a perfect gap
        l -= r.lastOrNull {l==it|| r.contains(l-it)} ?: r[0]
    }
    //Return the number of pebbles
    n
}

テスト

var r:(Int)->Int =
{var l=it
var n=0
while(l>0){n++
val r=mutableListOf(1)
var t=3
var i=3
while(t<=l){r.add(t)
t+=i
i++}
l-=r.lastOrNull{l==it|| r.contains(l-it)}?:r[0]}
n}

data class TestData(val input:Int, val output:Int)

fun main(args: Array<String>) {
    val tests = listOf(
            TestData(1,1),
            TestData(2,2),
            TestData(3,1),
            TestData(4,2),
            TestData(5,3),
            TestData(6,1),
            TestData(7,2),
            TestData(8,3),
            TestData(9,2),
            TestData(10,1),
            TestData(11,2),
            TestData(12,2),
            TestData(13,2),
            TestData(14,3),
            TestData(15,1),
            TestData(16,2),
            TestData(17,3),
            TestData(18,2),
            TestData(19,3),
            TestData(20,2),
            TestData(100,2),
            TestData(101,2),
            TestData(5050,1)
    )
    tests.map { it to r(it.input) }.filter { it.first.output != it.second }.forEach { println("Failed for ${it.first}, output ${it.second} instead") }
}

TryItOnline

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