Bu değer benzersiz para ve / veya notalarla yapılabilir mi?


29

Girilen bir parasal değerin bir tamsayı olarak benzersiz bir madeni para ve / veya not kombinasyonuyla gösterilip temsil edilemeyeceğini hesaplayan bir program yazın, bu aynı madalyonun / notun birden fazla kullanılamayacağı anlamına gelir.

Programınız girdi olarak bir değer almalı ve hem girdi hem de dilinizin bir dizisine eşdeğer bir madeni para / not değeri listesi alabilir. Madeni para / banknot listesi değişebilmelidir, bu nedenle eğer bir sabit kullanıyorsanız, bunun nerede tanımlandığından emin olun.

Programınız sırasıyla herhangi bir gerçek / sahte değeri vermelidir.

Değerini oluşturan sikke / notların listesini çıkış olduğunu not edin değil gerekli.

ÖRNEK

İngiliz Sterlini kullanarak, (1,00 £ = 100 ve 420,69 £ = 42069)

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

Aşağıdakiler doğru çıkacaktır:

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

Aşağıdaki yanlış çıkacaktır:

4
209
8889
4242424242
[ANYTHING ABOVE 8888]

ALTERNATİF TEST BİLGİLERİ (ABD Doları)

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

İyi şanslar!


4
Keşke senin gibi daha yeni gelenler de olsa ...
Leaky Nun


2
Farklı bir yazı tura kullanarak bazı test kodları eklemelisiniz
Leaky Nun

2
Açgözlü buluşma ile çözülemeyen test vakalarının en fazla kullanılmayan madalyonun en fazla kalan değerde alınmasının eklenmesini öneririm. Girişin sıralanmadığı ve bir değerin birden fazla şekilde yapılabildiği noktalara sahip olmak da iyi olacaktır. Genelde, test durumları için, her şeyden önce haklı olmadan, test durumlarında çalışan problemde makul bir girişimde bulunma ihtimalinden kaçınmak genellikle iyidir.
xnor

2
İlgili . Ayrıca ilgili . Eski sorunun tartışmalı bir kopyası var, ama bu soru IMO'nun daha iyi tasarlanmış olması ve eğer bir kopyasını koparmak istiyorsak, daha eski olanı kapatmak istiyorum.

Yanıtlar:


13

Brachylog 2 (TIO Nexus), 2 bayt

⊇+

Çevrimiçi deneyin!

Madeni para listesini standart girdi veya programın başlangıcına bir dizi değişmez olarak hazırlayarak alır (ya işe yarayacak, bu yüzden "daha meşru" olduğunuzu hissedeceksiniz; PPCG kuralları, soruya özel olarak izin verilen kurallar); ve bir komut satırı argümanı olarak üretmek için değer alır.

açıklama

Bu program, TIO Nexus'un Brachylog fonksiyonları için ambalajını kullanan uygulama detaylarını kullanır; özellikle, Çıkış üzerinden giriş yapmak için bir komut satırı argümanı vermenizi sağlar. (Bu Brachylog’un orijinal tasarımında öngörülmüyordu; ancak diller PPCG’de uygulanmalarıyla tanımlanıyor, ve bir uygulama gelirse ihtiyacım olanı yapmak için bu gerçekleşirse, bundan faydalanabilirim.) program şöyle görünür:

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

Tam bir program olarak, bir boole değeri döndürür; true.Programdaki tüm iddiaların aynı anda yerine getirilebilmesi false.durumunda ,

(Bir hatırlatıcı veya zaten bilmeyenler için: Brachylog 2, içinde bir bayt uzunluğa sahip olan kendi karakter kodlamasını kullanır .)


Brachylog'da ⊇'nın tek bir bayt olduğunu söylediniz, neden baytları buraya yapıştırmıyorsunuz? İddiaya girerim bunun bir nedeni var, sadece ilgileniyorum, bir karakter kodlama ucu.
theonlygusti

