Enumerazione dei problemi di cambio moneta usando N monete e ogni denominazione


13

Il problema del cambio delle monete è ben documentato. Dato un rifornimento infinito di monete di denominazioni x_1a x_mHai bisogno di trovare il numero di combinazioni che si sommano a y. Ad esempio, dato x = {1,2,3}e y = 4abbiamo quattro combinazioni:

  1. {1,1,1,1}
  2. {1,1,2}
  3. {1,3}
  4. {2,2}

introduzione

Esistono diverse varianti del problema di cambio moneta. In questa variante abbiamo due ulteriori restrizioni:

  1. Ogni denominazione deve essere utilizzata almeno una volta.
  2. Esattamente un numero fisso di monete deve essere utilizzato in totale.

Ad esempio, dato x = {1,2,3}, y = 36e n = 15dove nè il numero totale di monete che devono essere utilizzati, otteniamo quattro combinazioni:

  1. {1,2,2,2,2,2,2,2,3,3,3,3,3,3,3} (1 uno, 7 due, 7 tre)
  2. {1,1,2,2,2,2,2,3,3,3,3,3,3,3,3} (2, 5 o 8)
  3. {1,1,1,2,2,2,3,3,3,3,3,3,3,3,3} (3 uno, 3 due, 9 tre)
  4. {1,1,1,1,2,3,3,3,3,3,3,3,3,3,3} (4 unità, 1 coppia, 10 tre)

Sfida

La sfida è scrivere una funzione enumeratenella lingua di tua scelta che enumera tutte le combinazioni come descritto sopra dato:

  1. L'elenco delle denominazioni. Per esempio {1,5,10,25}. È possibile utilizzare elenchi o matrici.
  2. Un numero intero non negativo yche indica la somma di ogni combinazione.
  3. Un numero intero non negativo nche indica il numero totale di monete.

L'ordine degli argomenti non ha importanza. Sono ammesse funzioni senza punti.

L'output della enumeratefunzione deve essere un elenco di combinazioni. Ogni combinazione deve essere unica e deve essere un elenco di nnumeri interi che si sommano y. Ogni denominazione deve apparire almeno una volta in ogni combinazione e non deve mancare alcuna combinazione. L'ordinamento degli interi e delle combinazioni non ha importanza. È possibile utilizzare elenchi o matrici per l'output.

Tenere presente i seguenti casi limite:

  1. Se entrambi ye nsono zero e l'elenco delle denominazioni è vuoto, l'output è un elenco di una combinazione, la combinazione vuota (cioè {{}}).
  2. Altrimenti, se yè zero, nè zero o l'elenco delle denominazioni è vuoto, l'output è un elenco di zero combinazioni (cioè {}).
  3. Più in generale, se yè inferiore alla somma delle denominazioni o nè inferiore al numero di denominazioni, l'output è un elenco di zero combinazioni.

Il punteggio si baserà sulla dimensione dell'intero programma in byte. Si noti che ciò include la enumeratefunzione, le funzioni di supporto, le dichiarazioni di importazione, ecc. Non include i casi di test.


Abbastanza sicuro di aver visto questa sfida da qualche parte ...
Leaky Nun,

Spero che questa domanda non sia un duplicato. Non riuscivo a trovare la stessa domanda su Code Golf. Quindi, l'ho pubblicato.
Aadit M Shah,

@PeterTaylor Se yè inferiore alla somma delle denominazioni, ad un certo punto della soluzione ricorsiva raggiungerai il caso base in cui l'elenco delle denominazioni è vuoto. Quindi, la risposta sarà {}(cioè nessuna soluzione trovata). Se nè inferiore al numero di denominazioni, alla fine raggiungerai il caso base dove n = 0ma y != 0. Quindi, la risposta sarà di nuovo {}.
Aadit M Shah,

@PeterTaylor Effettivamente. Avrei potuto presumere troppo sui dettagli di implementazione. Sapresti come risolverlo?
Aadit M Shah,

10
Ti suggerisco di rimuovere il flag "Accettato" fino a quando non ottieni una risposta funzionante. E in generale è ragionevole aspettare un paio di giorni prima di accettare.
Peter Taylor,

Risposte:


2

05AB1E, 20 byte

g-¹sã€{Ùvy¹«DO³Qiˆ}¯

Input è nell'ordine: list of values, nr of coins, sum to reach.

