«Terminer le travail» le plus tôt possible


20

Contexte

Imaginez un instant que vous avez un travail incroyablement ennuyeux. Chaque matin, on vous donne une collection de tâches que vous devriez travailler ce jour-là. Chaque tâche a une certaine durée et une fois commencée, elle doit être terminée en une seule fois. Votre patron ne tolérera pas la marche au ralenti, donc s'il y a des tâches que vous pouvez encore accomplir avant de rentrer chez vous, vous devez travailler sur l'une d'entre elles (vous pouvez choisir laquelle). À l'inverse, si toutes les tâches restantes vous obligent à faire des heures supplémentaires, vous devez rentrer tôt à la maison! Ainsi, votre objectif est de minimiser la durée de votre journée de travail par une planification intelligente.

Fait amusant: c'est une variante du problème de planification des bureaucrates paresseux , et c'est NP-difficile ( source ).

Contribution

Vous avez deux entrées: le nombre d '"unités de temps" dans votre journée de travail (un entier positif L) et la collection de tâches (un tableau non vide d'entiers positifs T, représentant les durées des tâches). Ils peuvent être pris dans n'importe quel ordre et dans n'importe quel format raisonnable. Le tableau Tpeut contenir des tâches d'une durée supérieure à L, mais il est garanti qu'il contiendra au moins une tâche d'une durée maximale L.

Production

Un planning valide est un sous-ensemble de tâches S ⊆ Ttel que sum(S) ≤ L, et chaque tâche qui n'est pas dans S(compter les multiplicités) a une durée strictement supérieure à L - sum(S). Votre sortie doit être la plus petite somme possible d'un programme valide. En d'autres termes, vous devez sortir le nombre minimal d'unités de temps que vous devez travailler aujourd'hui.

Exemple

Considérez les entrées

L = 9
T = [3,4,4,4,2,5]

Une façon de planifier votre journée est la suivante [4,4]: vous terminez deux tâches en 8 unités de temps et il vous reste 1 unité. Comme aucune tâche d'une unité n'est disponible, vous pouvez rentrer chez vous. Cependant, le calendrier [2,5]est encore meilleur: vous travaillez pour 7 unités de temps, puis toutes les tâches restantes prendraient 3 unités de temps ou plus. L'horaire [2,4]n'est pas valide, car après avoir travaillé pour 6 unités de temps, vous auriez encore assez de temps pour terminer la tâche de 3 unités. 7 unités se révèle être optimal, donc la sortie correcte est 7.

Règles et notation

Vous pouvez écrire soit un programme complet soit une fonction. Le nombre d'octets le plus bas l'emporte et les failles standard sont interdites. Il n'y a pas de limite de temps, donc le forçage brut est parfaitement acceptable.

Cas de test

Ceux-ci sont donnés dans le format L T -> output.

 1 [1,2] -> 1
 6 [4,1] -> 5
 7 [7,7,9] -> 7
 9 [3,4,4,4,2,5] -> 7
20 [6,2,3,12,7,31] -> 17
42 [7,7,7,7,8,8,8] -> 36
42 [7,7,7,7,7,8,8,8] -> 35
42 [7,7,7,7,7,7,8,8,8] -> 36
16 [1,2,3,4,5,6,7,8,9,10] -> 13
37 [15,27,4,1,19,16,20,26,29,18] -> 23
22 [24,20,8,8,29,16,5,5,16,18,4,9] -> 18
80 [10,22,11,2,28,20,27,6,24,9,10,6,27,2,15,29,27] -> 71
59 [26,28,5,4,7,23,5,1,9,3,7,15,4,23,7,19,16,25,26] -> 52

Réponses:


3

Gelée, 20 octets

³œ-;⁴Ṃ;¹S>⁴
ŒPÇÐfS€Ṃ

Essayez-le en ligne!

TIO est assez rapide pour terminer les derniers cas de test dans son délai de 60 secondes, même à peine.

Contexte

L'algorithme est à la fois simple et inefficace:

  1. Nous générons tous les sous-ensembles de T , en comptant les multiplicités.

  2. Nous filtrons les sous-ensembles, en ne conservant que les sous-ensembles S qui répondent à l'un des critères suivants:

    • S est différent de T , et la somme des éléments de S et l'élément minimal pas en S est supérieure à L .

    • S et T sont identiques.

    Le T filtré (appelons-le T ' ) contient maintenant toutes les listes de tâches qui font juste assez de travail (ou même des heures supplémentaires).

  3. De tous les S dans T ' , choisissez celui qui a la somme la plus faible.

Comment ça fonctionne

ŒPÇÐfS€Ṃ     Main link. Left input: T (list). Right input: L (integer).

ŒP           Powerset; generate all subsets of T.
   Ðf        Filter them...
  Ç            applying the helper link.
     S€      Compute the sum of each kept subset.
       Ṃ     Take the minimum.

³œ-;⁴Ṃ;¹S>⁴  Helper link. Input: A (subset of T)

³œ-          Multiset subtraction; remove the elements of A from T, counting
             multiplicities.
   ;⁴        Append L to the resulting list.
     Ṃ       Take the minimum.
             If S == T, the difference was empty and the minimum is L.
      ;¹     Prepend the minimum to A.
        S    Compute the sum.
         >⁴  Compare it with L.
             If S == T, the comparison will return 1.

1

Pyth, 26 25 octets

JEhSsMf&gJsT>hS.-QT-JsTyQ

Essayez-le en ligne. Suite de tests.

Je n'ai pas pu exécuter les deux derniers cas de test (ils expirent en ligne, je suppose), mais tous les autres fonctionnent. Ceci est juste une solution de force brute de base.


1

Rubis, 124 octets

->(m,s){
f=proc{|l,t|t.reject!{|x|x>l}
(0...(t.size)).map{|x|
f.call(l-t[x],t[0,x]+t[(x+1)..-1])
}.max||l
}
m-f.call(m,s)
}

Il s'agit d'une solution de force brute.


1

MATL , 36 octets

iTFinZ^!"2G@2#)sXKt1G>~wb+lG>A*?KhX<

Essayez-le en ligne!

i           % input number L
TF          % array [true, false]
in          % input array T. Get its length
Z^!         % Cartesian power and transpose. Each column is a selection from T
"           % for each selection
  2G@2#)    %   take non-selected and then selected tasks
  sXK       %   sum of selected tasks. Copy to clipboard K
  t1G>~     %   duplicate. Is sum of selected tasks <= L?
  wb        %   swap, rotate
  +         %   sum of selected tasks plus each non-selected task
  lG>A      %   are all of those numbers greater than L?
  *         %   are both conditions met?
  ?         %   if so
    Kh      %     paste current minimum (or initially L), append new value
    X<      %     compute new minimum
            %   end if implicitly
            % end for each implicitly
            % display stack implicitly
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.