Quante torte a tre frutti puoi fare?


32

Una torta a tre frutti è composta da tre frutti diversi . Qual è la maggior parte delle torte a tre frutti che puoi ottenere dalle quantità di 5 frutti che hai?

Ad esempio, con

1 apple
1 banana
4 mangoes 
2 nectarines
0 peaches

puoi fare 2 torte:

apple, mango, nectarine
banana, mango, nectarine

Input: cinque numeri interi non negativi o un elenco di essi.

Output: il numero massimo di torte a tre frutti che puoi ottenere da quelle quantità di frutta. Vince il minor numero di byte.

Casi test:

1 1 4 2 0
2
2 2 2 2 2
3
0 6 0 6 0
0
12 5 3 2 1
5
1 14 14 3 2
6
0 0 1 0 50
0

Classifica:


Credo che nel tuo esempio manchino due opzioni aggiuntive: Apple, Banana, Mango e Apple, Banana, Nectarine. Pertanto, il 1 1 4 2 0test case dovrebbe produrre l'output: 4.
cobaltduck,

@cobaltduck Ma se usi la mela e la banana nella tua prima torta (mela / banana / mango), non hai la mela o la banana da usare nella seconda torta (mela / banana / nettarina).
AdmBorkBork,

2
@Timmy D: Ah, capito. Non era chiaro che le torte fossero fatte contemporaneamente.
cobaltduck,

@cobaltduck Credo che non debbano essere fatti contemporaneamente, ma non puoi imbrogliare riutilizzando i frutti che hai usato per il primo.
Lister

@Sig. Lister: Semantica. È sufficiente che esistesse una regola ambigua (per almeno un lettore) e da allora è stata chiarita.
cobaltduck,

Risposte:


34

Pyth, 19 18 14 byte

-1 byte di @FryAmTheEggman

Programma a 14 byte di @isaacg

Dichiaro che il numero di torte che possono essere formate da un elenco crescente [x1,x2,x3,x4,x5]è:

floor(min((x1+x2+x3+x4+x5)/3,(x1+x2+x3+x4)/2,x1+x2+x3))

O nel codice:

JSQhS/Ls~PJ_S3

[Vedi la cronologia delle revisioni per i programmi TI-BASIC e APL]

Prova di correttezza

Permettere

s3 = x1+x2+x3
s4 = x1+x2+x3+x4
s5 = x1+x2+x3+x4+x5

Vogliamo dimostrare che P(X)=floor(min(s5/3,s4/2,s3))è sempre il maggior numero di torte per un elenco x1≤x2≤x3≤x4≤x5di numeri di frutta 1 ~ 5.

Innanzitutto, mostriamo che tutti e tre i numeri sono limiti superiori.

  • Poiché ci sono s5frutti totali e ogni torta ha tre frutti, ⌊s5/3⌋è un limite superiore.

  • Dato che ci sono s4frutti che non sono frutti 5 e che in ogni torta sono richiesti almeno due frutti non 5, ⌊s4/2⌋è un limite superiore.

  • Poiché ci sono s3frutti che non sono né frutto 4 né frutto 5, e che almeno uno di questi frutti è richiesto in ogni torta, s3è un limite superiore.

In secondo luogo, mostriamo che il metodo di prendere frutti dalle tre pile più grandi soddisfa sempre il limite. Lo facciamo per induzione.

Caso di base: 0 torte possono ovviamente essere formate da qualsiasi elenco valido con P(X)>=0.

