Bisakah nilai ini dibuat dengan koin dan / atau catatan unik?


29

Tulis program yang menghitung jika nilai moneter yang dimasukkan, sebagai bilangan bulat, dapat diwakili oleh kombinasi unik koin dan / atau catatan, yang berarti koin / catatan yang sama tidak dapat digunakan lebih dari satu kali.

Program Anda harus mengambil nilai sebagai input, dan dapat mengambil daftar nilai koin / catatan baik melalui input atau melalui bahasa yang setara dengan array. Daftar koin / catatan harus dapat diubah, jadi pastikan sudah jelas di mana ini didefinisikan jika Anda menggunakan konstanta.

Program Anda harus menampilkan nilai kebenaran / kepalsuan masing-masing.

Harap dicatat bahwa mengeluarkan daftar koin / catatan yang membentuk nilai tidak diperlukan.

CONTOH

Menggunakan pound Inggris, (£ 1,00 = 100 dan £ 420,69 = 42069)

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

Berikut ini akan menampilkan true:

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

Berikut ini akan menampilkan false:

4
209
8889
4242424242
[ANYTHING ABOVE 8888]

DATA UJI ALTERNATIF (Dolar AS)

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

Semoga berhasil!


4
Saya berharap kami memiliki lebih banyak pendatang baru seperti Anda ...
Leaky Nun


2
Anda harus menambahkan beberapa testcases menggunakan set koin yang berbeda
Leaky Nun

2
Saya sarankan menambahkan test case yang tidak dapat diselesaikan dengan heuristik rakus mengambil koin terbesar yang tidak terpakai yaitu paling banyak nilai yang tersisa. Akan lebih baik jika ada yang inputnya tidak diurutkan dan di mana suatu nilai dapat dibuat lebih dari satu arah. Biasanya baik untuk kasus uji untuk menghindari kemungkinan seseorang melakukan upaya yang masuk akal pada masalah yang bekerja untuk kasus uji tanpa benar dalam segala hal.
xnor

2
Terkait . Juga terkait . Pertanyaan sebelumnya adalah duplikat, tetapi pertanyaan ini IMO dirancang lebih baik dan jika kita ingin menutupnya sebagai duplikat, saya lebih suka menutup yang lebih tua.

Jawaban:


13

Brachylog 2 (TIO Nexus), 2 byte

⊇+

Cobalah online!

Mengambil daftar koin baik melalui input standar atau melalui menambahkannya ke awal program sebagai array literal (keduanya akan bekerja, jadi terserah Anda yang Anda rasa "lebih sah"; yang pertama diizinkan secara default Aturan PPCG, yang terakhir secara khusus diizinkan oleh pertanyaan); dan mengambil nilai untuk menghasilkan sebagai argumen baris perintah.

Penjelasan

Program ini memanfaatkan detail implementasi dari cara pembungkus TIO Nexus untuk fungsi Brachylog; khusus, ini memungkinkan Anda memberikan argumen baris perintah untuk memberikan input melalui Output. (Ini tidak dipertimbangkan dalam desain asli untuk Brachylog; namun, bahasa didefinisikan oleh implementasinya di PPCG, dan jika implementasi muncul yang terjadi untuk melakukan apa yang saya butuhkan, maka saya dapat mengambil keuntungan darinya.) Itu berarti Program terlihat seperti ini:

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

Sebagai program penuh, ia mengembalikan nilai boolean; true.jika semua asersi dalam program dapat secara bersamaan dipenuhi, atau false.jika tidak bisa.

(Pengingat, atau untuk orang yang belum tahu: Brachylog 2 menggunakan pengkodean karakter sendiri yang panjangnya satu byte.)


Anda mengatakan bahwa ⊇ adalah byte tunggal di Brachylog, mengapa Anda tidak menempelkan byte di sini? Saya yakin ada alasan untuk itu, saya hanya tertarik, sedikit karakter-encoding nub.
theonlygusti

