Questo valore può essere realizzato con monete e / o banconote uniche?


29

Scrivi un programma che calcola se un valore monetario immesso, come un numero intero, può essere rappresentato da una combinazione unica di monete e / o banconote, il che significa che la stessa moneta / banconota non può essere utilizzata più di una volta.

Il tuo programma dovrebbe assumere un valore come input e può prendere un elenco di valori coin / note tramite input o tramite l'equivalente di un array nella tua lingua. L'elenco di monete / banconote dovrebbe essere in grado di cambiare, quindi assicurati che sia chiaro dove viene definito se stai usando una costante.

Il tuo programma dovrebbe generare rispettivamente qualsiasi valore di verità / falsità.

Si noti che l'output l'elenco delle monete / note che compongono il valore è non è necessaria.

ESEMPIO

Utilizzando la sterlina inglese, (£ 1,00 = 100 e £ 420,69 = 42069)

coins = [1, 2, 5, 10, 20, 50, 100, 200, 500, 1000, 2000, 5000]

Quanto segue produrrà true:

6 (1, 5)
15 (10, 5)
88 (1, 2, 5, 10, 20, 50)
512 (500, 10, 2)
7003 (5000, 2000, 2, 1)

Il seguente output restituirà false:

4
209
8889
4242424242
[ANYTHING ABOVE 8888]

DATI DI PROVA ALTERNATIVI (Dollaro USA)

coins = [1, 5, 10, 25, 50, 100, 200, 500, 1000, 2000, 5000, 10000]

In bocca al lupo!


4
Vorrei che avessimo nuovi arrivati ​​come te ...
Leaky Nun,


2
Dovresti aggiungere alcuni test usando un diverso set di monete
Leaky Nun

2
Suggerirei di aggiungere casi di test che non possono essere risolti con l'avida euristica di prendere la più grande moneta inutilizzata che è al massimo il valore rimanente. Sarebbe anche utile avere quelli in cui l'input non è ordinato e in cui un valore può essere fatto in più di un modo. È generalmente buono per i casi di test evitare la possibilità che qualcuno faccia un ragionevole tentativo del problema che funziona per i casi di test senza avere ragione su tutto.
xnor

2
Correlato . Anche correlati . La prima domanda è probabilmente un duplicato, ma questa domanda è meglio progettata dall'IMO e se vogliamo chiuderne una come duplicata, preferirei chiudere la precedente.

Risposte:


13

Brachylog 2 (TIO Nexus), 2 byte

⊇+

Provalo online!

