Schweres Kistenstapeln


27

Sie haben einen Haufen schwerer Kisten und möchten diese in möglichst wenigen Stapeln stapeln. Das Problem ist, dass Sie nicht mehr Kisten auf einer Kiste stapeln können, als es unterstützen kann.

Die Herausforderung

Eingabe : Eine Liste der Kistengewichte in ganzen kg.

Ausgabe : Eine Liste von Listen, die die Stapel von Boxen beschreiben. Dies muss die geringstmögliche Anzahl von Stapeln für die Eingabe verwenden. Um ein gültiger Stapel zu sein, muss das Gewicht jeder Kiste im Stapel größer oder gleich der Summe des Gewichts aller darüber liegenden Kisten sein.

Beispiele für gültige Stapel

(In der Reihenfolge von unten nach oben)

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

Beispiele für ungültige Stapel

(In der Reihenfolge von unten nach oben)

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

Beispiel Testfälle

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

Regeln und Annahmen

  • Es gelten Standard-E / A-Regeln und verbotene Regelungslücken
  • Verwenden Sie ein beliebiges praktisches Format für die E / A
    • Stapel können von oben nach unten oder von unten nach oben beschrieben werden, solange Sie konsistent sind.
    • Die Reihenfolge der Stapel (anstatt der Kästchen in diesen Stapeln) spielt keine Rolle.
    • Sie können Eingabefelder auch als vorsortierte Liste verwenden. Die Reihenfolge ist für die Eingabe nicht besonders wichtig, solange das allgemeine Problem nicht durch die Sortierung selbst gelöst wird.
  • Wenn es mehr als eine optimale Stapelkonfiguration gibt, können Sie einen beliebigen Stapel ausgeben
  • Sie können davon ausgehen, dass es mindestens eine Kiste gibt und alle Kisten mindestens 1 kg wiegen
  • Sie müssen mindestens ein Gewicht von 9.999 kg tragen.
  • Sie müssen mindestens 9.999 Boxen unterstützen.
  • Boxen mit dem gleichen Gewicht sind nicht zu unterscheiden, sodass nicht angegeben werden muss, welche Box wo verwendet wurde.

Viel Spaß beim Golfen! Viel Glück!


2
Dürfen wir die Gewichte in sortierter Reihenfolge nehmen? (entweder aufsteigend oder absteigend)
Arnauld

4
"Sie müssen mindestens 9.999 Boxen unterstützen." Wie wird "Unterstützung" hier interpretiert? Bedeutet dies lediglich, dass das Programm in der Lage sein sollte, Eingaben in einer solchen Größe zu verarbeiten, oder bedeutet dies, dass das Programm die Antwort tatsächlich in einer angemessenen Zeitspanne bereitstellen sollte? Wenn es das letztere ist, sollten viel größere Testfälle bereitgestellt werden.
Joel

1
Vorgeschlagener Testfall: [8, 8, 8, 5, 1]->[[8, 8], [8, 5, 1]]
Hiatsu

3
Oder noch besser: [8, 5, 8, 8, 1, 2]->[[8, 8], [8, 5, 2, 1]]
Hiatsu

2
@Arnauld, da das sonst zu einer Antwort einen uninteressanten Sortiercode hinzufügen würde, sage ich ja , Sie können die Eingaben in sortierter Reihenfolge übernehmen.
Beefster

Antworten:


5

Jelly , 19 Bytes

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

Probieren Sie es online!

Offensichtlich -3 dank Nick Kennedy ...

Oben nach unten.

Erläuterung:

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

Haben Sie eine Chance auf eine weniger kompakte Version mit Erklärung? Ich lerne eine Menge von denen.
John Keates

1
@ JohnKeates Hinzugefügt ein.
Erik der Outgolfer

5

JavaScript (Node.js),  139 122  116 Bytes

Erwartet die Eingabe in aufsteigender Reihenfolge.

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

Probieren Sie es online!

Kommentiert

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

Probieren Sie es online!

Funktioniert jetzt auf allen möglichen Eingaben. (Bei TIO tritt bei mehr als zehn Boxen eine Zeitüberschreitung auf, es wird jedoch eine korrekte Antwort berechnet.)


2
list(reversed(sorted(a)))kann wie sorted(a)[::-1]zum Golfen geschrieben werden.
Joel

Sie würden denken, ich würde das jetzt wissen, zumal ich so viel anderes indiziere. Vielen Dank.
Hiatsu

Nur als Randbemerkung, wenn nicht zum Golfen, wäre es besser, sorted(a, reverse=True)stattdessen zu schreiben .
Joel
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.