1
Mereka dikodekan pada disk sebagai 08 2B(Anda dapat melihat pengkodean di sini ). Alasan saya tidak mencantumkan pengkodean spesifik adalah bahwa itu tidak relevan; yang paling penting adalah bahwa Brachylog menggunakan tidak lebih dari 256 karakter unik, sehingga masing-masing dapat direpresentasikan dalam satu byte tunggal. Ini biasanya dilakukan oleh bahasa golf untuk membuat kode lebih mudah dibaca; mereka bisa menggunakan pengkodean seperti kode halaman 437 sebagai gantinya, tetapi jika Anda melakukannya tidak ada yang bisa membacanya .

10

05AB1E , 4 byte

æOså

Penjelasan:

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

Cobalah online!


Sepertinya Anda telah secara resmi menyesatkan semua orang untuk memadatkan daftar; p
Leaky Nun

Setelah Anda menghapus daftar terkompresi dan memindahkannya ke input, saya akan menghapus jawaban saya (karena pada saat jawaban kami akan sama)
Leaky Nun

Komunitas ini penuh dengan para genius.
Tobi

5

Mathematica, 25 byte

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

Fungsi murni mengambil array nilai koin sebagai argumen pertama dan integer target sebagai argumen kedua, dan mengembalikan Trueatau False.



3

Retina , 52 31 byte

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

Cobalah online! Mengambil input sebagai daftar koin dan catatan yang dipisahkan ruang diikuti oleh nilai yang diinginkan. Sunting: Disimpan 18 byte berkat @Kobi yang mendebug kode saya. Penjelasan: Dua baris pertama cukup mengkonversi dari desimal ke unary. Baris ketiga kemudian menangkap daftar koin dan catatan. Pergantian ini memungkinkan engine untuk mundur dan memilih untuk tidak menangkap koin / catatan tertentu. Kelompok penyeimbang kemudian mencocokkan nilai dengan semua sufiks dari daftar tangkap (tidak perlu tetapi pegolf).


Opsi kedua tidak berfungsi karena mesin tidak mundur ke grup 0-panjang (optimasi yang mengganggu). Anda dapat menggunakan ^((1+) )+(\2?(?<-2>)|){99}$(34 byte, dengan batasan jumlah koin), atau ^((1+) |1+ )+(\2?(?<-2>))+$(juga 34 byte).
Kobi

1
@Kobi Cantik! Saya menyimpan 2 byte dari kedua jawaban karena saya lupa itu (?<-2>\2?)berfungsi, ditambah byte lebih lanjut dari jawaban kedua Anda karena ?tidak lagi diperlukan.
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);}

Cobalah online!


Melakukan ini dalam lambda bisa membuatnya lebih pendek.
Okx

@ OKx Ini bersifat rekursif (jadi akan lebih lama), ditambah lagi saya tidak melakukan lambdas bahkan jika mereka akan lebih pendek.
Leaky Nun

1
Versi berulang algoritme Anda jauh lebih pendek saat Anda menghapus kebutuhan untuk menyalin larik: 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). Dengan Java 8 dan lambda-nya, dapat dikurangi menjadi 62 byte. Mengenai jawaban Anda seperti saat ini, int l=c.length-1maka menggunakan lbukan l-1juga lebih pendek.
Olivier Grégoire


2

JavaScript (ES6), 81 69 67 64 byte

Mengambil daftar koin cdan jumlah target adalam sintaks currying (c)(a). Pengembalian 0atau true.

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

Uji kasus


Apakah Anda diizinkan mengambil daftar koin?
Leaky Nun

@LeakyNun "... dan dapat mengambil daftar nilai koin / catatan ..."
Martin Ender

1
Jadi saya menyandikan daftar itu dengan gratis ...
Leaky Nun

@ LeakyNun Sepertinya begitu
Eddie Hart

2

Haskell , 28 byte

