Giá trị này có thể được thực hiện với các đồng tiền và / hoặc ghi chú độc đáo không?


29

Viết chương trình tính toán nếu một giá trị tiền tệ được nhập, dưới dạng số nguyên, có thể được biểu diễn bằng một tổ hợp tiền và / hoặc ghi chú duy nhất, có nghĩa là không thể sử dụng cùng một đồng tiền / ghi chú nhiều lần.

Chương trình của bạn sẽ lấy một giá trị làm đầu vào và có thể lấy danh sách các giá trị đồng xu / ghi chú thông qua đầu vào hoặc thông qua ngôn ngữ của bạn tương đương với một mảng. Danh sách tiền xu / ghi chú sẽ có thể thay đổi, vì vậy hãy chắc chắn rằng nó được xác định rõ nơi này được xác định nếu bạn đang sử dụng hằng số.

Chương trình của bạn sẽ xuất ra bất kỳ giá trị trung thực / giả mạo tương ứng.

Xin lưu ý rằng việc xuất ra danh sách các đồng xu / ghi chú tạo nên giá trị là không bắt buộc.

THÍ DỤ

Sử dụng bảng Anh, (£ 1,00 = 100 và £ 420,69 = 42069)

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

Sau đây sẽ xuất ra đúng:

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

Sau đây sẽ xuất sai:

4
209
8889
4242424242
[ANYTHING ABOVE 8888]

DỮ LIỆU KIỂM TRA THAY ĐỔI (Đô la Mỹ)

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

Chúc may mắn!


4
Tôi ước chúng ta có nhiều người mới như bạn ...
Leaky Nun


2
Bạn nên thêm một số testcase bằng cách sử dụng một bộ tiền xu khác
Leaky Nun

2
Tôi đề nghị thêm các trường hợp kiểm tra không thể giải quyết được bằng cách heuristic tham lam lấy đồng tiền chưa sử dụng lớn nhất, đó là nhiều nhất là giá trị còn lại. Cũng tốt nếu có những cái mà đầu vào không được sắp xếp và nơi có thể tạo ra một giá trị nhiều hơn một cách. Nói chung, nó tốt cho các trường hợp thử nghiệm để tránh khả năng ai đó đưa ra một nỗ lực hợp lý cho vấn đề phù hợp với các trường hợp thử nghiệm mà không đúng với mọi thứ.
xnor

2
Liên quan . Cũng liên quan . Câu hỏi trước đây được cho là trùng lặp, nhưng câu hỏi này là IMO được thiết kế tốt hơn và nếu chúng ta đóng một câu hỏi trùng lặp, tôi muốn đóng câu hỏi cũ hơn.

Câu trả lời:


13

Brachylog 2 (TIO Nexus), 2 byte

⊇+

Hãy thử trực tuyến!

Đưa danh sách các đồng tiền thông qua đầu vào tiêu chuẩn hoặc thông qua việc đưa nó vào đầu chương trình dưới dạng một mảng theo nghĩa đen (sẽ hoạt động, do đó, tùy theo bạn cảm thấy là "hợp pháp hơn"; Các quy tắc PPCG, sau này được cho phép cụ thể bởi câu hỏi); và lấy giá trị để tạo ra làm đối số dòng lệnh.

Giải trình

Chương trình này sử dụng các chi tiết triển khai về cách trình bao bọc của TIO Nexus cho các chức năng Brachylog; cụ thể, nó cho phép bạn đưa ra một đối số dòng lệnh để cung cấp đầu vào thông qua Đầu ra. (Điều này không được dự tính trong thiết kế ban đầu cho Brachylog; tuy nhiên, các ngôn ngữ được xác định bởi việc triển khai trên PPCG và nếu việc triển khai xuất hiện để làm những gì tôi cần, do đó tôi có thể tận dụng lợi thế của nó.) chương trình trông như thế này:

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

Là một chương trình đầy đủ, nó trả về giá trị boolean; true.nếu tất cả các xác nhận trong chương trình có thể được thỏa mãn đồng thời, hoặc false.nếu chúng không thể.

(Một lời nhắc hoặc cho những người chưa biết: Brachylog 2 sử dụng mã hóa ký tự của chính nó trong đó là một byte dài.)


Bạn nói rằng là một byte đơn trong Brachylog, tại sao bạn không dán các byte ở đây? Tôi cá là có một lý do cho nó, tôi chỉ quan tâm, một chút về mã hóa ký tự.
theonlygusti

