"Termina lavoro" il prima possibile


20

sfondo

Immagina per un momento di avere un lavoro noioso e noioso. Ogni mattina, ti viene data una raccolta di compiti che dovresti svolgere quel giorno. Ogni attività ha una certa durata e, una volta avviata, deve essere completata in una volta sola. Il tuo capo non tollererà il minimo, quindi se ci sono compiti che potresti ancora completare prima di andare a casa, devi lavorare su uno di essi (puoi scegliere quale). Al contrario, se tutte le attività rimanenti ti richiedono di fare gli straordinari, devi andare a casa presto! Pertanto, l'obiettivo è ridurre al minimo la durata della giornata lavorativa mediante una pianificazione intelligente.

Curiosità: questa è una variante del pigro problema di programmazione del burocrate ed è NP-difficile ( fonte ).

Ingresso

Hai due input: il numero di "unità di tempo" nel tuo giorno lavorativo (un numero intero positivo L) e la raccolta di attività (un array non vuoto di numeri interi positivi T, che rappresentano le durate delle attività). Possono essere presi in qualsiasi ordine e in qualsiasi formato ragionevole. L'array Tpuò contenere attività con durata maggiore di L, ma è garantito che contenga almeno un'attività con durata al massimo L.

Produzione

Una pianificazione valida è un sottoinsieme di attività S ⊆ Ttali che sum(S) ≤ Logni attività non Sinclusa (conteggio delle molteplicità) ha una durata strettamente superiore a L - sum(S). L'output deve essere la somma più piccola possibile di un programma valido. In altre parole, dovrai produrre il numero minimo di unità di tempo che devi lavorare oggi.

Esempio

Considera gli input

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

Un modo di programmare la giornata è [4,4]: finisci due attività in 8 unità di tempo e ti rimane 1 unità. Poiché non sono disponibili attività da 1 unità, è possibile tornare a casa. Tuttavia, il programma [2,5]è ancora migliore: lavori per 7 unità di tempo e quindi tutte le attività rimanenti richiederebbero 3 o più unità di tempo. Il programma [2,4]non è valido, poiché dopo aver lavorato per 6 unità di tempo, avresti ancora abbastanza tempo per completare l'attività di 3 unità. 7 unità risultano ottimali, quindi l'uscita corretta è 7.

Regole e punteggio

È possibile scrivere un programma completo o una funzione. Vince il conteggio di byte più basso e non sono consentite scappatoie standard. Non c'è limite di tempo, quindi la forza bruta è perfettamente accettabile.

Casi test

Questi sono indicati nel formato 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

Risposte:


3

Gelatina, 20 byte

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

Provalo online!

TIO è abbastanza veloce per finire gli ultimi casi di test entro il suo limite di 60 secondi, anche se a malapena.

sfondo

L'algoritmo è sia semplice che inefficiente:

  1. Generiamo tutti i sottoinsiemi di T , contando le molteplicità.

  2. Filtriamo i sottoinsiemi, mantenendo solo quei sottoinsiemi S che soddisfano uno dei seguenti criteri:

    • S è diverso da T , e la somma degli elementi di S e l'elemento minimo non in S è maggiore di L .

    • S e T sono identici.

    La T filtrata (chiamiamola T ' ) ora contiene tutti gli elenchi di attività che svolgono il lavoro sufficiente (o anche un po' di straordinario).

  3. Di tutte le S in T ' , scegli quella con la somma più bassa.

Come funziona

Œ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 byte

JEhSsMf&gJsT>hS.-QT-JsTyQ

Provalo online. Suite di test.

Non sono stato in grado di eseguire gli ultimi due casi di test (scadono online, presumo), ma tutti gli altri funzionano. Questa è solo una soluzione di base per la forza bruta.


1

Rubino, 124 byte

->(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)
}

Questa è una soluzione a forza bruta.


1

MATL , 36 byte

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

Provalo online!

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