Kann dieser Wert mit eindeutigen Münzen und / oder Banknoten erzielt werden?

29

Schreiben Sie ein Programm, das berechnet, ob ein eingegebener Geldwert als Ganzzahl durch eine eindeutige Kombination von Münzen und / oder Banknoten dargestellt werden kann. Dies bedeutet, dass dieselbe Münze / Banknote nur einmal verwendet werden kann.

Ihr Programm sollte einen Wert als Eingabe annehmen und kann eine Liste von Münz- / Notenwerten entweder über die Eingabe oder über die Entsprechung eines Arrays in Ihrer Sprache aufnehmen. Die Liste der Münzen / Banknoten sollte sich ändern können. Stellen Sie daher sicher, dass klar ist, wo dies definiert ist, wenn Sie eine Konstante verwenden.

Ihr Programm sollte jeweils einen Wahrheits- / Falschwert ausgeben.

Bitte beachten Sie, dass die Ausgabe der Liste der Münzen / Banknoten, aus denen der Wert besteht, nicht erforderlich ist.

BEISPIEL

Mit dem britischen Pfund (1,00 £ = 100 und 420,69 £ = 42069)

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

Folgendes wird true ausgeben:

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

Folgendes wird false ausgeben:

4
209
8889
4242424242
[ANYTHING ABOVE 8888]

ALTERNATIVE TESTDATEN (US-Dollar)

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

Viel Glück!

Eddie Hart
quelle
4
Ich wünschte, wir hätten mehr Neulinge wie Sie ...
Undichte Nonne
Related
Adnan
2
Sie sollten einige Testfälle mit einem anderen Satz von Münzen hinzufügen
Leaky Nun
2
Ich würde vorschlagen, Testfälle hinzuzufügen, die mit der gierigen Heuristik, die darin besteht, die größte unbenutzte Münze zu nehmen, die höchstens den verbleibenden Wert darstellt, nicht gelöst werden können. Es wäre auch gut, solche zu haben, bei denen die Eingabe nicht sortiert ist und bei denen ein Wert auf mehrere Arten erstellt werden kann. Im Allgemeinen ist es für Testfälle gut, zu vermeiden, dass jemand einen vernünftigen Versuch unternimmt, das Problem zu lösen, das für die Testfälle funktioniert, ohne bei allem Recht zu haben.
8.
2
Verwandte . Auch verwandt . Die erste Frage ist wohl ein Duplikat, aber diese Frage ist IMO besser gestaltet und wenn wir eine als Duplikat schließen wollen, würde ich lieber die ältere schließen.

Antworten:

13

Brachylog 2 (TIO Nexus), 2 Bytes

⊇+

Probieren Sie es online!

Nimmt die Liste der Münzen entweder über die Standardeingabe oder durch Voranstellen vor dem Start des Programms als Array-Literal (entweder funktioniert es, also liegt es an Ihnen, was Sie für "legitimer" halten; ersteres ist standardmäßig zulässig) PPCG-Regeln (letzteres ist in der Frage ausdrücklich erlaubt); und nimmt den zu erzeugenden Wert als Befehlszeilenargument.

Erläuterung

Dieses Programm verwendet Implementierungsdetails der Art und Weise, wie der Wrapper von TIO Nexus für Brachylog funktioniert. Insbesondere können Sie ein Befehlszeilenargument angeben, um Eingaben über die Ausgabe zu erhalten. (Dies war im ursprünglichen Design für Brachylog nicht vorgesehen. Sprachen werden jedoch durch ihre Implementierung in PPCG definiert. Wenn eine Implementierung folgt, die genau das tut, was ich brauche, kann ich sie daher nutzen.) Programm sieht so aus:

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

Als vollständiges Programm gibt es einen Booleschen Wert zurück. true.ob alle Behauptungen im Programm gleichzeitig erfüllt werden können oder false.nicht.

(Eine Erinnerung oder für Leute, die es noch nicht wissen: Brachylog 2 verwendet eine eigene Zeichenkodierung, die ein einziges Byte lang ist.)


quelle
Sie sagten, dass ⊇ ein einzelnes Byte in Brachylog ist. Warum fügen Sie die Bytes hier nicht ein? Ich wette, es gibt einen Grund dafür, ich bin nur interessiert, ein bisschen wie ein zeichencodierender Nub.
theonlygusti
1
Sie sind auf der Festplatte als 08 2B(Sie können die Codierungen hier nachschlagen) codiert . Der Grund, warum ich die spezielle Codierung nicht angegeben habe, ist, dass sie irrelevant ist. Alles, was wirklich zählt, ist, dass Brachylog nicht mehr als 256 eindeutige Zeichen verwendet, sodass jedes in einem einzelnen Byte dargestellt werden kann. Dies geschieht üblicherweise durch Golfsprachen, um den Code besser lesbar zu machen. Sie könnten stattdessen eine Codierung wie Codepage 437 verwenden, aber wenn Sie dies tun, könnte sie niemand lesen .
10

05AB1E , 4 Bytes