1
Chúng được mã hóa trên đĩa dưới dạng 08 2B(bạn có thể xem các bảng mã ở đây ). Lý do tôi không liệt kê mã hóa cụ thể là vì nó không liên quan; tất cả những gì thực sự quan trọng là Brachylog sử dụng không quá 256 ký tự duy nhất, sao cho mỗi ký tự có thể được biểu diễn trong một byte đơn. Điều này thường được thực hiện bằng các ngôn ngữ chơi gôn để làm cho mã dễ đọc hơn; thay vào đó họ có thể sử dụng mã hóa như mã trang 437, nhưng nếu bạn làm điều đó thì không ai có thể đọc được .

10

05AB1E , 4 byte

æOså

Giải trình:

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

Hãy thử trực tuyến!


Có vẻ như bạn đã chính thức đánh lừa mọi người trong việc nén danh sách; p
Leaky Nun

Khi bạn đã xóa danh sách nén của mình và chuyển nó vào đầu vào, tôi sẽ xóa câu trả lời của mình (bởi vì vào thời điểm đó, câu trả lời của chúng tôi sẽ giống nhau)
Leaky Nun

Cộng đồng này đầy những thiên tài.
Tobi

5

Toán học, 25 byte

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

Hàm thuần túy lấy một mảng các giá trị coin làm đối số thứ nhất và số nguyên đích làm đối số thứ hai và trả về Truehoặc False.



3

Võng mạc , 52 31 byte

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

Hãy thử trực tuyến! Đưa đầu vào dưới dạng danh sách các đồng tiền và ghi chú được phân tách bằng dấu cách, theo sau là giá trị mong muốn. Chỉnh sửa: Đã lưu 18 byte nhờ @Kobi, người đã gỡ lỗi mã của tôi. Giải thích: Hai dòng đầu tiên chỉ đơn giản là chuyển đổi từ thập phân sang đơn nguyên. Dòng thứ ba sau đó nắm bắt danh sách các đồng tiền và ghi chú. Sự xen kẽ cho phép động cơ quay lại và chọn không chụp các đồng xu / ghi chú cụ thể. Nhóm cân bằng sau đó khớp giá trị với tất cả các hậu tố của danh sách chụp (không cần thiết nhưng golfier.)


Tùy chọn thứ hai không hoạt động vì động cơ không quay lại thành các nhóm có độ dài 0 (tối ưu hóa gây khó chịu). Bạn có thể sử dụng ^((1+) )+(\2?(?<-2>)|){99}$(34 byte, với giới hạn về số lượng tiền), hoặc ^((1+) |1+ )+(\2?(?<-2>))+$(cũng là 34 byte).
Kobi

1
@Kobi Đẹp quá! Tôi đã lưu 2 byte từ cả hai câu trả lời vì tôi quên rằng nó (?<-2>\2?)hoạt động, cộng với một byte nữa từ câu trả lời thứ hai của bạn vì ?không còn cần thiết nữa.
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);}

Hãy thử trực tuyến!


Làm điều này trong lambda có thể làm cho nó ngắn hơn.
Okx

@Okx Nó là đệ quy (vì vậy nó sẽ dài hơn), cộng với tôi không làm lambdas ngay cả khi chúng sẽ ngắn hơn.
Leaky Nun

1
Phiên bản lặp của thuật toán của bạn ngắn hơn khi bạn loại bỏ nhu cầu sao chép mảng: 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). Với Java 8 và lambdas của nó, nó có thể giảm xuống còn 62 byte. Về câu trả lời của bạn như hiện tại, int l=c.length-1sau đó sử dụng lthay vì l-1cũng ngắn hơn.
Olivier Grégoire


2

JavaScript (ES6), 81 69 67 64 byte

Đưa ra danh sách các đồng tiền cvà số tiền mục tiêu atrong cú pháp currying (c)(a). Trả về 0hoặc true.

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

Các trường hợp thử nghiệm


Bạn có được phép lấy danh sách các đồng tiền không?
Leaky Nun

@LeakyNun "... và có thể lấy danh sách các giá trị đồng xu / ghi chú ..."
Martin Ender

1
Vì vậy, tôi đã mã hóa danh sách mà không có gì ...
Leaky Nun

@LeakyNun Có vẻ như vậy
Eddie Hart

2

Haskell , 28 byte

