ค่านี้สามารถทำด้วยเหรียญและ / หรือธนบัตรที่ไม่ซ้ำกันได้หรือไม่?


29

เขียนโปรแกรมที่คำนวณว่ามูลค่าเงินที่ป้อนเข้าเป็นจำนวนเต็มสามารถแสดงด้วยการรวมกันที่ไม่ซ้ำกันของเหรียญและ / หรือธนบัตรซึ่งหมายความว่าเหรียญ / ธนบัตรเดียวกันไม่สามารถใช้งานได้มากกว่าหนึ่งครั้ง

โปรแกรมของคุณควรรับค่าเป็นอินพุตและสามารถใช้รายการค่าเหรียญ / โน้ตได้ผ่านอินพุตหรือผ่านอาร์เรย์ของภาษาของคุณ รายการเหรียญ / ธนบัตรควรสามารถเปลี่ยนแปลงได้ดังนั้นโปรดตรวจสอบให้แน่ใจว่ามีการกำหนดที่ชัดเจนหากคุณใช้ค่าคงที่

โปรแกรมของคุณควรส่งออกค่าความจริง / เท็จใด ๆ ตามลำดับ

โปรดทราบว่าไม่จำเป็นต้องแสดงรายการเหรียญ / ธนบัตรที่สร้างมูลค่า

ตัวอย่าง

ใช้ปอนด์สหราชอาณาจักร (1.00 = 100 และ£ 420.69 = 42069)

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

ผลลัพธ์ต่อไปนี้จะเป็นจริง:

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

ผลลัพธ์ต่อไปนี้จะเป็นเท็จ:

4
209
8889
4242424242
[ANYTHING ABOVE 8888]

ข้อมูลการทดสอบทางเลือก (ดอลลาร์สหรัฐ)

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

โชคดี!


4
ฉันหวังว่าเราจะมีผู้มาใหม่เหมือนคุณ ...
รั่วนูน


2
คุณควรเพิ่มเครื่องทดสอบบางอย่างโดยใช้ชุดเหรียญอื่น
Leaky Nun

2
ฉันขอแนะนำให้เพิ่มกรณีทดสอบที่ไม่สามารถแก้ไขได้ด้วยวิธีแก้ปัญหาแบบโลภของการใช้เหรียญที่ไม่ได้ใช้ที่ใหญ่ที่สุดนั่นคือมูลค่าที่เหลืออยู่มากที่สุด นอกจากนี้ยังเป็นการดีหากมีรายการที่อินพุตไม่ได้ถูกจัดเรียงและค่าสามารถสร้างได้มากกว่าหนึ่งวิธี โดยทั่วไปแล้วเป็นสิ่งที่ดีสำหรับกรณีทดสอบเพื่อหลีกเลี่ยงความเป็นไปได้ที่บางคนพยายามอย่างมีเหตุผลในปัญหาที่ใช้ได้กับกรณีทดสอบโดยไม่ถูกต้องกับทุกสิ่ง
xnor

2
ที่เกี่ยวข้อง ที่เกี่ยวข้องอีกด้วย คำถามก่อนหน้านี้เป็นคำถามที่ซ้ำกัน แต่คำถามนี้เป็น IMO ที่ออกแบบมาดีกว่าและถ้าเราจะปิดคำถามที่ซ้ำกันฉันควรปิดคำถามเก่ากว่า

คำตอบ:


13

Brachylog 2 (TIO Nexus) 2 ไบต์

⊇+

ลองออนไลน์!

รับรายชื่อเหรียญทั้งผ่านทางอินพุตมาตรฐานหรือผ่านการเติมจนถึงจุดเริ่มต้นของโปรแกรมในรูปแบบของอาร์เรย์ (อาจใช้งานได้ดังนั้นจึงขึ้นอยู่กับคุณว่าคุณรู้สึกว่า "ถูกกฎหมายมากขึ้น" หรือไม่ กฏการจ่ายต่อหนึ่งคลิก PPCG ซึ่งได้รับอนุญาตเป็นพิเศษจากคำถาม); และรับค่าเพื่อสร้างเป็นอาร์กิวเมนต์บรรทัดคำสั่ง

คำอธิบาย

