Wählen Sie aus einem vorhandenen Satz von Gewichten eine Zielsumme aus

9

Beim Gewichtheben möchte ich ein bestimmtes Gewicht erreichen, indem ich mehrere Platten an einer Stange befestige.

Ich habe folgende Platten:

  • 6 Teller à 1 kg
  • 6 Teller à 2,5 kg
  • 6 Teller à 5 kg
  • 6 Teller à 10 kg

Die Stange selbst wiegt 10 kg.

Die Platten dürfen nur paarweise angebracht werden - sie sind an jedem Ende der Stange angebracht, und die Anordnung an den beiden Enden muss vollständig symmetrisch sein (z. B. Anbringen von zwei 5-kg-Platten an einem Ende und einer 10-kg-Platte an das andere Ende ist aus Sicherheitsgründen verboten).

Erstellen Sie ein Programm oder eine Funktion, die mir sagt, wie viele Platten jeder Art ich verwenden muss, um ein bestimmtes Gesamtgewicht zu erhalten. Die Eingabe ist eine Ganzzahl größer als 11; Die Ausgabe ist eine Liste / ein Array / eine Zeichenfolge mit 4 Zahlen. Wenn es unmöglich ist, vorhandene Platten zu kombinieren, um das Zielgewicht zu erhalten, geben Sie ein Null / Leer-Array, eine ungültige Zeichenfolge aus, lösen Sie eine Ausnahme oder ähnliches aus.

Wenn es mehrere Lösungen gibt, darf der Code nur eine ausgeben (lassen Sie den Benutzer nicht wählen - er ist zu beschäftigt mit anderen Dingen).

Testfälle:

12 -> [2 0 0 0] - 2 plates of 1 kg plus the bar of 10 kg
13 -> [0 0 0 0] - a special-case output that means "impossible"
20 -> [0 0 2 0] - 2 plates of 5 kg + bar
20 -> [0 4 0 0] - a different acceptable solution for the above
21 -> [6 2 0 0] - 6 plates of 1 kg + 2 plates of 2.5 kg + bar
28 -> [0 0 0 0] - impossible
45 -> [0 2 6 0] - a solution for a random number in range
112 -> [2 4 6 6] - a solution for a random number in range
121 -> [6 6 6 6] - maximal weight for which a solution is possible

Wenn Ihr Code die Zahlen in umgekehrter Reihenfolge ausgibt (von der schweren bis zur leichten Platte), geben Sie dies bitte explizit an, um Verwechslungen zu vermeiden.

Anatolyg
quelle
1
Ist das nicht ein Betrug der Frage nach der minimalen Münzzählung ? Ich denke nicht, dass der gleiche gierige Algorithmus fehlschlägt, außer mit der Beschränkung von 6 einer Plattenart. Ich denke, das ist vielleicht kein ausreichender Unterschied, aber ich bin mir nicht sicher.
FryAmTheEggman
1
Der gierige Algorithmus funktioniert nicht (zumindest nicht ohne Modifikation) genau deshalb, weil die Anzahl begrenzt ist
Anatolyg
Verwandte , aber das ist ASCII
AdmBorkBork
Ja, der Grund, den ich gepostet habe, war, dass ich nicht sicher war, ob die Änderung signifikant genug war. Ich habe gepostet, um zu versuchen, Community-Feedback zu erhalten, und ich werde meinen Kommentar entfernen, wenn es so aussieht, als ob die Community nicht mit mir übereinstimmt.
FryAmTheEggman
Können wir alle Lösungen anstelle von nur einer ausgeben?
Luis Mendo

Antworten:

5

Gelee , 22 Bytes

4ṗạµ×2,5,10,20S€+⁵iƓịḤ

Probieren Sie es online aus! oder überprüfen Sie alle Testfälle .

Wie es funktioniert

4ṗạµ×2,5,10,20S€+⁵iƓịḤ  Main link. No arguments