Hàm toán tử (#)lấy một số nguyên và một danh sách các số nguyên (hay nói chung hơn là bất kỳ vùng Traversablechứa số nào) và trả về a Bool.

Sử dụng như 6#[1, 2, 5, 10, 20, 50, 100, 200, 500, 1000, 2000, 5000].

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

Hãy thử trực tuyến!

Làm thế nào nó hoạt động

  • clà giá trị mong muốn và ldanh sách các giá trị coin.
  • mapM(:[0])lánh xạ (:[0])qua l, ghép từng giá trị với 0 và sau đó xây dựng sản phẩm cartesian, đưa ra danh sách trong đó mỗi phần tử là giá trị tương ứng của nó trong lhoặc 0.
  • sum<$>tổng hợp từng kết hợp và elem c$kiểm tra nếu ccó trong danh sách kết quả.

2

R, 88 83 byte

-5 byte nhờ @Jarko Dubbeldam

trả về một hàm ẩn danh. Nó tạo ra tất cả các kết hợp có thể có của tiền (sử dụng expand.gridtrên các cặp T,F) và kiểm tra nếu có (các) giá trị. klà tiền xu vì clà một từ dành riêng trong R. Có thể kiểm tra nhiều giá trị cùng một lúc.

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

Hãy thử trực tuyến!


Bạn có thể thay thế c(T,F)bằng !0:1rep(list(!0:1),length(k))bằnglapply(k,function(x)!0:1)
JAD

1
Trên thực tế, hãy làm điều đóMap(function(x)!0:1,k)
JAD

1

Japt , 7 byte

à mx èN

Hãy thử trực tuyến! Đầu ra 0cho giả, một số nguyên dương cho sự thật.

Giải trình

à 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

Trả về nilgiá trị giả và giá trị đồng xu nhỏ nhất trong danh sách tạo thành số là trung thực (tất cả các số là trung thực trong Ruby).

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

Tuy nhiên, hãy cẩn thận, thuật toán này cực kỳ chậm, với O(C!)độ phức tạp về thời gian, trong đó Cđộ dài của danh sách tiền xu. Cuối cùng nó cũng kết thúc, nhưng hầu hết các trường hợp thử nghiệm sẽ hết thời gian trên hầu hết các thông dịch viên trực tuyến f(UK_POUND, 5).

Đây là phiên bản 41 byte kết thúc nhanh hơn nhiều bằng cách thêm một điều kiện kết thúc bổ sung và thực sự khó hơn nhiều khi hết thời gian

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

Hãy thử trực tuyến!


1

Tiện ích Bash + GNU, 56 39

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

Danh sách mệnh giá đầu vào (chưa sắp xếp) được đưa ra dưới dạng danh sách được phân tách bằng dấu phẩy. Danh sách đầu vào và giá trị được đưa ra dưới dạng tham số dòng lệnh.

Đầu ra được đưa ra dưới dạng mã trả lại shell. Kiểm tra với echo $?sau khi chạy tập lệnh. 0có nghĩa là sự thật, 1có nghĩa là giả.

Hãy thử trực tuyến .

  • printf %$2s xuất ra một chuỗi value khoảng trắng
  • "^ {${1//,/\}? {}}?$"là một bản mở rộng shell mở rộng danh sách mệnh giá thành regex như thế nào ^ {1}? {2}? {5}? {10}? ... $. Hóa ra làegrep công cụ regex đủ thông minh để khớp chính xác với điều này, bất kể mệnh giá là gì theo thứ tự
  • egrep kiểm tra xem chuỗi khoảng trắng có khớp với biểu thức chính quy không

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

Xem nó hoạt động ở đây .

C, 53 byte

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

Biến thể này lấy mảng coin, đánh bại mục đích của vấn đề này, bởi vì nó đi đến phép trừ đơn giản.

Đối số đầu tiên là mảng coin, thứ hai là số xu và thứ ba là giá trị.

C, 48 byte

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

Một thay thế cho các biến thể trước đó. Nó giả định rằng mảng coin có thể bị đảo ngược và không bị chấm dứt.



0

CJam , 18 17 byte

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

Hãy thử trực tuyến!

Giải trình

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 byte

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

Một hàm ẩn danh lấy một mảng các giá trị coin làm đối số thứ nhất và số nguyên đích làm đối số thứ hai và trả về true hoặc false.

Hãy thử trực tuyến!


0

Toán học, 42 byte

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

đầu vào

[15, {10,5}]

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.