โปรแกรมนี้ใช้ประโยชน์จากรายละเอียดการนำไปใช้ของวิธีห่อหุ้มของ TIO Nexus สำหรับฟังก์ชั่น Brachylog; โดยเฉพาะมันช่วยให้คุณกำหนดอาร์กิวเมนต์บรรทัดคำสั่งเพื่อให้อินพุตผ่านเอาต์พุต (นี่ไม่ใช่ภาพวาดในการออกแบบดั้งเดิมสำหรับ Brachylog อย่างไรก็ตามภาษานั้นถูกกำหนดโดยการใช้งานบน PPCG และหากมีการติดตั้งเกิดขึ้นเพื่อทำสิ่งที่ฉันต้องการฉันจึงสามารถใช้ประโยชน์จากมันได้) นั่นหมายความว่า โปรแกรมดูเหมือนว่านี้:

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

ในฐานะโปรแกรมเต็มรูปแบบจะส่งคืนค่าบูลีน true.หากการยืนยันทั้งหมดในโปรแกรมสามารถสร้างความพึงพอใจไปพร้อม ๆ กันหรือfalse.ไม่สามารถทำได้

(คำเตือนหรือสำหรับคนที่ยังไม่รู้: Brachylog 2 ใช้การเข้ารหัสอักขระของตัวเองซึ่งมีความยาวไบต์เดียว)


คุณบอกว่า⊇เป็นไบต์เดียวใน Brachylog ทำไมคุณไม่วางไบต์ที่นี่? ฉันพนันว่ามีเหตุผลมันฉันแค่สนใจบิตของการเข้ารหัสอักขระ nub
theonlygusti

1
พวกเขากำลังเข้ารหัสบนดิสก์เป็น08 2B(คุณสามารถดูการเข้ารหัสที่นี่ ) เหตุผลที่ฉันไม่ได้ระบุการเข้ารหัสที่เฉพาะเจาะจงก็คือมันไม่เกี่ยวข้องเลย สิ่งที่สำคัญจริงๆก็คือ Brachylog ใช้อักขระไม่เกิน 256 ตัวเพื่อให้แต่ละอักขระสามารถแสดงเป็นไบต์เดียว โดยทั่วไปจะใช้ภาษาการตีกอล์ฟเพื่อให้อ่านง่ายขึ้น พวกเขาสามารถใช้การเข้ารหัสเช่นรหัสหน้า 437 แทน แต่ถ้าคุณไม่ว่าไม่มีใครจะสามารถที่จะอ่านมัน

10

05AB1E , 4 ไบต์

æOså

คำอธิบาย:

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

ลองออนไลน์!


ดูเหมือนว่าคุณเข้าใจผิดทุกคนอย่างเป็นทางการในการบีบอัดรายการ p
Leaky Nun

เมื่อคุณลบรายการที่บีบอัดและย้ายไปยังข้อมูลที่ป้อนแล้วฉันจะลบคำตอบของฉัน (เพราะเมื่อเวลาที่คำตอบของเราจะเหมือนเดิม)
Leaky Nun

ชุมชนนี้เต็มไปด้วยอัจฉริยะ
Tobi

5

Mathematica ขนาด 25 ไบต์

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

ฟังก์ชั่นการถ่ายเพียวอาร์เรย์ของเหรียญค่านิยมเป็นอาร์กิวเมนต์แรกและจำนวนเต็มเป้าหมายเป็นอาร์กิวเมนต์ที่สองและกลับมาหรือTrueFalse


4

เยลลี่ 6 ไบต์

ŒPS€e@

ลองออนไลน์!

-2 ไบต์ขอบคุณแม่ชี Leaky
-13 ไบต์ขอบคุณแม่ชี Leaky (เรื่องยาว)



@LeakyNun Heh มีทางออกที่ดีกว่าไม่ได้มี
HyperNeutrino

@JanathanAllan โอ้โห ขอบคุณ!
HyperNeutrino

เพิ่มลิงค์ TIO;)
Okx

3

เรติน่า52 52ไบต์

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

ลองออนไลน์! ใช้อินพุตเป็นรายการเหรียญและบันทึกย่อที่คั่นด้วยช่องว่างตามด้วยค่าที่ต้องการ แก้ไข: บันทึกแล้ว 18 ไบต์ขอบคุณ @Kobi ผู้ที่ดีรหัสของฉัน คำอธิบาย: สองบรรทัดแรกเพียงแปลงจากทศนิยมเป็น unary บรรทัดที่สามนั้นจะรวบรวมรายชื่อเหรียญและธนบัตร การสลับช่วยให้เครื่องยนต์ย้อนกลับและเลือกที่จะไม่จับเหรียญ / ธนบัตรเฉพาะ จากนั้นกลุ่มที่สมดุลจะจับคู่ค่ากับส่วนต่อท้ายทั้งหมดของรายการบันทึกภาพ (ไม่จำเป็น แต่มีนักกอล์ฟ)