Fungsi operator (#)mengambil bilangan bulat dan daftar bilangan bulat (atau, lebih umum, Traversablewadah angka apa saja) dan mengembalikan a Bool.

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

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

Cobalah online!

Bagaimana itu bekerja

  • cadalah nilai yang diinginkan dan ldaftar nilai koin.
  • mapM(:[0])lmemetakan (:[0])lebih dari l, memasangkan setiap nilai dengan 0, dan kemudian membangun produk kartesius, memberikan daftar di mana setiap elemen baik nilai yang sesuai di dalam l, atau 0.
  • sum<$>jumlah setiap kombinasi, dan elem c$periksa apakah cada dalam daftar yang dihasilkan.

2

R, 88 83 byte

-5 byte terima kasih kepada @Jarko Dubbeldam

mengembalikan fungsi anonim. Ini menghasilkan semua kemungkinan kombinasi koin (menggunakan expand.gridpasangan T,F) dan memeriksa apakah nilainya ada. kadalah koin karena cmerupakan kata yang dilindungi undang-undang di R. Dapat memeriksa beberapa nilai sekaligus.

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

Cobalah online!


Anda dapat menggantinya c(T,F)dengan !0:1, dan rep(list(!0:1),length(k))olehlapply(k,function(x)!0:1)
JAD

1
Sebenarnya, buat ituMap(function(x)!0:1,k)
JAD

1

Japt , 7 byte

à mx èN

Cobalah online! Keluaran 0untuk falsy, bilangan bulat positif untuk kebenaran.

Penjelasan

à 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 byte

Mengembalikan nilsebagai nilai falsy, dan nilai koin terkecil dalam daftar yang menjadikan angka sebagai benar (semua angka benar di Ruby).

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

Berhati-hatilah, bagaimanapun, bahwa algoritma ini sangat lambat, dengan O(C!)kompleksitas waktu, di mana Cpanjang daftar koin. Ini akhirnya selesai, tetapi sebagian besar kasus uji akan time out pada sebagian besar penerjemah online f(UK_POUND, 5).

Ini adalah versi 41-byte yang selesai jauh lebih cepat dengan menambahkan kondisi akhir tambahan, dan jauh lebih sulit untuk benar-benar kehabisan waktu

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

Cobalah online!


1

Utilitas Bash + GNU, 56 39

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

Daftar denominasi input (tidak disortir) diberikan sebagai daftar yang dipisahkan koma. Daftar input dan nilai diberikan sebagai parameter baris perintah.

Output yang diberikan dalam bentuk kode pengembalian shell. Periksa dengan echo $?setelah menjalankan skrip. 0berarti jujur, 1berarti palsu.

Cobalah online .

  • printf %$2smenghasilkan serangkaian valuespasi
  • "^ {${1//,/\}? {}}?$"adalah ekspansi shell yang memperluas daftar denominasi ke seperti regex ^ {1}? {2}? {5}? {10}? ... $. Ternyata egrepmesin regex cukup pintar untuk mencocokkan dengan benar, terlepas dari apa urutan denominasi
  • egrep memeriksa apakah string spasi cocok dengan 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;}

Lihat berhasil di sini .

C, 53 byte

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

Varian ini menggunakan larik koin, yang mengalahkan tujuan dari masalah ini, karena turun ke pengurangan sederhana.

Argumen pertama adalah susunan koin, yang kedua adalah jumlah koin, dan yang ketiga adalah nilainya.

C, 48 byte

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

Alternatif untuk varian sebelumnya. Diasumsikan bahwa susunan koin dapat dibalik dan nol diakhiri.



0

CJam , 18 17 byte

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

Cobalah online!

Penjelasan

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

Oktaf, 39 byte

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

Fungsi anonim yang mengambil array nilai koin sebagai argumen pertama dan integer target sebagai argumen kedua, dan mengembalikan benar atau salah.

Cobalah online!


0

Mathematica, 42 byte

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

memasukkan

[15, {10,5}]

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.