Układanie ciężkich skrzynek

27

Masz mnóstwo ciężkich pudeł i chcesz je układać w jak najmniejszej liczbie stosów. Problem polega na tym, że nie można układać na pudełku większej liczby pudeł niż jest w stanie obsłużyć, dlatego cięższe pudełka muszą znajdować się na spodzie stosu.

Wyzwanie

Dane wejściowe : lista wag skrzynek w pełnych kg.

Wyjście : lista list opisujących stosy pudeł. Musi to wykorzystywać jak najmniejszą liczbę stosów możliwych do wprowadzenia. Aby być prawidłowym stosem, waga każdego pudełka w stosie musi być większa lub równa sumie wagi wszystkich pudeł nad nim.

Przykłady prawidłowych stosów

(W kolejności od dołu do góry)

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

Przykłady nieprawidłowych stosów

(W kolejności od dołu do góry)

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

Przykładowe przypadki testowe

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

Zasady i założenia

  • Obowiązują standardowe zasady we / wy i zakazane luki
  • Użyj dowolnego dogodnego formatu dla I / O
    • Stosy można opisywać od góry do dołu lub od dołu do góry, pod warunkiem, że jesteś spójny.
    • Kolejność stosów (zamiast pudełek w tych stosach) nie ma znaczenia.
    • Możesz również traktować pola wprowadzania jako listę wstępnie ustawioną. Kolejność nie jest szczególnie ważna dla danych wejściowych, o ile ogólny problem nie zostanie rozwiązany przez samo sortowanie.
  • Jeśli istnieje więcej niż jedna optymalna konfiguracja stosów, możesz wyprowadzić dowolną z nich
  • Możesz założyć, że jest co najmniej jedno pudełko i że wszystkie pudełka ważą co najmniej 1 kg
  • Musisz wytrzymać obciążenie do 9 999 kg, co najmniej.
  • Musisz obsłużyć co najmniej 9 999 wszystkich pól.
  • Pudełka o tej samej masie są nierozróżnialne, więc nie trzeba dodawać adnotacji, które pudełko zostało użyte.

Miłej gry w golfa! Powodzenia!

Wołowina
źródło
2
Czy możemy przyjmować odważniki w uporządkowanej kolejności? (rosnąco lub malejąco)
Arnauld
4
„Musisz obsłużyć maksymalnie 9 999 wszystkich skrzynek”. Jak interpretuje się tutaj „wsparcie”? Czy oznacza to po prostu, że program powinien być w stanie przyjąć taki rozmiar danych wejściowych, czy też oznacza, że ​​program powinien faktycznie udzielić odpowiedzi w rozsądnym czasie? Jeśli tak jest, należy zapewnić znacznie większe przypadki testowe.
Joel
1
Sugerowany przypadek testowy: [8, 8, 8, 5, 1]->[[8, 8], [8, 5, 1]]
Hiatsu
3
Lub jeszcze lepiej: [8, 5, 8, 8, 1, 2]->[[8, 8], [8, 5, 2, 1]]
Hiatsu
2
@Arnauld, ponieważ w przeciwnym razie dodałoby to nieciekawego kodu sortującego do odpowiedzi, powiem tak , możesz wprowadzać dane w posortowanej kolejności.
Beefster

Odpowiedzi:

5

Galaretka , 19 bajtów

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

Wypróbuj online!

Oczywiste -3 dzięki Nickowi Kennedy'emu ...

Od góry do dołu.

Wyjaśnienie:

Œ!ŒṖ€ẎṖÄ>ḊƲ€¬ȦƊƇ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]])
Erik the Outgolfer
źródło
Czy jest jakaś szansa na mniej kompaktową wersję z wyjaśnieniem? Uczę się od nich tony.
John Keates
1
@JohnKeates Dodano jeden.
Erik the Outgolfer
5

JavaScript (Node.js),  139 122  116 bajtów

Oczekuje, że dane wejściowe zostaną posortowane w porządku rosnącym.

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

Wypróbuj online!

Skomentował

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[]
Arnauld
źródło
2

Python 3.8 (wersja wstępna) , 178 bajtów

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

Wypróbuj online!

Teraz działa na wszystkich możliwych wejściach. (Przekracza limit czasu w TIO z więcej niż dziesięcioma pudełkami, ale oblicza poprawną odpowiedź)

Hiatsu
źródło
2
list(reversed(sorted(a)))można napisać jak sorted(a)[::-1]do golfa.
Joel
Można by pomyśleć, że do tej pory to wiem, zwłaszcza że robię tyle innych indeksowań. Dzięki.
Hiatsu
Uwaga dodatkowa: gdyby nie gra w golfa, lepiej byłoby pisać sorted(a, reverse=True).
Joel