การแจงนับปัญหาเปลี่ยนเหรียญโดยใช้ N เหรียญและแต่ละนิกาย


13

ปัญหาการเปลี่ยนแปลงเหรียญเป็นเอกสารที่ดีมาก ได้รับการจัดหาที่ไม่มีที่สิ้นสุดของเหรียญ ได้แก่x_1การที่คุณต้องพบจำนวนรวมกันซึ่งเพิ่มขึ้นถึงx_m yตัวอย่างเช่นที่กำหนดx = {1,2,3}และy = 4เรามีชุดค่าผสมสี่แบบ:

  1. {1,1,1,1}
  2. {1,1,2}
  3. {1,3}
  4. {2,2}

บทนำ

ปัญหาการเปลี่ยนเหรียญมีหลายรูปแบบ ในรูปแบบนี้เรามีข้อ จำกัด เพิ่มเติมสองประการ:

  1. ทุกนิกายจะต้องใช้อย่างน้อยหนึ่งครั้ง
  2. จำนวนเหรียญที่แน่นอนต้องถูกนำมาใช้ทั้งหมด

ตัวอย่างเช่นกำหนดx = {1,2,3}, y = 36และn = 15ที่nคือจำนวนของเหรียญที่จะต้องใช้เราได้รับสี่ชุดที่:

  1. {1,2,2,2,2,2,2,2,3,3,3,3,3,3,3} (1 รายการ, 7 twos, 7 threes)
  2. {1,1,2,2,2,2,2,3,3,3,3,3,3,3,3} (2 อัน, 5 twos, 8 threes)
  3. {1,1,1,2,2,2,3,3,3,3,3,3,3,3,3} (3 รายการ, 3 twos, 9 threes)
  4. {1,1,1,1,2,3,3,3,3,3,3,3,3,3,3} (4 รายการ 1 twos, 10 threes)

ท้าทาย

ความท้าทายคือการเขียนฟังก์ชั่นenumerateในภาษาที่คุณเลือกซึ่งจะระบุชุดค่าผสมทั้งหมดตามที่อธิบายไว้ข้างต้น:

  1. รายการของนิกาย {1,5,10,25}เช่น คุณสามารถใช้รายการหรืออาร์เรย์
  2. จำนวนเต็มที่ไม่เป็นลบyที่แสดงผลรวมของทุกชุดค่าผสม
  3. จำนวนเต็มที่ไม่เป็นลบnที่ระบุจำนวนเหรียญทั้งหมด

ลำดับของข้อโต้แย้งไม่สำคัญ อนุญาตให้ใช้ฟังก์ชั่น Pointfree

ผลลัพธ์ของenumerateฟังก์ชันจะต้องเป็นรายการของชุดค่าผสม ชุดค่าผสมแต่ละชุดต้องไม่ซ้ำกันและต้องเป็นรายการnจำนวนเต็มที่รวมyกัน ทุกประเภทจะต้องปรากฏอย่างน้อยหนึ่งครั้งในแต่ละชุดค่าผสมและจะต้องไม่หายไป การเรียงลำดับของจำนวนเต็มและชุดค่าผสมนั้นไม่สำคัญ คุณสามารถใช้รายการหรืออาร์เรย์สำหรับเอาต์พุต

โปรดจำไว้ว่ากรณีขอบต่อไปนี้:

  1. หากทั้งสองyและnเป็นศูนย์และรายการของนิกายว่างเปล่าเอาท์พุทเป็นรายการของการรวมกันหนึ่งชุดที่ว่างเปล่า (เช่น{{}})
  2. มิฉะนั้นถ้าyเป็นศูนย์จะมีค่าnเป็นศูนย์หรือรายการของสกุลเงินว่างเปล่าผลลัพธ์คือรายการของการรวมศูนย์ (เช่น{})
  3. โดยทั่วไปถ้าyน้อยกว่าผลรวมของหน่วยหรือnน้อยกว่าจำนวนหน่วยดังนั้นเอาต์พุตคือรายการของชุดค่าผสมศูนย์