Prende l'elenco delle monete tramite input standard o anteponendolo all'inizio del programma come un array letterale (o funzionerà, quindi dipende da te che ritieni sia "più legittimo"; il primo è consentito per impostazione predefinita Regole PPCG, quest'ultima specificamente consentita dalla domanda); e accetta il valore da produrre come argomento della riga di comando.

Spiegazione

Questo programma utilizza i dettagli di implementazione del modo in cui il wrapper di TIO Nexus per le funzioni di Brachylog; in particolare, consente di fornire un argomento da riga di comando per fornire input tramite Output. (Questo non era previsto nel progetto originale di Brachylog; tuttavia, le lingue sono definite dalla loro implementazione su PPCG, e se arriva un'implementazione che accade per fare ciò di cui ho bisogno, posso quindi trarne vantaggio.) Ciò significa che il il programma si presenta così:

⊇+
⊇   Some subset of {standard input}
 +  sums to {the first command-line argument}

Come programma completo, restituisce un valore booleano; true.se tutte le affermazioni nel programma possono essere soddisfatte contemporaneamente o false.se non possono esserlo.

(Un promemoria o per le persone che non lo sanno già: Brachylog 2 utilizza la propria codifica dei caratteri in cui è lungo un singolo byte.)


Hai detto che ⊇ è un singolo byte in Brachylog, perché non incollare qui i byte? Scommetto che c'è una ragione per questo, sono solo interessato, un po 'di un nub di codifica dei personaggi.
theonlygusti,

1
Sono codificati su disco come 08 2B(puoi vedere le codifiche qui ). Il motivo per cui non ho elencato la codifica specifica è che è irrilevante; tutto ciò che conta davvero è che Brachylog utilizzi non più di 256 caratteri univoci, in modo che ciascuno possa essere rappresentato in un singolo byte. Questo è comunemente fatto dai linguaggi del golf per rendere il codice più leggibile; potrebbero invece utilizzare una codifica come code page 437, ma se lo facessi nessuno sarebbe in grado di leggerlo .

10

05AB1E , 4 byte

æOså

Spiegazione:

æ      Calculate the powerset of the first input
 O     Sum each element
  s    Put the second input at the top of the stack
   å   Check whether the input is in the powerset sum.

Provalo online!


Sembra che tu abbia indotto in errore tutti a comprimere l'elenco; p
Leaky Nun

Dopo aver cancellato l'elenco compresso e spostato nell'input, eliminerò la mia risposta (perché nel frattempo le nostre risposte sarebbero state le stesse)
Leaky Nun

Questa comunità è piena di geni.
Tobi,

5

Mathematica, 25 byte

!FreeQ[Tr/@Subsets@#,#2]&

Funzione pura che accetta una matrice di valori-moneta come primo argomento e numero intero di destinazione come secondo argomento, e ritorno Trueo False.



3

Retina , 52 31 byte

\d+
$*
^((1+) |1+ )+(?<-2>\2)+$

Provalo online! Prende l'input come un elenco separato da spazi di monete e banconote seguito dal valore desiderato. Modifica: salvato 18 byte grazie a @Kobi che ha eseguito il debug del mio codice. Spiegazione: Le prime due righe si convertono semplicemente da decimale a unario. La terza riga cattura quindi l'elenco di monete e banconote. L'alternanza consente al motore di tornare indietro e scegliere di non acquisire monete / banconote specifiche. Il gruppo di bilanciamento quindi confronta il valore con tutti i suffissi dell'elenco di acquisizione (non necessario ma più golfista).


La seconda opzione non funziona perché il motore non esegue il backtracking in gruppi di lunghezza 0 (un'ottimizzazione fastidiosa). È possibile utilizzare ^((1+) )+(\2?(?<-2>)|){99}$(34 byte, con limite al numero di monete) o ^((1+) |1+ )+(\2?(?<-2>))+$(anche 34 byte).
Kobi,

1
@Kobi Beautiful! Ho salvato 2 byte da entrambe le risposte perché ho dimenticato che (?<-2>\2?)funziona, più un ulteriore byte dalla tua seconda risposta perché ?non è più necessario.
Neil,


2

Java (OpenJDK 8) , 125 byte

boolean f(int[]c,int n){int l=c.length;if(l<1)return n==0;int[]a=java.util.Arrays.copyOf(c,l-1);return f(a,n-c[l-1])|f(a,n);}

Provalo online!


Fare questo in una lambda potrebbe renderlo più breve.
Okx,

@Okx È ricorsivo (quindi sarebbe più lungo), inoltre non faccio lambda anche se sarebbero più brevi.
Leaky Nun,

1
La versione iterativa dell'algoritmo è molto più breve quando si rimuove la necessità di copiare l'array: boolean f(int[]c,int n){for(int l=c.length;l-->0;n-=n<c[l]?0:c[l]);return n<1;}(79 byte). Con Java 8 e i suoi lambdas, può essere ulteriormente ridotto a 62 byte. Per quanto riguarda la tua risposta così com'è attualmente, l' int l=c.length-1utilizzo al lposto di l-1è anche più breve.
Olivier Grégoire,


2

JavaScript (ES6), 81 69 67 64 byte

Prende l'elenco delle monete ce l'importo target anella sintassi del curry (c)(a). Restituisce 0o true.

c=>g=(a,m=1)=>c.map((c,i)=>x-=c*(m>>i&1),x=a)&&!x||x-a&&g(a,m+1)

Casi test


Ti è permesso di prendere la lista delle monete?
Leaky Nun,

@LeakyNun "... e può prendere un elenco di valori di monete / banconote ..."
Martin Ender

1
Quindi ho codificato l'elenco per niente ...
Leaky Nun

@LeakyNun Sembra così
Eddie Hart

2

Haskell , 28 byte

La funzione operatore (#)accetta un numero intero e un elenco di numeri interi (o, più in generale, qualsiasi Traversablecontenitore di numeri) e restituisce a Bool.

Usa come 6#[1, 2, 5, 10, 20, 50, 100, 200, 500, 1000, 2000, 5000].

c#l=elem c$sum<$>mapM(:[0])l

Provalo online!

Come funziona

  • cè il valore desiderato e ll'elenco dei valori delle monete.
  • mapM(:[0])lesegue (:[0])la mappatura l, accoppiando ciascun valore con 0, quindi costruisce il prodotto cartesiano, fornendo elenchi in cui ogni elemento è il valore corrispondente in lo 0.
  • sum<$>somma ogni combinazione e elem c$controlla sec trova nell'elenco risultante.

2

R, 88 83 byte

-5 byte grazie a @Jarko Dubbeldam

restituisce una funzione anonima. Genera tutte le possibili combinazioni di monete (usando expand.gridsu coppie di T,F) e controlla se i valori sono presenti. kè monete poiché cè una parola riservata in R. Può controllare più valori contemporaneamente.

function(k,v)v%in%apply(expand.grid(Map(function(x)!0:1,k)),1,function(x)sum(k[x]))

Provalo online!


Puoi sostituirlo c(T,F)con !0:1e rep(list(!0:1),length(k))conlapply(k,function(x)!0:1)
JAD

1
In realtà, Map(function(x)!0:1,k)
fallo

1

Japt , 7 byte

à mx èN

Provalo online! Output 0per falsy, un numero intero positivo per verità.

Spiegazione

à mx èN
          // Implicit: U = input array, V = input integer, N = array of all inputs
à         // Take all combinations of U.
  mx      // Map each combination to its sum.
     è    // Count the number of items in the result which also exist in
      N   //   the array of inputs.
          // This returns 0 if no combination sums to V, a positive integer otherwise.
          // Implicit: output result of last expression


1

Rubino , 39 byte

Restituisce nilcome valore falso e il valore della moneta più piccolo nell'elenco che costituisce il numero come vero (tutti i numeri sono veri in Rubino).

f=->c,n{n!=0?c.find{|i|f[c-[i],n-i]}:1}

Attenzione, tuttavia, che questo algoritmo è follemente lento, con O(C!)complessità temporale, dov'è Cla lunghezza della lista delle monete. Alla fine finisce, ma la maggior parte dei casi di test andrà in timeout anche sulla maggior parte degli interpreti online f(UK_POUND, 5).

Ecco una versione da 41 byte che termina molto più velocemente aggiungendo una condizione di fine extra, ed è molto più difficile scadere

f=->c,n{n>0?c.find{|i|f[c-[i],n-i]}:n==0}

Provalo online!


1

Utilità Bash + GNU, 56 39

printf %$2s|egrep "^ {${1//,/\}? {}}?$"

L'elenco delle denominazioni di input (non ordinato) viene fornito come elenco separato da virgole. Elenco di input e valore sono indicati come parametri della riga di comando.

Output fornito sotto forma di codice di ritorno della shell. Ispezionare con echo $?dopo aver eseguito lo script. 0significa verità, 1significa falsità.

Provalo online .

  • printf %$2sgenera una stringa di valuespazi
  • "^ {${1//,/\}? {}}?$"è un'espansione della shell che espande l'elenco delle denominazioni in una regex come ^ {1}? {2}? {5}? {10}? ... $. Si scopre che il egrepmotore regex è abbastanza intelligente da adattarsi correttamente a questo, indipendentemente dall'ordine in cui si trovano le denominazioni
  • egrep controlla se la stringa di spazi corrisponde alla regex

1

C, 66 byte

m;v;f(n){for(m=1e5;m/=10;)for(v=5;n-=n<v*m?0:v*m,v/=2;);return!n;}

Guarda che funziona qui .

C, 53 byte

g(c,w,n)int*c;{for(;n-=n<c[--w]?0:c[w],w;);return!n;}

Questa variante prende l'array di monete, che sconfigge lo scopo di questo problema, perché si riduce alla semplice sottrazione.

Il primo argomento è l'array di monete, il secondo è il conteggio delle monete e il terzo è il valore.

C, 48 byte

g(c,n)int*c;{for(;n-=n<*c?0:*c,*++c;);return!n;}

Un'alternativa alla variante precedente. Presuppone che l'array di monete possa essere invertito e terminato con zero.



0

CJam , 18 17 byte

q~_,2\m*\f.*::+#)

Provalo online!

Spiegazione

q~                  e# Read and eval input.
  _,                e# Duplicate the money list and take its length.
    2\m*            e# Take the (length)th Cartesian power of [0 1].
        \f.*        e# Element-wise multiplication of each set of 0's and 1's with the money
                    e#   list. This is essentially the powerset, but with 0s instead of 
                    e#   missing elements.
            ::+     e# Sum each set.
               #    e# Find the index of the desired amount in the list. (-1 if not found)
                )   e# Increment. -1 => 0 (falsy), anything else => nonzero (truthy)



0

Ottava, 39 byte

 @(L,n)any(cellfun(@sum,powerset(L))==n)

Una funzione anonima che accetta una matrice di valori-moneta come primo argomento e l'intero di destinazione come secondo argomento e restituisce vero o falso.

Provalo online!


0

Mathematica, 42 byte

ListQ@NumberDecompose[#,Sort[#2,Greater]]&

ingresso

[15, {10,5}]

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.