Ağır Kutu İstifleme


27

Bir sürü ağır kutunuz var ve bunları mümkün olan en az sayıda istifle istiflemek istiyorsunuz. Sorun, bir kutuya destekleyebileceğinden daha fazla kutu istifleyemeyeceğinizdir, bu nedenle ağır kutuların bir yığının altına gitmesi gerekir.

Meydan okuma

Giriş : Bütün kg cinsinden kutuların ağırlık listesi.

Çıktı : Kutu yığınlarını tanımlayan listelerin listesi. Bu, giriş için mümkün olan en az sayıda yığın kullanmalıdır. Geçerli bir yığın olması için, yığındaki her bir kutunun ağırlığı, üstündeki tüm kutuların ağırlığının toplamına eşit veya ondan daha büyük olmalıdır.

Geçerli yığın örnekleri

(Alttan üst sıraya)

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

Geçersiz yığın örnekleri

(Aşağıdan yukarıya doğru sırayla)

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

Örnek Test Durumları

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]]

Kurallar ve Varsayımlar

  • Standart G / Ç kuralları ve yasaklı boşluklar geçerlidir
  • G / Ç için uygun herhangi bir formatı kullanın
    • Yığınlar, tutarlı olduğunuz sürece yukarıdan aşağıya veya aşağıdan yukarıya doğru tanımlanabilir.
    • Yığın sırası (bu yığınların içindeki kutular yerine) önemli değildir.
    • Giriş kutularını önceden hazırlanmış bir liste olarak da alabilirsiniz. Genel sorun, sıralama tarafından çözülmediği sürece, sipariş girişi için özellikle önemli değildir.
  • Birden fazla optimum yığın konfigürasyonu varsa, bunlardan herhangi birini çıkartabilirsiniz.
  • En az bir kutu olduğunu ve tüm kutuların en az 1 kg ağırlığında olduğunu varsayabilirsiniz.
  • En azından 9,999 kg ağırlığa kadar desteklemelisiniz.
  • En az 9.999 toplam kutuya kadar destek vermelisiniz.
  • Aynı ağırlığa sahip kutular ayırt edilemez, bu nedenle hangi kutunun nerede kullanıldığını açıklamaya gerek yok.

Mutlu golf! İyi şanslar!


2
Ağırlıkları sıralı olarak alabilir miyiz? (artan veya azalan)
Arnauld,

4
"En az 9.999 toplam kutuya kadar destek vermelisiniz." Burada "destek" nasıl yorumlanır? Bu sadece programın bu türden bir giriş boyutu alabilmesi gerektiği anlamına mı geliyor, yoksa programın gerçekten makul bir sürede cevap vermesi gerektiği anlamına mı geliyor? İkincisi ise, sağlanan çok daha büyük test durumları olmalıdır.
Joel,

1
Önerilen test durumu: [8, 8, 8, 5, 1]->[[8, 8], [8, 5, 1]]
Hiatsu

3
Veya daha da iyisi: [8, 5, 8, 8, 1, 2]->[[8, 8], [8, 5, 2, 1]]
Hiatsu

2
@Arnauld, aksi halde bu bir cevaba ilgi çekici olmayan bir sıralama kodu ekleyeceğinden, evet diyeceğim , girişleri sıralı olarak alabilirsiniz.
Beefster

Yanıtlar:


5

Jöle , 19 bayt

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

Çevrimiçi deneyin!

Açıkça -3 Nick Kennedy sayesinde ...

Yukarıdan aşağıya

Açıklama:

Œ!ŒṖ€ẎṖÄ>ḊƲ€¬ȦƊƇ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]])

Açıklama ile daha az kompakt bir sürümde herhangi bir şans? Onlardan bir ton öğrendim.
John Keates

1
@JohnKeates Bir tane eklendi.
Outgolfer Erik

5

JavaScript (Node.js),  139 122  116 bayt

Girdilerin artan düzende sıralanmasını bekler.

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

Çevrimiçi deneyin!

Yorumlananlar

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 (yayın öncesi) , 178 bayt

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([])]

Çevrimiçi deneyin!

Şimdi tüm olası girişler üzerinde çalışıyor. (10'dan fazla kutu içeren TIO'da zaman aşımına uğradı, ancak doğru bir cevap hesapladı)


2
list(reversed(sorted(a)))sorted(a)[::-1]golf amaçlı olduğu gibi yazılabilir .
Joel,

Bunu, özellikle de çok fazla başka indeksleme yaptığımdan beri bileceğimi düşünürdünüz. Teşekkürler.
Hiatsu

Tıpkı bir yan not olarak, golf oynamak için olmasa da sorted(a, reverse=True)onun yerine daha iyi yazardı.
Joel,
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.