การให้คะแนนจะขึ้นอยู่กับขนาดของโปรแกรมทั้งหมดในหน่วยไบต์ โปรดทราบว่าสิ่งนี้รวมถึงenumerateฟังก์ชั่นฟังก์ชั่นผู้ช่วยคำสั่งนำเข้าและอื่น ๆ มันไม่รวมกรณีทดสอบ


ค่อนข้างมั่นใจว่าผมเคยเห็นที่ไหนสักแห่งความท้าทายนี้ ...
รั่วนูน

ฉันหวังว่าคำถามนี้จะไม่ซ้ำกัน ฉันไม่พบคำถามเดียวกันบน Code Golf ดังนั้นฉันโพสต์มัน
Aadit M Shah

@PeterTaylor หากyน้อยกว่าผลรวมของนิกายนั้นในบางจุดในโซลูชันแบบเรียกซ้ำของคุณคุณจะไปถึงกรณีพื้นฐานที่รายการของนิกายว่างเปล่า ดังนั้นคำตอบจะเป็น{}(เช่นไม่พบวิธีแก้ไข) ถ้าnเป็นน้อยกว่าจำนวนของนิกายแล้วในที่สุดคุณจะถึงกรณีฐานที่แต่n = 0 ดังนั้นคำตอบอีกครั้งจะเป็นy != 0 {}
Aadit M Shah

@PeterTaylor แน่นอน ฉันอาจคาดเดารายละเอียดการใช้งานมากเกินไป คุณรู้วิธีแก้ไขไหม
Aadit M Shah

10
ฉันขอแนะนำให้คุณลบการตั้งค่าสถานะ "ยอมรับ" จนกว่าคุณจะได้รับคำตอบที่ถูกต้อง และโดยทั่วไปก็ควรรอสองสามวันก่อนที่จะยอมรับ
Peter Taylor

คำตอบ:


2

05AB1E, 20 ไบต์

g-¹sã€{Ùvy¹«DO³Qiˆ}¯

list of valuesการป้อนข้อมูลที่อยู่ในการสั่งซื้อ: nr of coins, sum to reach,

คำอธิบายสั้น ๆ

  1. รับการเรียงสับเปลี่ยนทั้งหมดของรายการเหรียญความยาว: final length - length of unique coin list
  2. เพิ่มรายการเหรียญที่ไม่ซ้ำในรายการเหล่านี้
  3. ถ้าผลรวมเท่ากับผลรวมที่ต้องการให้บันทึกรายการ
  4. ส่งออกรายการที่บันทึกไว้ทั้งหมด

ลองออนไลน์

คอมไพเลอร์ออนไลน์ไม่สามารถจัดการเหรียญจำนวนมากได้


4

MATL , 22 ไบต์

Z^!S!Xu!tsi=Z)"1G@m?@!

ลำดับการป้อนข้อมูลคือ: อาร์เรย์ของจำนวนเหรียญที่ใช้ ( n), ผลรวมที่ต้องการ ( y)

ชุดค่าผสมแต่ละชุดจะแสดงบนบรรทัดที่แตกต่างกัน เอาท์พุทที่ว่างเปล่าจะปรากฏเป็นสตริงที่ว่างเปล่า (ไม่มีอะไรเลย)

ลองออนไลน์!

โค้ดมีหน่วยความจำไม่เพียงพอในคอมไพเลอร์ออนไลน์สำหรับตัวอย่างในการท้าทาย แต่ทำงานแบบออฟไลน์กับคอมพิวเตอร์มาตรฐานที่ทันสมัยพอสมควร:

>> matl
 > Z^!S!Xu!tsi=Z)"1G@m?@!
 > 