1
Diskte olduğu gibi kodlanmışlar 08 2B(kodlamaları burada bulabilirsiniz ). Belirli bir kodlamayı listelemememin nedeni bunun alakasız olmasıdır; tek önemli olan Brachylog’un 256 benzersiz karakter kullanmaması ve böylece her birinin tek bir baytta gösterilebilmesi. Bu genellikle kodu daha okunaklı kılmak için golf dilleri tarafından yapılır; bunun yerine sayfa 437 gibi bir kodlama kodunu kullanabilirlerdi, fakat bunu yaparsanız kimse okuyamazdı .

10

05AB1E , 4 bayt

æOså

Açıklama:

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

Çevrimiçi deneyin!


Resmi listeyi sıkıştırmak için herkesi resmen yanlış yönlendirmiş gibisin, p
Leaky Nun

Sıkıştırılmış listenizi silip girişe taşıdığınızda, cevabımı silerim (çünkü cevaplarımız aynı olur)
Leaky Nun

Bu topluluk dahi dolu.
Tobi

5

Mathematica, 25 bayt

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

İlk argüman olarak bir sikke-değer dizisini ve ikinci argüman olarak hedef tamsayı alarak ve döndüren Trueveya döndüren saf işlev False.



3

Retina , 52 31 bayt

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

Çevrimiçi deneyin! Girdiyi boşlukla ayrılmış bir madeni para ve not listesi ve ardından istenen değer olarak alır. Düzenleme: Kodumu hata ayıkladı @ Kobi sayesinde 18 bayt kaydedildi. Açıklama: İlk iki satır sadece ondalıktan birliğe dönüşür. Üçüncü satır daha sonra yazı turalarının ve notaların listesini gösterir. Değişim, motorun geriye doğru ilerlemesini ve belirli paraları / notları yakalamamayı seçmesini sağlar. Dengeleme grubu daha sonra, yakalama listesinin tüm sonlarına göre değeri eşleştirir (gereksiz ancak golfçü.)


İkinci seçenek çalışmaz çünkü motor 0 uzunluklu gruplara geri dönmez (can sıkıcı bir optimizasyon). Kullanılabilir ^((1+) )+(\2?(?<-2>)|){99}$(34 bayt, bozuk para sayısı sınırında) veya ^((1+) |1+ )+(\2?(?<-2>))+$(ayrıca 34 bayt).
Kobi

1
@Kobi Güzel! Her iki (?<-2>\2?)cevaptan da 2 bayt kurtardım, çünkü bunun işe yaradığını unuttum , artı ikinci cevabınız için bir bayt daha çünkü ?artık gerekli değil.
Neil,


2

Java (OpenJDK 8) , 125 bayt

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);}

Çevrimiçi deneyin!


Bunu bir lambdada yapmak kısaltabilir.
Okx,

@Okx Özyinelemelidir (bu yüzden daha uzun olur), ayrıca daha kısa olsalar bile lambda yapmam.
Leaky Rahibe

1
Algoritmanızın yinelemeli sürümü, diziyi kopyalama gereğini kaldırdığınızdan çok daha kısadır: boolean f(int[]c,int n){for(int l=c.length;l-->0;n-=n<c[l]?0:c[l]);return n<1;}(79 bayt). Java 8 ve lambdaları ile 62 bayta daha da düşürülebilir. Cevabınızı şu anda olduğu gibi, int l=c.length-1o zaman lyerine kullanmak l-1da daha kısa.
Olivier Grégoire


2

JavaScript (ES6), 81 69 67 64 bayt

Körme sözdiziminde madeni paraların listesini cve hedef miktarını alır . Veya döndürür .a(c)(a)0true

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

Test durumları


Madeni paraların listesine girme izni var mı?
Leaky Rahibe

@LeakyNun "... ve yazı / para değerlerinin bir listesini alabilir ..."
Martin Ender

1
Bu yüzden listeyi boşuna
kodladım

@LeakyNun Öyle görünüyor
Eddie Hart

2

Haskell , 28 bayt