ตัวเลือกที่สองไม่ทำงานเนื่องจากเครื่องมือไม่ย้อนรอยไปเป็นกลุ่มความยาว 0 (การเพิ่มประสิทธิภาพที่น่ารำคาญ) คุณสามารถใช้^((1+) )+(\2?(?<-2>)|){99}$(34 ไบต์ จำกัด จำนวนเหรียญ) หรือ^((1+) |1+ )+(\2?(?<-2>))+$(34 ไบต์ด้วย)
Kobi

1
@Kobi สวย! ฉันบันทึก 2 ไบต์จากคำตอบทั้งสองเพราะฉันลืมว่ามัน(?<-2>\2?)ใช้ได้และอีกหนึ่งไบต์จากคำตอบที่สองของคุณเพราะ?ไม่จำเป็นอีกต่อไป
Neil


2

Java (OpenJDK 8) , 125 ไบต์

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

ลองออนไลน์!


การทำสิ่งนี้ในแลมบ์ดาอาจทำให้สั้นลง
Okx

@Okx มันเป็นแบบเรียกซ้ำ (ดังนั้นมันจะนานกว่า) บวกกับฉันไม่ได้ทำ lambdas แม้ว่ามันจะสั้นกว่าก็ตาม
Leun Nun

1
เวอร์ชันซ้ำของอัลกอริทึมของคุณสั้นลงเนื่องจากคุณไม่จำเป็นต้องคัดลอกอาร์เรย์: boolean f(int[]c,int n){for(int l=c.length;l-->0;n-=n<c[l]?0:c[l]);return n<1;}(79 ไบต์) ด้วย Java 8 และ lambdas สามารถลดได้ถึง 62 ไบต์ เกี่ยวกับคำตอบของคุณตามที่เป็นอยู่ในปัจจุบันint l=c.length-1จากนั้นใช้lแทนl-1จะสั้นกว่า
Olivier Grégoire

2

Prolog (SWI)ขนาด 46 ไบต์

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

ลองออนไลน์!

ส้อมของคำตอบหลามของฉัน


