Impilamento pesante della scatola


27

Hai un sacco di scatole pesanti e vuoi impilarle nel minor numero possibile di pile. Il problema è che non puoi impilare più scatole su una scatola di quelle che può supportare, quindi le scatole più pesanti devono andare in fondo a una pila.

La sfida

Input : un elenco di pesi di scatole, in kg interi.

Output : un elenco di elenchi che descrivono le pile di scatole. Questo deve usare il minor numero possibile di stack per l'input. Per essere una pila valida, il peso di ogni scatola nella pila deve essere maggiore o uguale alla somma del peso di tutte le scatole sopra di essa.

Esempi di stack validi

(In ordine dal più basso al più alto)

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

Esempi di stack non validi

(In ordine dal basso verso l'alto)

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

Esempi di casi di test

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

Regole e presupposti

  • Si applicano le regole I / O standard e le lacune vietate
  • Utilizzare qualsiasi formato utile per l'I / O
    • Le pile possono essere descritte dall'alto verso il basso o dal basso verso l'alto, purché tu sia coerente.
    • L'ordine delle pile (anziché le scatole all'interno di quelle pile) non ha importanza.
    • Puoi anche prendere le caselle di input come un elenco predefinito. L'ordine non è particolarmente importante per l'input, a condizione che il problema generale non venga risolto dall'ordinamento stesso.
  • Se esiste più di una configurazione ottimale di stack, è possibile emetterne uno qualsiasi
  • Si può presumere che ci sia almeno una scatola e che tutte le scatole pesino almeno 1 kg
  • È necessario supportare pesi fino a 9.999 kg, come minimo.
  • Devi supportare fino a 9.999 caselle totali, come minimo.
  • Le scatole dello stesso peso sono indistinguibili, quindi non è necessario annotare quale scatola è stata utilizzata dove.

Buon golf! In bocca al lupo!


2
Possiamo prendere i pesi in ordine? (crescente o decrescente)
Arnauld

4
"Devi supportare fino a 9.999 scatole in totale, almeno." Come viene interpretato il "supporto" qui? Significa semplicemente che il programma dovrebbe essere in grado di accettare una tale dimensione di input o significa che il programma dovrebbe effettivamente fornire la risposta in un ragionevole lasso di tempo? Se è quest'ultimo, dovrebbero essere previsti casi di test molto più ampi.
Gioele il

1
Caso di prova suggerito: [8, 8, 8, 5, 1]->[[8, 8], [8, 5, 1]]
Hiatsu

3
O ancora meglio: [8, 5, 8, 8, 1, 2]->[[8, 8], [8, 5, 2, 1]]
Hiatsu

2
@Arnauld, poiché altrimenti ciò aggiungerebbe un codice di ordinamento poco interessante a una risposta, sto per dire di , puoi prendere gli input in ordine.
Beefster

Risposte:


5

Gelatina , 19 byte

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

Provalo online!

Ovvio -3 grazie a Nick Kennedy ...

Dall'alto al basso.

Spiegazione:

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

Qualche possibilità in una versione meno compatta con spiegazione? Ho imparato un sacco da quelli.
John Keates,

1
@JohnKeates Aggiunto uno.
Erik the Outgolfer,

5

JavaScript (Node.js),  139 122  116 byte

Prevede l'ingresso ordinato in ordine crescente.

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

Provalo online!

Commentate

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 (pre-release) , 178 byte

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

Provalo online!

Ora funziona su tutti gli input possibili. (Timeout su TIO con più di una decina di caselle, ma calcola una risposta corretta)


2
list(reversed(sorted(a)))può essere scritto sorted(a)[::-1]a scopo di golf.
Gioele il

Penseresti che lo saprei ormai, soprattutto da quando faccio molto altro indicizzazione. Grazie.
Hiatsu,

Proprio come un'osservazione laterale, se non fosse per il golf, sarebbe meglio scrivere sorted(a, reverse=True)invece.
Gioele il
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.