> [1 2 3]
> 15
> 36
1 1 1 1 2 3 3 3 3 3 3 3 3 3 3
1 1 1 2 2 2 3 3 3 3 3 3 3 3 3
1 1 2 2 2 2 2 3 3 3 3 3 3 3 3
1 2 2 2 2 2 2 2 3 3 3 3 3 3 3

คำอธิบาย

Z^      % Implicitly input array of denomminations and number of coins n. Compute 
        % Cartesian power. This gives 2D array with each "combination"
        % on a different row
!S!     % Sort each row
Xu      % Deduplicate rows
!       % Transpose: rows become columns. Call this array A
ts      % Push a copy, compute sum of each column
i       % Input y (desired sum)
=       % Logical array that contains true if the "combination" has the desired sum
Z)      % Keep only those columns in array A
"       % For each column
  1G    %   Push array of denominations again
  @     %   Push current column
  m     %   Is each denomination present in the column?
  ?     %   If so
    @!  %     Push current column again. Transpose into a row
        %   End if
        % End for
        % Implicitly display stack contents

3

Python 3, 120 106 ไบต์

from itertools import*
lambda d,t,l:[i+d for i in combinations_with_replacement(d,l-len(d))if sum(i+d)==t]

ฟังก์ชั่นที่ไม่ระบุชื่อที่ใช้ใส่ของ tuple ของนิกายของแบบฟอร์ม(x_1, x_2, x_3 ... , x_k), [(solution_1), (solution_2), (solution_3), ... (solution_k)]ค่าเป้าหมายและจำนวนเหรียญผ่านการโต้แย้งและการกลับรายการของสิ่งอันดับของรูปแบบ

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

Itertoolsของcombinations_with_replacementฟังก์ชั่นที่ใช้ในการสร้างทั้งหมดl-len(d)รวมกันกับการเปลี่ยนของนิกาย โดยการผนวกกับแต่ละชุดที่เหล่านี้จะรับประกันว่าแต่ละนิกายปรากฏขึ้นอย่างน้อยหนึ่งครั้งและที่รวมกันใหม่มีความยาวd lหากองค์ประกอบของผลรวมการรวมtการรวมกันจะถูกเพิ่มลงในรายการส่งคืนเป็น tuple

ลองใช้กับ Ideone


วิธีทางเลือกสำหรับ 108 ไบต์

from itertools import*
lambda d,t,l:set(tuple(sorted(i+d))for i in product(d,repeat=l-len(d))if sum(i+d)==t)

ฟังก์ชั่นที่ไม่ระบุชื่อที่ใช้ใส่ของ tuple ของนิกายของแบบฟอร์ม(x_1, x_2, x_3 ... , x_k), ค่าเป้าหมายและจำนวนเหรียญผ่านอาร์กิวเมนต์และส่งกลับชุดของ tuples {(solution_1), (solution_2), (solution_3), ... (solution_k)}ของรูปแบบ

มันทำงานอย่างไร (เวอร์ชั่นอื่น)

สิ่งนี้ใช้productฟังก์ชันจากitertoolsเพื่อสร้างl-len(d)การเตรียมการทั้งหมดของนิกาย โดยการผนวกกับแต่ละชุดที่เหล่านี้จะรับประกันว่าแต่ละนิกายปรากฏขึ้นอย่างน้อยหนึ่งครั้งและที่รวมกันใหม่มีความยาวd lหากองค์ประกอบของผลรวมtการรวมเป็นชุดค่าจะถูกเรียงลำดับแปลงจากรายการเป็น tuple และเพิ่มลงใน tuples ที่ส่งคืน ในที่สุดการโทรsetจะลบรายการที่ซ้ำกัน

ลองใช้กับ Ideone (เวอร์ชั่นอื่น)


0

JavaScript (ES6), 135 ไบต์

g=(a,n,y,r)=>n>0?y>0&&a.map((x,i)=>g(a.slice(i),n-1,y-x,[...r,x])):n|y||console.log(r)
(a,n,y)=>g(a,n-a.length,a.reduce((y,x)=>y-x,y),a)
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.