Attiva gli scivoli e proteggi il jackpot


23

Parteciperai a un gameshow. Una delle sfide funziona come segue:

  • La prima stanza contiene un gran numero di palle identiche.
  • La seconda stanza contiene una serie di scivoli, ognuno dei quali ha un sensore che conta quante palle sono state posizionate al suo interno. Una palla che viene messa in uno scivolo non può quindi essere recuperata.
  • Ogni scivolo si innescherà dopo che un certo numero di palline (il suo conteggio di innesco ) è stato inserito in esso. Quando si attiva, fa lampeggiare le luci, fa un rumore e non lascia dubbi sul fatto che si sia innescato.
  • È necessario attivare gli Nscivoli per passare alla sfida successiva.
  • Sai il conteggio dei trigger, ma non la corrispondenza tra conteggio e scivolo.
  • Hai un'opportunità per prendere le palle dalla prima stanza alla seconda. Una volta che hai messo una palla in uno scivolo, non puoi tornare indietro per altre palle.
  • Ogni palla che prendi detrae denaro dal jackpot.

Ovviamente vuoi assicurarti di superare la sfida, ma vuoi minimizzare la perdita di denaro del jackpot. Scrivi un programma, una funzione, un verbo, ecc. Per dirti quante palle hai bisogno.

Esempio

Supponiamo che i conteggi dei trigger siano 2, 4 e 10 e che per passare siano necessari 2 scivoli. Esiste una strategia per passare con 10 palline: posizionare fino a 4 palline nel primo scivolo, fino a 4 palline nel secondo scivolo e fino a 4 palline nel terzo scivolo. Dal momento che uno dei tre scivoli si innescherà dopo solo 2 palline, utilizzerai solo un totale di 10. Non esiste una strategia che garantisca il funzionamento con meno di 10, quindi è l'output corretto.

Ingresso

L'input è costituito da una matrice di conteggi di trigger interi e da un numero intero che fornisce il numero di scivoli da attivare. Puoi prendere i due input in entrambi gli ordini e, se necessario, puoi prendere un terzo input con la lunghezza dell'array.

Si può presumere che tutti gli ingressi siano maggiori di zero e che il numero di scivoli che devono essere attivati ​​non superi il numero di scivoli.

Puoi anche presumere che i conteggi siano ordinati (crescente o decrescente), purché lo dichiari chiaramente nella tua risposta.

Produzione

L'output dovrebbe essere un singolo numero intero, fornendo il numero di palline richieste dalla strategia ottimale.

Casi test

Formato: N counts solution

1 [2 4 10] 6
2 [2 4 10] 10
3 [2 4 10] 16
1 [3 5 5 5 5 5 5 5 5 5] 5
2 [1 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 8 11] 8
2 [1 2 6 6 6 6 6 6 6 10] 16
2 [1 2 3 3 4 4 6 6 6 11] 17
3 [1 2 3 4 5 5 6] 16
3 [2 4 7 7 7 7 7 7 7] 21
5 [1 2 2 3 3 3 3 3 5 9 9 11] 27
2 [5 15 15] 25
1 [4 5 15] 10
3 [1 4 4 4] 10
2 [1 3 4] 6
2 [1 3 3 8] 8

Attenzione: non tentare di ninja!
Erik the Outgolfer,

1
Puoi spiegare perché l'ultimo caso di test ne dà 10? Non cercare un posto di almeno 4 in ciascuno per assicurarsi che almeno uno si inneschi? Probabilmente sono troppo stupido e non ho letto bene la domanda, ma non capisco.
Mr. Xcoder,

2
@Rod Dovresti solo posizionarne 5 in due prima che uno si
innescasse

3
@ H.PWiz Grazie, ora capito. La sfida ora sembra molto più complicata ....
Mr. Xcoder,

1
@ Mr.Xcoder, sì, ma devi essere certo di riuscire nel caso peggiore.
Peter Taylor,

Risposte:


4

Python, 222 198 byte

def S(G,P,T=0):
 T=T or[0]*len(P);r=[0]*(sum(t>=p for t,p in zip(T,P))>=G)
 for i,t in enumerate(T):
    if t<max(P):a=next(p for p in P if p>t)-t;T[i]+=a;r+=[a+S(G,P,sorted(T))];T[i]-=a
 return min(r)

L'uso è S(2, (2, 4, 10)).

Per testare questo programma a qualsiasi velocità decente, aggiungi la memoizzazione inserendo questo dopo la definizione della funzione:

old_s = S
mem = {}
def S(G, P, T=0):
    k = (G, tuple(P), T and tuple(T) or 0)
    if k in mem: return mem[k]
    r = old_s(G, P, T)
    mem[k] = r
    return r