Spiegazione in breve

  1. Ottieni tutte le permutazioni dell'elenco delle monete di lunghezza: final length - length of unique coin list
  2. Aggiungi l'elenco di monete uniche a questi elenchi.
  3. Se la somma è uguale alla somma desiderata, salva l'elenco
  4. Emette tutti gli elenchi salvati

Provalo online

Il compilatore online non può gestire un gran numero di monete.


4

MATL , 22 byte

Z^!S!Xu!tsi=Z)"1G@m?@!

L'ordine di input è: array di denominazioni, numero di monete prese ( n), somma desiderata ( y).

Ogni combinazione viene visualizzata su una riga diversa. L'output vuoto viene visualizzato come una stringa vuota (quindi nulla).

Provalo online!

Il codice esaurisce la memoria nel compilatore online per l'esempio nella sfida, ma funziona offline con un computer standard, ragionevolmente moderno:

>> matl
 > Z^!S!Xu!tsi=Z)"1G@m?@!
 > 
> [1 2 3]
> 15
> 36
1 1 1 1 2 3 3 3 3 3 3 3 3 3 3
1 1 1 2 2 2 3 3 3 3 3 3 3 3 3
1 1 2 2 2 2 2 3 3 3 3 3 3 3 3
1 2 2 2 2 2 2 2 3 3 3 3 3 3 3

Spiegazione

Z^      % Implicitly input array of denomminations and number of coins n. Compute 
        % Cartesian power. This gives 2D array with each "combination"
        % on a different row
!S!     % Sort each row
Xu      % Deduplicate rows
!       % Transpose: rows become columns. Call this array A
ts      % Push a copy, compute sum of each column
i       % Input y (desired sum)
=       % Logical array that contains true if the "combination" has the desired sum
Z)      % Keep only those columns in array A
"       % For each column
  1G    %   Push array of denominations again
  @     %   Push current column
  m     %   Is each denomination present in the column?
  ?     %   If so
    @!  %     Push current column again. Transpose into a row
        %   End if
        % End for
        % Implicitly display stack contents

3

Python 3, 120 106 byte

from itertools import*
lambda d,t,l:[i+d for i in combinations_with_replacement(d,l-len(d))if sum(i+d)==t]

Una funzione anonima che accetta input di una tupla di denominazioni del modulo (x_1, x_2, x_3 ... , x_k), un valore target e un numero di monete tramite argomento e restituisce un elenco di tuple del modulo [(solution_1), (solution_2), (solution_3), ... (solution_k)].

Come funziona

ItertoolsLa combinations_with_replacementfunzione è utilizzata per generare tutte le l-len(d)combinazioni, con la sostituzione, delle denominazioni. Aggiungendo da ciascuna di queste combinazioni, si garantisce che ogni denominazione appare almeno una volta e che la nuova combinazione ha lunghezza l. Se gli elementi di una combinazione si sommano a t, la combinazione viene aggiunta all'elenco di restituzione come tupla.

Provalo su Ideone


Un metodo alternativo per 108 byte

from itertools import*
lambda d,t,l:set(tuple(sorted(i+d))for i in product(d,repeat=l-len(d))if sum(i+d)==t)

Una funzione anonima che accetta input di una tupla di denominazioni del modulo (x_1, x_2, x_3 ... , x_k), un valore target e un numero di monete tramite argomento e restituisce un insieme di tuple del modulo {(solution_1), (solution_2), (solution_3), ... (solution_k)}.

Come funziona (altra versione)

Questo utilizza la productfunzione da itertoolsper generare tutte le l-len(d)disposizioni delle denominazioni. Aggiungendo da ciascuna di queste combinazioni, si garantisce che ogni denominazione appare almeno una volta e che la nuova combinazione ha lunghezza l. Se gli elementi di una combinazione si sommano a t, la combinazione viene ordinata, convertita da un elenco a una tupla e aggiunta alle tuple di ritorno. Infine, la chiamata setrimuove eventuali duplicati.

Provalo su Ideone (altra versione)


0

JavaScript (ES6), 135 byte

g=(a,n,y,r)=>n>0?y>0&&a.map((x,i)=>g(a.slice(i),n-1,y-x,[...r,x])):n|y||console.log(r)
(a,n,y)=>g(a,n-a.length,a.reduce((y,x)=>y-x,y),a)
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.