4                       Set the left argument and initial return value to 4.
 ṗ                      Take the Cartesian power of [1, 2, 3, 4] and 4, i.e.,
                        generate all 4-tuples of integers between 1 and 4.
  ạ                     Take the absolute difference of all integers in the
                        4-tuples and the integer 4. This maps [1, 2, 3, 4] to
                        [3, 2, 1, 0] and places [0, 0, 0, 0] at index 0.
   µ                    Begin a new, monadic chain. Argument: A (list of 4-tuples)
     2,5,10,20          Yield [2, 5, 10, 20].
    ×                   Perform vectorized multiplication with each 4-tuple in A.
              S€        Sum each resulting 4-tuple.
                +⁵      Add 10 to each sum.
                   Ɠ    Read an integer from STDIN.
                  i     Find its first index in the array of sums (0 if not found).
                     Ḥ  Unhalve; yield the list A, with all integers doubled.
                    ị   Retrieve the 4-tuple at the proper index.
Dennis
quelle
6

MATL , 29 28 Bytes

4t:qEZ^!"[l2.5AX]@Y*10+G=?@.

Für Eingaben, die keine Lösung haben, wird eine leere Ausgabe erzeugt (ohne Fehler).

Probieren Sie es online aus!

Erläuterung

4           % Push 4
t:q         % Duplicate 4 and transform into range [0 1 2 3]
E           % Multiply by 2: transform into [0 2 4 6]
Z^          % Cartesian power. Each row is a "combination" of the four numbers
!           % Transpose
"           % For each column
  [l2.5AX]  %   Push [1 2.5 5 10]
  @         %   Push current column
  Y*        %   Matrix multiply. Gives sum of products
  10+       %   Add 10
  G=        %   Compare with input: are they equal?
  ?         %   If so
    @       %     Push current column, to be displayed
    .       %     Break loop
            %   Implicit end
            % Implicit end
            % Implicit display
Luis Mendo
quelle
5

Mathematica, 70 Bytes