Eseguiamo una programmazione dinamica su un array T che contiene il numero di sfere che abbiamo lanciato in ogni scivolo, inizialmente tutti gli zero. Senza fornire una prova rigorosa, sostengo che possiamo tenere sempre T ordinato, cioè supponiamo che lanciamo sempre il maggior numero di palline nell'ultimo scivolo, che a nostra volta supponiamo sia stato lo scivolo più grande.

Se poi T, quando l'elemento abbinato per l'elemento con P (che è il nostro input di problema), ha almeno G (che è il nostro obiettivo) elementi più grandi, abbiamo trovato una soluzione e restituiamo 0, perché dobbiamo lanciare 0 più palle per trovare una soluzione. Ciò significa che se G è 1, il nostro minimo buttato nello scivolo deve contenere una quantità uguale o maggiore di sfere rispetto al più piccolo requisito dello scivolo, e così via per G. più grandi

Altrimenti, per ogni posizione lanciamo abbastanza palle per passare al successivo requisito dello scivolo (qualsiasi cosa nel mezzo non sarebbe mai osservabile) e ricorrere. Restituiamo quindi il minimo di queste chiamate ricorsive.


215 byte rimuovendo continue.
Mr. Xcoder,

1
195 byte rimuovendoenumerate
Felipe Nardi Batista l'

4

Haskell, 124 117 100 98 91 80 78 byte

Salvato 11 byte grazie a @Peter Taylor

0#_=0
n#a=minimum$zipWith(\x y->x*y+(n-1)#(snd.splitAt y$a))a[1..length a-n+1]

Provalo online!

(#) accetta un numero intero e un elenco di numeri interi in ordine decrescente come argomenti

L'uso è 1#[10,4,2]

spiegazione:

Per ogni valore, x, nella posizione i (1-idexed) nell'elenco, la migliore tattica per rimuovere quell'elemento (o una certa quantità di elementi inferiore o uguale a x) è quella di versare x palle negli scivoli.

Per ogni elemento, x, nella posizione i nell'elenco, (n #) calcola x * i + ((n-1) #) dell'elenco oltre la posizione i (fino a quando n è 0). Quindi prende il minimo di tutte le possibilità verificate.


3

Haskell , 54 byte

(%)0
(p%l)n|h:t<-l=p+min(p%t$n)(h%t$n-1)|n<1=p|1>0=1/0

Provalo online!

Prende l'elenco in ordine crescente.


Nota per sé: la prossima volta insiste sul fatto che l'output dovrebbe essere un tipo intero.
Peter Taylor,

1
Non so abbastanza Haskell per capirlo, potresti aggiungere una spiegazione?
orlp,

2

Python, 73 byte

f=lambda n,c:n and min(c[i]*-~i+f(n-1,c[-~i:])for i in range(len(c)-n+1))

La risposta di Haskell al porto di H.PWiz. Richiede che l'input sia in ordine decrescente.


1

CJam (35 byte)

{:A,,e!f<{$__(;A,+.-\Af=.*1bz}%:e<}

Demo online

Prende l'input N countssupponendo che countssia ordinato in ordine crescente.

Dissezione

Indica i conteggi in ordine decrescente come un array con 1 indice C(quindi il secondo elemento di Cè il secondo conteggio più grande). Supponiamo che finiamo per vincere innescando scivoli C[a_0], C[a_1], ... C[a_{N-1}]. Poi, nel peggiore dei casi, per ogni C[a_i]abbiamo messo almeno C[a_i]palle in ciascuno di scivoli 1a a_i. Quindi mettiamo le C[a_{N-1}]palle negli a_{N-1}scivoli, altre C[a_{N-2}]palle dentro a_{N-2}di loro, ...

Su ogni sottoinsieme di Nconteggi, che ci dà la somma più piccola? Quindi dovremmo mirare a vincere con quel sottoinsieme di conteggi.

NB Il codice utilizza effettivamente i conteggi in ordine crescente, ma penso che l'ordine decrescente sia più intuitivo.

{         e# Define a block
  :A      e#   Store the sorted counts as A
  ,,e!f<  e#   Get all N-element subsets of A's indices
  {       e#   Map over these subsets S:
    $__   e#     Sort the subset and get a couple of copies
    (;A,+ e#     Remove the first element from one copy and append len(A)
    .-    e#     Pointwise subtraction, giving [S[0]-S[1] S[1]-S[2] ...]
    \Af=  e#     Get the counts [A[S[0]] A[S[1]] ...]
    .*    e#     Pointwise multiplication
    1bz   e#     Sum and take absolute value, giving the worst case score
  }%
  :e<     e#   Select the minimum worst case score
}
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.