2
คุณสามารถบันทึก 2 ไบต์โดยใช้ GNU Prolog แทน (อนุญาตให้คุณสะกดisเป็น#=ซึ่งจะช่วยให้คุณลบช่องว่างบางส่วน)

2

JavaScript (ES6), 81 69 67 64 ไบต์

รับรายการของเหรียญcและปริมาณเป้าหมายในไวยากรณ์a currying (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)

กรณีทดสอบ


คุณได้รับอนุญาตให้นำรายชื่อเหรียญหรือไม่
Leun Nun

@LeakyNun "... และสามารถนำรายชื่อค่าเหรียญ / ธนบัตร ... "
Martin Ender

1
ดังนั้นผมจึงเข้ารหัสรายการเพื่ออะไร ...
รั่วนูน

@LeakyNun ดูเหมือนว่า
Eddie Hart

2

Haskell , 28 ไบต์

ฟังก์ชั่นผู้ประกอบการ(#)จะใช้เวลาเป็นจำนวนเต็มและรายชื่อของจำนวนเต็ม (หรือมากกว่าปกติใด ๆTraversableที่เก็บของตัวเลข) Boolและผลตอบแทน

6#[1, 2, 5, 10, 20, 50, 100, 200, 500, 1000, 2000, 5000]ใช้เป็น

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

ลองออนไลน์!

มันทำงานอย่างไร

  • cคือค่าที่ต้องการและlรายการค่าเหรียญ
  • mapM(:[0])lแผนที่(:[0])มากกว่าlคู่แต่ละค่ากับ 0 แล้วสร้างผลิตภัณฑ์คาร์ทีเซียนให้รายการที่แต่ละองค์ประกอบเป็นทั้งค่าที่สอดคล้องกันในlหรือ 0
  • sum<$>สรุปผลรวมแต่ละชุดและelem c$ตรวจสอบว่าcอยู่ในรายการผลลัพธ์หรือไม่

2

R, 88 83 ไบต์

-5 ไบต์ขอบคุณ @Jarko Dubbeldam

ส่งคืนฟังก์ชั่นที่ไม่ระบุชื่อ มันสร้างการผสมที่เป็นไปได้ทั้งหมดของเหรียญ (ใช้expand.gridกับคู่ของT,F) และตรวจสอบว่ามีมูลค่า (s) kเป็นเหรียญเนื่องจากcเป็นคำที่สงวนไว้ใน R สามารถตรวจสอบค่าได้หลายค่าพร้อมกัน

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

ลองออนไลน์!


คุณสามารถแทนที่c(T,F)โดย!0:1และrep(list(!0:1),length(k))โดยlapply(k,function(x)!0:1)
JAD

1
ที่จริงแล้วทำอย่างนั้นMap(function(x)!0:1,k)
JAD

1

Japtap , 7 ไบต์

à mx èN

ลองออนไลน์! เอาต์พุต0สำหรับ falsy ซึ่งเป็นจำนวนเต็มบวกสำหรับความจริง

คำอธิบาย

à 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 ไบต์

ส่งคืนnilเป็นค่าที่ไม่แน่นอนและค่าเหรียญที่เล็กที่สุดในรายการที่ประกอบขึ้นเป็นจำนวนจริง (ตัวเลขทั้งหมดเป็นจริงในทับทิม)

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

อย่างไรก็ตามโปรดระวังว่าอัลกอริทึมนี้ช้าอย่างบ้าคลั่งโดยมีO(C!)ความซับซ้อนของเวลาอยู่ที่ไหนCความยาวของรายการเหรียญ ในที่สุดมันก็เสร็จสิ้น f(UK_POUND, 5)แต่ส่วนใหญ่กรณีทดสอบจะหมดเวลาในล่ามออนไลน์มากที่สุดแม้

นี่คือรุ่น 41 ไบต์ที่เสร็จเร็วขึ้นมากโดยการเพิ่มเงื่อนไขการสิ้นสุดพิเศษและยากยิ่งที่จะหมดเวลาจริง

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

ลองออนไลน์!


1

ยูทิลิตี Bash + GNU, 56 39

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

รายการที่ได้รับการป้อนข้อมูล (ไม่ได้เรียง) จะถูกกำหนดเป็นรายการที่คั่นด้วยเครื่องหมายจุลภาค รายการอินพุตและค่าถูกกำหนดเป็นพารามิเตอร์บรรทัดคำสั่ง

เอาต์พุตที่กำหนดในรูปแบบของโค้ดส่งคืนเชลล์ ตรวจสอบด้วยecho $?หลังจากเรียกใช้สคริปต์ 0หมายถึงความจริง1หมายถึงความเท็จ

ลองมันออนไลน์

  • printf %$2sเอาต์พุตสตริงของvalueช่องว่าง
  • "^ {${1//,/\}? {}}?$"คือการขยายตัวของเชลล์ที่ขยายรายการนิกายเพื่อ regex ^ {1}? {2}? {5}? {10}? ... $เช่น ปรากฎว่าเอ็นegrepจิ้น regex นั้นฉลาดพอที่จะจับคู่กับสิ่งนี้ได้อย่างถูกต้องโดยไม่คำนึงถึงลำดับที่มีอยู่
  • egrep ตรวจสอบว่าสตริงของช่องว่างตรงกับ regex

1

C, 66 ไบต์

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

เห็นมันทำงานที่นี่

C, 53 ไบต์

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

ตัวแปรนี้ใช้อาเรย์เหรียญซึ่งเอาชนะจุดประสงค์ของปัญหานี้ได้เนื่องจากมันเป็นการลบแบบง่าย

อาร์กิวเมนต์แรกคืออาร์เรย์เหรียญที่สองคือการนับเหรียญและที่สามคือค่า

C, 48 ไบต์

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

ทางเลือกที่แตกต่างจากรุ่นก่อนหน้า จะถือว่าอาร์เรย์เหรียญสามารถย้อนกลับและสิ้นสุดลงเป็นศูนย์



0

CJam , 18 17 ไบต์

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

ลองออนไลน์!

คำอธิบาย

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

อ็อกเทฟ 39 ไบต์

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

ฟังก์ชั่นที่ไม่ระบุชื่อที่ใช้อาร์เรย์ของค่าเหรียญเป็นอาร์กิวเมนต์แรกและจำนวนเต็มเป้าหมายเป็นอาร์กิวเมนต์ที่สองและส่งกลับจริงหรือเท็จ

ลองออนไลน์!


โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.