Select[FrobeniusSolve[{2,5,10,20},2#-20],AllTrue[EvenQ@#&&#<7&]][[1]]&

Anonyme Funktion. Nimmt eine Zahl als Eingabe und gibt entweder eine Liste oder Fehler aus und gibt zurück, {}[[1]]wenn es keine Lösung gibt.

LegionMammal978
quelle
4

Gelee, 25 Bytes

×2,5,10,20S+⁵⁼³
4ṗ4’ÇÐfḢḤ

Probieren Sie es hier aus.

Lynn
quelle
2,5,10,20->2,5,⁵,20
Leaky Nun
wirklich ... ist keine ,Dyade? Mein ganzes Leben ist eine Lüge
Leaky Nun
@LeakyNun ,ist eine Dyade, kann aber auch für Literale verwendet werden. 2,5,⁵,20ist nicht eine wörtliche obwohl ( 2,5und 20sind, aber ,, und ,sind Atome), so dass Sie etwas zu kombinieren , die Links bräuchten.
Dennis
3

Python 3, 112 Bytes

lambda n:[i for i in[[i//4**j%4*2for j in range(4)]for i in range(256)]if i[0]+2.5*i[1]+5*i[2]+10*i[3]+10==n][0]

Eine anonyme Funktion, die über ein Argument die Zielmasse eingibt und die Nummer jeder Platte als Liste zurückgibt. Wenn keine Lösung vorhanden ist, wird ein Fehler ausgegeben. Das ist reine rohe Gewalt.

Wie es funktioniert

lambda n                                   Anonymous function with input target mass n
...for i in range(256)                     Loop for all possible arrangement indices i
[i//4**j%4*2for j in range(4)]             Create a base-4 representation of the index i,
                                           and multiply each digit by 2 to map from
                                           (0,1,2,3) to (0,2,4,6)
[...]                                      Package all possible arrangements in a list
...for i in...                             Loop for all possible arrangements i
i...if i[0]+2.5*i[1]+5*i[2]+10*i[3]+10==n  Return i if it gives the target mass
[...]                                      Package all solutions in a list
:...[0]                                    Return the first list element. This removes any
                                           multiple solutions, and throws an error if there
                                           being no solutions results in an empty list

Probieren Sie es auf Ideone

TheBikingViking
quelle
2

Brachylog , 50 Bytes

,L##l4,L:{.~e[0:3]}a:[2:5:10:20]*+:10+?,L:{:2*.}a.

Rückgabe, falsewenn nicht möglich.

Fatalisieren
quelle
1

Pyth, 34 31 25 Bytes

h + fqQ +; s * VT [1 2,5 5;) yMM ^ U4 4] * 4] 0 
yMh + fqQ +; s * VT [2 5; y;) ^ U4 4] * 4] 0
yMhfqQ +; s * VT [2 5; y;) ^ U4 4

Testsuite.

Fehler in der Unmöglichkeit.

Dies ist im Wesentlichen eine Brute-Force.

Dies ist ziemlich schnell, da es nur 256 mögliche Anordnungen gibt.

Undichte Nonne
quelle
1

Scala, 202 Bytes

Beschlossen, dass Scala hier nicht viel Liebe findet, deshalb präsentiere ich eine (wahrscheinlich nicht optimale) Lösung in Scala.

def w(i:Int){var w=Map(20->0,10->0,5->0,2->0);var x=i-10;while(x>0){
var d=false;for(a<-w.keys)if(a<=x & w(a)<6 & !d){x=x-a;w=w.updated(a,w(a)+2);d=true;}
if(!d){println(0);return;}}
println(w.values);}

Das Programm wird in umgekehrter Reihenfolge und mit zusätzlichem Müll ausgegeben, verglichen mit Lösungen in der Post. Wenn keine Lösung gefunden wird, wird 0 gedruckt.

Hinweis: Ich konnte keine Zeilenumbrüche oder Leerzeichen entfernen, da Scala dumm ist. Um die Größe zu verringern, muss die Methode überarbeitet werden, es sei denn, ich habe etwas Offensichtliches übersehen.

ejaszewski
quelle
1

APL, 40 Bytes

{2×(4⍴4)⊤⍵⍳⍨10+2×,⊃∘.+/↓1 2.5 5 10∘.×⍳4}

In ⎕IO ← 0. Auf Englisch:

  1. 10+2×,∘.+⌿1 2.5 5 10∘.×⍳4: Erstellen Sie das Array aller möglichen Gewichte, indem Sie die äußere 4D-Summe der Gewichte pro Gewichtstyp berechnen.
  2. ⍵⍳⍨: Suche den Index der angegebenen. Wenn nicht gefunden, ist der Index 1 + die Anzahl des Arrays in Schritt 1;
  3. (4⍴4)⊤: den Index in Basis 4 darstellen, dh die Koordinate des angegebenen Gewichts im 4D-Raum berechnen;
  4. : Bringen Sie das Ergebnis in den Problemraum, wo die Koordinaten als die Hälfte der Anzahl der Platten interpretiert werden sollten.

Beispiel: {2 × (4⍴4) ⊤⍵⍳⍨10 + 2 ×, ⊃∘. + / ↓ 1 2,5 5 10∘. × ⍳4} 112 2 4 6 6

Bonus : Da APL eine Array-Sprache ist, können mehrere Gewichte gleichzeitig getestet werden. In diesem Fall wird das Ergebnis transponiert:

      {2×(4⍴4)⊤⍵⍳⍨10+2×,⊃∘.+/↓1 2.5 5 10∘.×⍳4}12 13 20 21 28 45 112 121
2 0 0 6 0 0 2 6
0 0 0 2 0 2 4 6
0 0 2 0 0 2 6 6
0 0 0 0 0 2 6 6
lstefano
quelle
1

JavaScript (ES6), 109 Byte

n=>`000${[...Array(256)].findIndex((_,i)=>i+(i&48)*9+(i&12)*79+(i&3)*639+320==n*32).toString(4)*2}`.slice(-4)

Gibt 00-2bei Fehler zurück. Alternative Lösung, die undefinedbei Fehler zurückgibt , auch 109 Bytes:

n=>[...Array(256)].map((_,i)=>`000${i.toString(4)*2}`.slice(-4)).find(s=>+s[0]+s[1]*2.5+s[2]*5+s[3]*10+10==n)
Neil
quelle