Passaggio induttivo: dato qualsiasi elenco in Xcui P(X) > 0, possiamo cuocere una torta, lasciando un elenco X'con P(X') >= P(X)-1. Lo facciamo prendendo un frutto dalle tre pile più grandi 3,4,5, quindi ricorrendo se necessario. Sopportami; ci sono alcuni casi.

  • Se x2<x3, quindi non abbiamo bisogno di ordinare l'elenco dopo aver rimosso i frutti. Ne abbiamo già uno valido X'. Sappiamo che P(X') = P(X)-1perché s5'è 3 in meno (perché sono stati rimossi tre frutti di tipo 1 ~ 5), s4'è 2 in meno e s3'1 in meno. Quindi P(X')è esattamente uno in meno di P (X).
  • Se x3<x4, allora abbiamo fatto allo stesso modo.
  • Ora prendiamo il caso in cui x2=x3=x4. Questa volta avremo bisogno di riorganizzare l'elenco.

    • Se x5>x4, quindi riordiniamo l'elenco cambiando le pile 4 e 2. s5'e s4'siamo ancora in diminuzione rispettivamente di 3 e 2, ma s3'=s3-2. Questo non è un problema, perché se x2=x3=x4, quindi 2*x4<=s3-> 2*x4+s3 <= 2*s3-> (x4 + s4)/2 <= s3. Abbiamo due sottotitoli:
    • Uguaglianza, cioè (x4,x3,x2,x1)=(1,1,1,0)nel qual caso P(X)= 1e possiamo chiaramente fare una torta da pile 5,4,3, o:

    • (s4+1)/2 <= s3, nel qual caso diminuire s4di un extra 1non significa una riduzione extra di P (X).

  • Ora ci resta il caso in cui x1<x2=x3=x4=x5. Ora s3verrà anche ridotto di 1, quindi dobbiamo (s5/3+1)esserlo <=s4/2; cioè 8x5+2x1+2<=9x5+3x1, o x5+x1>=2. Tutti i casi più piccoli di questo possono essere controllati manualmente.

  • Se ogni numero è uguale, è chiaro che possiamo raggiungere il limite di ⌊s5/3⌋, che è sempre inferiore rispetto agli altri due: passiamo semplicemente attraverso i numeri in sequenza.

Finalmente abbiamo finito. Per favore, commenta se mi manca qualcosa e darò una piccola ricompensa per una prova più elegante.


Penso che la tua richiesta corrisponda alla soluzione iterativa di @ fryamtheeggman.
Sparr,

@Sparr Sto cercando di dimostrare che il mio limite è raggiungibile usando il metodo di fryamtheeggman.
lirtosiast

2
Questo può essere golfato di 4 byte trasformandolo in un ciclo:JSQhS/Ls~PJ_S3
isaacg


7

CJam, 34

q~L{J2be!\f{\.-_W#){j)7}|;}0+:e>}j

Provalo online

Spiegazione:

q~          read and evaluate the input array
L{…}j       calculate with memoized recursion and no initial values
             using the input array as the argument
  J2b       convert 19 to base 2 (J=19), obtaining [1 0 0 1 1]
  e!        get permutations without duplicates
             these are all the combinations of three 1's and two 0's
             which represent the choices of fruit for one pie
  \         swap with the argument array
  f{…}      for each combination and the argument
    \       swap to bring the combination to the top
    .-      subtract from the argument array, item by item
    _       duplicate the resulting array
    W#)     does it contain the value -1? (calculate (index of W=-1) + 1)
    {…}|    if not
      j     recursively solve the problem for this array
      )7    increment the result, then push a dummy value
    ;       pop the last value (array containing -1 or dummy value)
  0+        add a 0 in case the resulting array is empty
             (if we couldn't make any pie from the argument)
  :e>       get the maximum value (best number of pies)

Memorizzare la ricorsione costa byte? Non esiste un limite di runtime.
xnor

2
@xnor Penso che in realtà salva 1 byte qui :)
aditsu

7

Haskell, 62 byte

f x=maximum$0:[1+f y|y<-mapM(\a->a:[a-1|a>0])x,sum y==sum x-3]

Questo definisce una funzione fche accetta l'elenco dei frutti xe restituisce il numero massimo di torte.

Spiegazione

Calcoliamo il numero di torte in modo ricorsivo. La parte mapM(\a->a:[a-1|a>0])xvaluta l'elenco di tutti gli elenchi ottenuti xdecrementando eventuali voci positive. Se x = [0,1,2]risulta

[[0,1,2],[0,1,1],[0,0,2],[0,0,1]]

La parte tra l'esterno []è una comprensione dell'elenco: ripetiamo tutto ynell'elenco precedente e filtriamo quelli la cui somma non è uguale a sum(x)-3, quindi otteniamo tutti gli elenchi in cui 3 frutti diversi sono stati trasformati in una torta. Quindi valutiamo in modo ricorsivo fsu questi elenchi, aggiungiamo 1a ciascuno e prendiamo il massimo di essi e 0(il caso base, se non possiamo fare torte).


7

C #, 67

Crea ricorsivamente una torta per iterazione con i frutti che hai di più fino allo sfinimento.

int f(List<int>p){p.Sort();p[3]--;p[4]--;return p[2]-->0?1+f(p):0;}

Casi di prova qui


Non hai familiarità con C #, ma puoi forse fare p[2]--contemporaneamente al controllo p[2]>-1?
xnor

buon punto, aggiornerò la risposta tra un secondo.
AXMIM

6

Pyth, 29

Wtt=QS-Q0=Q+tPPQtM>3.<Q1=hZ;Z

Suite di test

Ordina l'elenco di input e rimuove gli zeri. Quindi, finché hai 3 frutti, decrementa il primo e gli ultimi due elementi e aggiungi gli elementi rimanenti all'elenco, prima di ordinarlo e rimuovere nuovamente gli zeri. Quindi incrementare un contatore di 1.

Questo è in realtà piuttosto veloce fintanto che ci sono solo 5 frutti, può risolvere per contenitori di frutta molto grandi, cioè 1000,1000,1000,1000,1000in meno di un secondo.


Puoi provare che è corretto?
aditsu,

@aditsu Non l'ho provato, ma l'ho verificato rispetto al tuo per diversi valori aggiuntivi. Non ho mai scritto una prova per qualcosa di simile prima, ma ci proverò. Per ora, dirò che ha senso che dovrebbe funzionare perché prendi sempre solo le più grandi pile di frutta, fino a quando non esaurisci quelle più piccole. Mentre le strategie avide non sono ovviamente sempre intrinsecamente corrette, non riesco a pensare al motivo per cui qui non funziona.
FryAmTheEggman,

@FryAmTheEggman Ho capito bene che prendi i due frutti più comuni e il frutto più raro?
xnor

@xnor Sì, è corretto. Non funziona?
FryAmTheEggman,

1
@TimmyD No, non devo (penso di doverlo fare), tuttavia per rimuovere questa funzionalità non costa alcun byte (in realtà costa di più). Detto questo, mi aspetto che la soluzione di Reto Koradi sia più breve nella maggior parte delle lingue, e ovviamente quella di Thomas è molto più concisa. Penso che il motivo per cui non è necessario riordinare sia correlato ad esso, non importa da quale delle 3 pile più piccole prendi.
FryAmTheEggman,

6

Python, soluzione generale, 128 92 byte

-36 byte da @xnor, tu da real mvp

g=lambda l,k:0if k>sum(l)else-(-1in l)or-~g(map(sum,zip(sorted(l),[0]*(len(l)-k)+[-1]*k)),k))

def g(a,k):b=[i for i in a if i];return 0if len(b)<k;c=sorted(b,reverse=True);return 1+g([c[i]-(k-1>i)for i in range(len(c))],k)

Funziona finché la mia prova è corretta. In caso contrario, fammi sapere perché, così posso provare a risolverlo. Se è incomprensibile, fammi sapere, e lo attaccherò dopo alcune tazze di caffè.


Tutto mi sembra stretto ora.
lirtosiast,

@Mego Grazie per averci lavorato! Potresti includere la prova nel post SE? C'è una preoccupazione generale che qualcuno che legge anni dopo potrebbe trovare collegamenti non funzionanti. La formattazione LaTeX dovrebbe funzionare principalmente in MathJax.
xnor

@Mego Oops, ho dimenticato che MathJax non è abilitato qui. Hmm, chiederò cosa fare.
xnor

Sto assegnando la generosità per questa prova. Congratulazioni!
xnor

@Mego No, penso che il tuo link MathCloud sia il migliore che abbiamo.
xnor

5

Python 2, 78 byte

Prendendo 5 numeri come input: 91 89 88 byte

s=sorted([input()for x in[0]*5])
while s[2]:s[2]-=1;s[3]-=1;s[4]-=1;s.sort();x+=1
print x

Modifica : cambiando s=sorted([input()for x in[0]*5])per si s=sorted(map(input,['']*5));x=0salva 1 byte.

Prende 5 numeri come input e stampa il numero di possibili torte che possono essere fatte. Adotta lo stesso approccio della risposta di Reto Koradi - senza migliorare il conteggio dei byte - ma sembrava che a Python mancasse una risposta a questa domanda.

Grazie @ThomasKwa e @xsot per il tuo suggerimento.

Come funziona

 s=sorted([input()for x in[0]*5]) takes 5 numbers as input, puts them in a list 
                                  and sorts it in ascending order. The result
                                  is then stored in s 

 while s[2]:                      While there are more than 3 types of fruit 
                                  we can still make pies. As the list is                     
                                  sorted this will not be true when s[2] is 0. 
                                  This takes advantage of 0 being equivalent to False.

 s[2]-=1;s[3]-=1;s[4]-=1          Decrement in one unit the types of fruit 
                                  that we have the most

 s.sort()                         Sort the resulting list

 x+=1                             Add one to the pie counter

 print x                          Print the result

Nota che la variabile xnon è mai definita, ma il programma sfrutta alcune perdite di Python 2.7. Quando si definisce l'elenco scon la comprensione dell'elenco, l'ultimo valore nell'iterabile ( [0]*5in questo caso) viene archiviato nella variabile utilizzata per iterare.

Per chiarire le cose:

>>>[x for x in range(10)]
>>>x
9

Prendendo un elenco come input: 78 byte

Grazie @xnor @xsot e @ThomasKwa per aver suggerito di modificare l'input in un elenco.

s=sorted(input());x=0
while s[2]:s[2]-=1;s[3]-=1;s[4]-=1;s.sort();x+=1
print x

Come funziona

Funziona allo stesso modo del codice sopra, ma in questo caso l'input è già un elenco, quindi non è necessario crearlo e la variabile xdeve essere definita.

Disclaimer: questo è il mio primo tentativo di giocare a golf e sembra che possa ancora essere giocato a golf, quindi suggerisci eventuali modifiche che potrebbero essere apportate al fine di ridurre il conteggio dei byte.


1
Puoi avere l'input già in un elenco; s[2]>0-> s[2], poiché il numero nella pila è sempre non negativo.
lirtosiast

Thomas Kwa ha sottolineato che potresti supporre che l'input sia già stato fornito come elenco, quindi puoi semplicemente farlo s=sorted(input()). Inoltre, il conteggio dei byte corrente è 89; le newline contano come un singolo carattere.
xnor

@ThomasKwa già sottolineato che si potrebbe accettare l'input come una lista, ma se ti ostini a accettare input multi-riga, sostituire la prima linea con la seguente per salvare un byte: s=sorted(map(input,['']*5));x=0.
xsot

4

CJam, 23 byte

0l~{\)\$2/~+:(+_2=)}g;(

Provalo online

Questo prende frutto dalle 3 pile più grandi in ogni iterazione e conta il numero di iterazioni.

Non ho una prova matematica che questo dia sempre il risultato corretto. Lo fa per gli esempi di test forniti e credo che funzionerà per tutti i casi fino a quando qualcuno non mi darà un contro esempio.

La spiegazione intuitiva che ho usato per convincermi: per massimizzare il numero di torte, è necessario mantenere quante più pile possibile vuote. Questo perché perdi la possibilità di fare più torte non appena hai 3 o più pile vuote.

Questo si ottiene prendendo sempre frutta dalle pile più grandi. Non riesco a pensare a un caso in cui prendere frutta da una pila più piccola porterebbe a una situazione migliore rispetto a prendere frutta da una pila più grande.

Ho un ragionamento leggermente più formale nella mia testa. Proverò a pensare a un modo per dirlo in parole / formula.


Ho cercato di usare l'induzione; forse possiamo unire le nostre idee per trovare una prova formale.
lirtosiast

@ThomasKwa Non ho trovato niente di abbastanza chiaro che sembrerebbe convincente se lo scrivessi. Tutto dipende dal fatto che non vedo assolutamente alcun motivo per cui sarebbe mai meglio prendere da uno stack più piccolo a uno stack più grande. Mentre ci sono chiaramente situazioni in cui prendere da uno stack più piccolo sarebbe peggio. Ho anche inserito alcuni numeri casualmente moderatamente grandi nelle soluzioni di miniera e aditsu e hanno prodotto lo stesso risultato. La mia soluzione è anche coerente con la tua formula per gli esempi che ho provato.
Reto Koradi,

3

> <>, 76 byte

0&4\/~}&?!/
@:@<\!?:}$-1@@$!?&+&:)@:@
,:&:@(?$n;/++:&+::2%-2,:&:@(?$&~+:3%-3

Risulta che l'ordinamento in> <> non è facile! Questo programma si basa sulla dimostrazione fornita da Thomas Kwa per essere vera, che sembra certamente essere il caso dei casi di test.

I 5 numeri di input dovrebbero essere presenti nello stack all'inizio del programma.

Le prime due righe ordinano i numeri in pila e la terza esegue il calcolo floor(min((x1+x2+x3+x4+x5)/3,(x1+x2+x3+x4)/2,x1+x2+x3)), tratto dalla risposta di Thomas.


Sarebbe più breve se calcolassi tutte le somme di tre / quattro elementi e il minimo di quelle?
lirtosiast,

@ThomasKwa Sembra che ciò implichi la ricerca delle permutazioni del set di input, la somma dei 3 e 4 elementi più in alto di ciascuno e il più piccolo di essi? Non credo che trovare le permutazioni sarà più breve dell'approccio di ordinamento / calcolo che ho usato, specialmente in un linguaggio basato su stack. Se venissi a conoscenza di eventuali algoritmi utili per generare permutazioni in un linguaggio basato su stack sarei interessato a vedere: o)
Prese il

2

Python 2, 59 byte

h=lambda l,k=3:k*'_'and min(h(sorted(l)[:-1],k-1),sum(l)/k)

Un metodo generale che funziona per qualsiasi ne k. La k=3rende i frutti per impostazione predefinita torta per 3, ma è possibile passare in un valore diverso. La ricorsione utilizza il fatto che le stringhe sono più grandi dei numeri in Python 2, lasciando che la stringa vuota rappresenti il ​​caso base dell'infinito.

Questo metodo usa il fatto che assumere sempre il frutto più comune è ottimale, quindi consideriamo ogni possibile grado di frutto come un fattore limitante. Ho riprovato questo fatto di seguito.


La prova di Mego mi ha fatto pensare a questa prova più diretta che l'assunzione ripetuta dei frutti più comuni è ottimale. Questo è dichiarato con torte di kfrutta.

Teorema: l' assunzione ripetuta dei kfrutti più comuni fornisce il numero ottimale di torte.

Prova: mostreremo che se le Ntorte sono possibili, allora la strategia di frutta più comune produce almeno Ntorte. Facciamo questo cambiando i frutti tra le Ntorte per farle corrispondere a quelle prodotte da questa strategia, mantenendo valide le torte.

Facciamolo in modo che la prima torta (chiamalo p) contenga i frutti più comuni. Se non lo è ancora, deve contenere un frutto i, ma non un frutto più comune j. Quindi, le torte rimanenti hanno rigorosamente più frutta jche frutta i, e quindi alcune altre torte qdevono contenere jma non i. Quindi, possiamo scambiare frutta idalla torta pcon frutta jdalla torta q, che mantiene le Ntorte con frutti distinti.

Ripeti questo processo fino a quando non pha i kfrutti più comuni.

Quindi, metti pda parte la torta e ripeti questo processo per la prossima torta per far sì che abbia i frutti rimanenti più comuni. Continua fino a quando le torte non sono la sequenza prodotta dalla strategia della frutta più comune.


1

PowerShell, 92 byte

$a=($args|sort)-ne0;while($a.count-ge3){$a[0]--;$a[-1]--;$a[-2]--;$a=($a-ne0;$c++}($c,0)[!$c]

Utilizza lo stesso algoritmo avido basato sulla risposta di FryAmTheEggman ... solo molto più elaborato in PowerShell ....

$a=($args|sort)-ne0  # Take input arguments, sort them, remove any 0's
while($a.count-ge3){ # So long as we have 3 or more fruit piles
  $a[0]--            # Remove one from the first element...
  $a[-1]--           # ... the last element ...
  $a[-2]--           # ... and the second-to-last.
  $a=$a-ne0          # Remove any 0's from our piles
  $c++               # Increment how many pies we've made
}                    #
($c,0)[!$c]          # Equivalent to if($c){$c}else{0}
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.