æOså

Erläuterung:

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

Probieren Sie es online!

Okx
quelle
Sieht so aus, als hätten Sie alle offiziell dazu verleitet, die Liste zu komprimieren: p
Leaky Nun,
Sobald Sie Ihre komprimierte Liste gelöscht und in die Eingabe verschoben haben, werde ich meine Antwort löschen (da unsere Antworten zu dem Zeitpunkt identisch sein würden)
Leaky Nun,
Diese Community ist voller Genies.
Tobi
5

Mathematica, 25 Bytes

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

Reine Funktion, die ein Array von Münzwerten als erstes Argument und die Ziel-Ganzzahl als zweites Argument verwendet und Trueoder zurückgibt False.

Greg Martin
quelle
4

Gelee, 6 Bytes

ŒPS€e@

Probieren Sie es online!

-2 Bytes dank Leaky Nun
-13 Bytes dank Leaky Nun (lange Geschichte)

HyperNeutrino
quelle
@LeakyNun Heh, es gibt eine bessere Lösung, nicht wahr?
HyperNeutrino
@ JonathanAllan Oh, whoops. Vielen Dank!
HyperNeutrino
TIO-Link hinzugefügt;)
Ok,
3

Retina , 52 31 Bytes

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

Probieren Sie es online! Übernimmt die Eingabe als durch Leerzeichen getrennte Liste von Münzen und Banknoten, gefolgt vom gewünschten Wert. Bearbeiten: Dank @Kobi, der meinen Code getestet hat, wurden 18 Bytes gespeichert. Erläuterung: Die ersten beiden Zeilen werden einfach von dezimal in unär umgewandelt. Die dritte Zeile erfasst dann die Liste der Münzen und Banknoten. Die Abwechslung ermöglicht es dem Motor, zurückzuverfolgen und bestimmte Münzen / Banknoten nicht zu erfassen. Die Bilanzgruppe vergleicht dann den Wert mit allen Suffixen der Erfassungsliste (unnötig, aber golferischer).

Neil
quelle
Die zweite Option funktioniert nicht, da die Engine nicht in Gruppen mit der Länge 0 zurückverfolgt (eine ärgerliche Optimierung). Sie können ^((1+) )+(\2?(?<-2>)|){99}$(34 Bytes, mit Begrenzung der Anzahl der Münzen) oder ^((1+) |1+ )+(\2?(?<-2>))+$(auch 34 Bytes) verwenden.
Kobi
1
@Kobi Schön! Ich habe 2 Bytes von beiden Antworten gespeichert, weil ich vergessen habe, dass dies (?<-2>\2?)funktioniert, plus ein weiteres Byte von Ihrer zweiten Antwort, weil die ?nicht mehr erforderlich ist.
Neil
2

Brachylog , 7 Bytes

tT&h⊇+T

Probieren Sie es online!

Wie es funktioniert

tT&h⊇+T
tT      the second input is T
  &     and
   h    the first input
    ⊇   is a superset of a set
     +  that sums up to
      T T

Einschließlich der Kombination, 9 Bytes

tT&h⊇.+T∧

Probieren Sie es online!

Undichte Nonne
quelle
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);}

Probieren Sie es online!

Undichte Nonne
quelle
Wenn Sie dies in einem Lambda tun, wird es möglicherweise kürzer.
Ok,
@Okx Es ist rekursiv (also würde es länger sein) und ich mache keine Lambdas, auch wenn sie kürzer wären.
Undichte Nonne
1
Die iterative Version Ihres Algorithmus ist viel kürzer, da Sie das Array nicht kopieren müssen: 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). Mit Java 8 und seinen Lambdas kann es weiter auf 62 Bytes reduziert werden. Bezüglich Ihrer Antwort, wie sie aktuell ist, int l=c.length-1ist die Verwendung von lanstelle von l-1ebenfalls kürzer.
Olivier Grégoire
2

Prolog (SWI) , 46 Bytes

a([],0).
a([H|T],X):-Y is X-H,(a(T,Y);a(T,X)).

Probieren Sie es online!

Gabel meiner Python Antwort .