İşleç işlevi (#)bir tamsayı ve bir tamsayı listesi (veya daha genel olarak herhangi bir Traversablesayı kabını) alır ve a'yı döndürür Bool.

Olarak kullanın 6#[1, 2, 5, 10, 20, 50, 100, 200, 500, 1000, 2000, 5000].

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

Çevrimiçi deneyin!

Nasıl çalışır

  • cİstenilen değer ve lmadeni paraların listesi.
  • mapM(:[0])lharita (:[0])üzerinde l, daha sonra 0 ile her değer eşleştirme, ve her eleman karşılık gelen değeri, burada listesi veren, kartezyen bir ürün oluşturur l, ya da 0.
  • sum<$>her bir kombinasyonu toplar ve sonuçta listede elem c$olup olmadığını kontrol eder c.

2

R, 88 83 bayt

@Jarko Dubbeldam sayesinde -5 bayt

isimsiz bir işlev döndürür. Tüm olası jeton kombinasyonlarını ( expand.gridçiftler halinde kullanarak T,F) üretir ve değerlerin mevcut olup olmadığını kontrol eder. R 'de ayrılmış bir kelime kolduğundan beri cparadır.

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

Çevrimiçi deneyin!


Sen değiştirebilir c(T,F)tarafından !0:1ve rep(list(!0:1),length(k))tarafındanlapply(k,function(x)!0:1)
JAD

1
Aslında, şunu yapMap(function(x)!0:1,k)
JAD

1

Japt , 7 bayt

à mx èN

Çevrimiçi deneyin! Çıkışlar 0falsy için, truthy için pozitif bir tamsayı.

açıklama

à 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

Ruby , 39 bayt

İade nilfalsy değeri ve truthy olarak numarası (tüm sayılar Ruby truthy vardır) oluşturan listedeki en küçük jeton değeri olarak.

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

Bununla birlikte, bu algoritmanın, madeni para listesinin uzunluğu olan O(C!)zaman karmaşıklığıyla delicesine yavaş olduğuna dikkat edin C. Sonunda biter, ancak çoğu test senaryosu çoğu çevrimiçi tercümana bile zaman aşımına uğrar f(UK_POUND, 5).

İşte ekstra bir bitiş koşulu ekleyerek çok daha hızlı biten ve aslında zaman aşımına uğraması zor olan 41 baytlık bir sürüm.

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

Çevrimiçi deneyin!


1

Bash + GNU yardımcı programları, 56 39

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

Giriş sıralama listesi (sıralanmamış) virgülle ayrılmış liste olarak verilir. Giriş listesi ve değer komut satırı parametreleri olarak verilmiştir.

Kabuk dönüş kodu şeklinde verilen çıktı. echo $?Komut dosyasını çalıştırdıktan sonra ile kontrol edin . 0truthy, sahte 1anlamına gelir.

Çevrimiçi deneyin .

  • printf %$2sbir valueboşluk dizesi çıkarır
  • "^ {${1//,/\}? {}}?$"mezhep listesini benzer bir regex'e genişleten bir kabuk genişletmedir ^ {1}? {2}? {5}? {10}? ... $. egrepRegex motorunun, hangi sıralamada olduğuna bakılmaksızın, bununla doğru şekilde eşleşebilecek kadar akıllı olduğu ortaya çıktı .
  • egrep boşluk dizesinin regex ile eşleşip eşleşmediğini kontrol eder.

1

C, 66 bayt

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

O bkz burada çalışmak .

C, 53 bayt

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

Bu değişken, bu problemin amacını yitiren bozuk para dizisini alır, çünkü basit çıkarmadan gelir.

İlk argüman jeton dizisi, ikincisi jeton sayımı ve üçüncüsü değerdir.

C, 48 bayt

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

Önceki değişkene bir alternatif. Bozuk para dizisinin tersine çevrilebileceğini ve sıfırlanabileceğini varsayar.



0

CJam , 18 17 bayt

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

Çevrimiçi deneyin!

açıklama

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

Octave, 39 bayt

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

İlk argüman olarak jeton-değer dizisini ve ikinci argüman olarak hedef tamsayı alan ve doğru ya da yanlış olarak döndüren adsız bir işlev.

Çevrimiçi deneyin!


0

Mathematica, 42 bayt

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

giriş

[15, {10,5}]

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.