重い箱の積み重ね


27

重い箱がたくさんあるので、できるだけ少ない数のスタックに積み重ねたいと思っています。問題は、サポートできる以上のボックスをスタックできないため、より重いボックスをスタックの最下部に配置する必要があることです。

チャレンジ

入力:箱の重量のリスト(kg単位)。

出力:ボックスのスタックを説明するリストのリスト。これは、入力に可能な限り少ない数のスタックを使用する必要があります。有効なスタックであるためには、スタック内の各ボックスの重量が、その上のすべてのボックスの重量の合計以上でなければなりません。

有効なスタックの例

(下から上へ)

  • [3]
  • [1、1]
  • [3、2、1]
  • [4、2、1、1]
  • [27、17、6、3、1]
  • [33、32、1]
  • [999、888、99、11、1]

無効なスタックの例

(下から上へ)

  • [1、2]
  • [3、3、3]
  • [5、5、1]
  • [999、888、777]
  • [4、3、2]
  • [4321、3000、1234、321]

テストケースの例

1

IN: [1, 2, 3, 4, 5, 6, 9, 12]
OUT: [[12, 6, 3, 2, 1], [9, 5, 4]]

2

IN: [87, 432, 9999, 1234, 3030]
OUT: [[9999, 3030, 1234, 432, 87]]

3

IN: [1, 5, 3, 1, 4, 2, 1, 6, 1, 7, 2, 3]
OUT: [[6, 3, 2, 1], [7, 4, 2, 1], [5, 3, 1, 1]]

4

IN: [8, 5, 8, 8, 1, 2]
OUT: [[8, 8], [8, 5, 2, 1]]

ルールと仮定

  • 標準I / Oルールと禁止された抜け穴が適用されます
  • I / Oに便利な形式を使用します
    • スタックは、一貫している限り、上から下または下から上に記述できます。
    • スタック内のボックスではなく、スタックの順序は関係ありません。
    • 入力ボックスを事前に並べられたリストとして使用することもできます。一般的な問題がソート自体で解決されない限り、入力にとって順序は特に重要ではありません。
  • スタックの最適な構成が複数ある場合は、それらのいずれかを出力できます
  • 少なくとも1つの箱があり、すべての箱の重量が少なくとも1 kg
  • 最低9,999 kgの重量をサポートする必要があります。
  • 最低で合計9,999個のボックスをサポートする必要があります。
  • 同じ重量のボックスは見分けがつかないため、どのボックスがどこで使用されたかを注釈する必要はありません。

ハッピーゴルフ!がんばろう!


2
ソートされた順序で重みを取得できますか?(昇順または降順)
Arnauld

4
「最小で合計9,999個のボックスをサポートする必要があります。」ここで「サポート」はどのように解釈されますか?それは、プログラムがそのようなサイズの入力を受け入れることができることを単に意味するのか、それともプログラムが妥当な時間内に実際に答えを提供することを意味するのか?後者の場合、はるかに大きなテストケースが提供されるはずです。
ジョエル

1
推奨されるテストケース:[8, 8, 8, 5, 1]->[[8, 8], [8, 5, 1]]
Hiatsu

3
またはそれ以上:[8, 5, 8, 8, 1, 2]->[[8, 8], [8, 5, 2, 1]]
Hiatsu

2
@Arnauld、そうでなければそれは答えに無意味なソートコードを追加するので、私はyesと言うつもりです、あなたはソートされた順序で入力を取り込むことができます。
ビーフスター

回答:


5

ゼリー、19バイト

Œ!ŒṖ€ẎṖÄ>ḊƲ€¬ȦƊƇLÞḢ

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

ニックケネディのおかげで明らかに-3 ...

上から下へ。

説明:

Œ!ŒṖ€ẎṖÄ>ḊƲ€¬ȦƊƇLÞḢ  Arguments: S (e.g. [1, 2, 3, 4, 5])
Œ!                   Permutations (e.g. [..., [4, 1, 5, 2, 3], ...])
    €                Map link over left argument (e.g. [..., [..., [[4, 1], [5], [2, 3]], ...], ...])
  ŒṖ                  Partitions (e.g. [..., [[4, 1], [5], [2, 3]], ...])
     Ẏ               Concatenate elements (e.g. [..., ..., [[4, 1], [5], [2, 3]], ..., ...])
               Ƈ     Filter by link (e.g. [..., [[1, 3], [2], [4], [5]], ...])
              Ɗ       Create >=3-link monadic chain (e.g. [[1], [], [0]])
           €           Map link over left argument (e.g. [[1], [], [0]])
          Ʋ             Create >=4-link monadic chain (e.g. [1])
      Ṗ                  Remove last element (e.g. [4])
       Ä                 Cumulative sum (e.g. [4])
         Ḋ               [Get original argument] Remove first element (e.g. [1])
        >                Greater than (vectorizes) (e.g. [1])
            ¬          Logical NOT (vectorizes) (e.g. [[0], [], [1]])
             Ȧ         Check if non-empty and not containing zeroes after flattening (e.g. 0)
                 Þ   Sort by link (e.g. [[[1, 2, 3], [4, 5]], ..., [[5], [4], [3], [2], [1]]])
                L     Length (e.g. 4)
                  Ḣ  Pop first element (e.g. [[1, 2, 3], [4, 5]])

説明付きのよりコンパクトなバージョンで何かチャンスはありますか?それらから多くを学びます。
ジョンキーツ

1
@JohnKeatesが追加しました。
Erik the Outgolfer

5

JavaScript(Node.js)、 139 122  116バイト

入力が昇順でソートされることを期待します。

f=(A,s=[],[n,...a]=A,r)=>n?s.some((b,i,[...c])=>n<eval(b.join`+`)?0:f(A,c,a,c[i]=[n,...b]))?S:r?0:f(A,[...s,[]]):S=s

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

コメント済み

f = (                        // f is a recursive function taking:
  A,                         //   A[] = input array
  s = [],                    //   s[] = list of stacks, initially empty
  [n,                        //   n   = next weight to process
      ...a] = A,             //   a[] = array of remaining weights
  r                          //   r   = recursion flag
) =>                         //
  n ?                        // if n is defined:
    s.some((b, i,            //   for each stack b[] at position i in s[],
                  [...c]) => //   using c[] as a copy of s[]:
      n < eval(b.join`+`) ?  //     if n is not heavy enough to support all values in b[]:
        0                    //       abort
      :                      //     else:
        f(                   //       do a recursive call:
          A, c, a,           //         using A[], c[] and a[]
          c[i] = [n, ...b]   //         with n prepended to c[i]
        )                    //       end of recursive call
    ) ?                      //   end of some(); if successful:
      S                      //     return S[]
    :                        //   else:
      r ?                    //     if this is a recursive call:
        0                    //       do nothing
      :                      //     else:
        f(A, [...s, []])     //       try again with an additional stack
  :                          // else:
    S = s                    //   success: save the solution in S[]

2

Python 3.8(プレリリース)、178バイト

f=lambda b,s=[[]]:(a for i in range(len(s))if b[0]>=sum(s[i])for a in f(b[1:],s[:i]+[[b[0]]+s[i]]+s[i+1:]+[[]]))if b else[s]
g=lambda a:(c:=sorted(f(a),key=len)[0])[:c.index([])]

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

すべての可能な入力で動作するようになりました。(10個以上のボックスがあるTIOではタイムアウトしますが、正しい答えを計算します)


2
list(reversed(sorted(a)))sorted(a)[::-1]ゴルフの目的として書くことができます。
ジョエル

特に他の多くのインデックス作成を行っているので、私は今までにそれを知っていると思うでしょう。ありがとう。
ハイツ

副次的な発言として、ゴルフではない場合は、sorted(a, reverse=True)代わりに書く方が良いでしょう。
ジョエル
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.