Undichte Nonne
quelle
2
Sie können GNU Prolog speichern 2 Byte wahrscheinlich stattdessen unter Verwendung von (so dass Sie buchstabieren , iswie #=, die Sie einige Leerzeichen entfernen lassen würde).
2

JavaScript (ES6), 81 69 67 64 Byte

Nimmt die Liste der Münzen cund den Zielbetrag ain Curry-Syntax auf (c)(a). Rückgabe 0oder true.

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

Testfälle

Arnauld
quelle
Dürfen Sie die Münzliste mitnehmen?
Undichte Nonne
@LeakyNun "... und kann eine Liste mit Münzen- / Banknotenwerten aufnehmen ..."
Martin Ender
1
Also habe ich die Liste für nichts verschlüsselt ...
Undichte Nonne
@LeakyNun Es scheint so
Eddie Hart
2

Haskell , 28 Bytes

Die Operatorfunktion (#)nimmt eine Ganzzahl und eine Liste von Ganzzahlen (oder allgemeiner einen beliebigen TraversableContainer mit Zahlen) und gibt a zurück Bool.

Verwenden Sie als 6#[1, 2, 5, 10, 20, 50, 100, 200, 500, 1000, 2000, 5000].

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

Probieren Sie es online!

Wie es funktioniert

  • cist der gewünschte Wert und ldie Liste der Münzwerte.
  • mapM(:[0])lordnet (:[0])über l, paart jeden Wert mit 0 und konstruiert dann das kartesische Produkt, wobei Listen angegeben werden, in denen jedes Element entweder den entsprechenden Wert in loder 0 hat.
  • sum<$>summiert jede Kombination und elem c$prüft, ob sie cin der Ergebnisliste enthalten ist.
Ørjan Johansen
quelle
2

R 88 83 Bytes

-5 Bytes dank @Jarko Dubbeldam

Gibt eine anonyme Funktion zurück. Es generiert alle möglichen Kombinationen von Münzen (mit Hilfe expand.gridvon Paaren von T,F) und prüft, ob die Werte vorhanden sind. kist eine Münze, da ces sich bei R um ein reserviertes Wort handelt. Kann mehrere Werte gleichzeitig prüfen.

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

Probieren Sie es online!

Giuseppe
quelle
Sie können c(T,F)durch !0:1und rep(list(!0:1),length(k))durch ersetzenlapply(k,function(x)!0:1)
JAD
1
Eigentlich machen Sie dasMap(function(x)!0:1,k)
JAD
1

Japt , 7 Bytes

à mx èN

Probieren Sie es online! Ausgaben 0für Falsy, eine positive Ganzzahl für Truthy.

Erläuterung

à 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
ETHproductions
quelle
1

Ruby , 39 Bytes

Gibt nilden falschen Wert und den kleinsten Münzwert in der Liste zurück, der die Zahl als wahr darstellt (alle Zahlen sind in Ruby wahr).

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

Aber Sie passen, dass dieser Algorithmus irrsinnig langsam ist, mit O(C!)Zeitkomplexität, wo Cdie Länge der Münze Liste. Es endet schließlich, aber die meisten Testfälle laufen bei den meisten Online-Dolmetschern sogar aus f(UK_POUND, 5).

Hier ist eine 41-Byte-Version, die durch Hinzufügen einer zusätzlichen Endebedingung viel schneller beendet wird und eine Zeitüberschreitung erheblich erschwert

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

Probieren Sie es online!

Wert Tinte
quelle
1

Bash + GNU-Dienstprogramme, 56 39

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

Eingabebezeichnungsliste (unsortiert) wird als durch Kommas getrennte Liste angegeben. Eingabeliste und Wert werden als Befehlszeilenparameter angegeben.

Ausgabe in Form des Shell-Returncodes. Überprüfen Sie mit, echo $?nachdem Sie das Skript ausgeführt haben. 0bedeutet wahr, 1bedeutet falsch.

Probieren Sie es online aus .

  • printf %$2sgibt eine Folge von valueLeerzeichen aus
  • "^ {${1//,/\}? {}}?$"ist eine Shell-Erweiterung, die die Nennwertliste zu einem regulären Ausdruck erweitert ^ {1}? {2}? {5}? {10}? ... $. Es stellt sich heraus, dass die egrepRegex-Engine intelligent genug ist, um mit dieser übereinzustimmen, unabhängig davon, in welcher Reihenfolge sich die Nennwerte befinden
  • egrep prüft, ob die Zeichenkette mit dem regulären Ausdruck übereinstimmt
Digitales Trauma
quelle
1

C 66 Bytes

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

Sehen Sie es hier arbeiten .

C 53 Bytes

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

Diese Variante verwendet das Coin-Array, das den Zweck dieses Problems zunichte macht, da es sich um eine einfache Subtraktion handelt.

Das erste Argument ist das Münzfeld, das zweite die Münzzahl und das dritte der Wert.

C 48 Bytes

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

Eine Alternative zur vorherigen Variante. Es wird davon ausgegangen, dass das Münzarray umgekehrt und nullterminiert werden kann.

2501
quelle
0

CJam , 18 17 Bytes

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

Probieren Sie es online!

Erläuterung

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)
Geschäfts-Katze
quelle
0

PHP, 70 Bytes

Gibt 1 für wahr und nichts für falsch aus

<?foreach($_GET[1]as$v)$i-=$v*$r[]=($i=&$_GET[0])/$v^0;echo max($r)<2;

Probieren Sie es online!

Jörg Hülsermann
quelle
0

Oktave, 39 Bytes

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

Eine anonyme Funktion, die ein Array von Münzwerten als erstes Argument und die Ziel-Ganzzahl als zweites Argument verwendet und true oder false zurückgibt.

Probieren Sie es online!

rahnema1
quelle
0

Mathematica, 42 Bytes

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

Eingang

[15, {10,5}]

J42161217
quelle