เงินที่บันทึกไว้เป็นเงิน


21

... นับ!

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

หมายเหตุเกี่ยวกับคำศัพท์เกี่ยวกับเหรียญอเมริกัน:

  • เหรียญร้อยละ 1: เพนนี
  • เหรียญ 5 เซ็นต์: นิกเกิล
  • เหรียญร้อยละ 10: ค่าเล็กน้อย
  • เหรียญ 25 เซ็นต์: ไตรมาส (ดอลลาร์สี่ไตรมาส)

ตัวอย่างที่ 1:

โปรแกรมผ่าน:

12, [1, 5, 10]

(12 เซ็นต์)

เอาท์พุท:

4

มี 4 วิธีที่เป็นไปได้ในการรวมเหรียญที่มีชื่อเพื่อสร้าง 12 เซนต์:

  1. 12 เพนนี
  2. 1 นิกเกิลและ 7 เพนนี
  3. 2 nickels และ 2 pennies
  4. 1 เซนต์และ 2 เพนนี

ตัวอย่างที่ 2:

โปรแกรมผ่าน:

26, [1, 5, 10, 25]

(26 เซ็นต์)

เอาท์พุท:

13

มี 13 วิธีในการรวมเหรียญที่มีชื่อเพื่อสร้าง 26 เซ็นต์:

  1. 26 เพนนี
  2. 21 เพนนีและนิกเกิล 1 อัน
  3. 16 เพนนีและ 2 นิค
  4. 11 pennies และ 3 nickels
  5. 6 pennies และ 4 nickels
  6. 1 เพนนีและ 5 นิค
  7. 16 เพนนีและ 1 เซนต์เล็กน้อย
  8. 6 เพนนีและ 2 เซนต์
  9. 11 เพนนี 1 เซนต์และนิกเกิล 1 อัน
  10. 6 เพนนี 1 เซนต์และ 2 นิค
  11. 1 เพนนี 1 เซนต์และ 3 นิค
  12. 1 เพนนี 2 สลึงและนิกเกิล 1 อัน
  13. 1 ในสี่และ 1 เพนนี

ตัวอย่างที่ 3:

โปรแกรมผ่าน:

19, [2, 7, 12]

เอาท์พุท:

2

มี 2 ​​วิธีที่เป็นไปได้ในการรวมเหรียญที่มีชื่อเพื่อสร้าง 19 เซ็นต์:

  1. เหรียญ 12 เซนต์ 1 เหรียญและเหรียญ 7 เซนต์ 1 เหรียญ
  2. เหรียญ 7 เซ็นต์ 1 เหรียญและเหรียญ 2 เซ็นต์ 6 เหรียญ

ตัวอย่างที่ 4:

โปรแกรมผ่าน:

13, [2, 8, 25]

เอาท์พุท:

0

ไม่มีวิธีที่เป็นไปได้ในการรวมเหรียญที่มีชื่อเพื่อสร้าง 13 เซนต์


สิ่งนี้ผ่าน Sandbox ช่องโหว่มาตรฐานใช้ นี่คือรหัสกอล์ฟดังนั้นคำตอบที่มีจำนวนไบต์น้อยที่สุดจะเป็นผู้ชนะ


1
s / นับ / รับ
mbomb007

4
@ mbomb007 s/count/earnสี่ไบต์:
wizzwizz4

5
สำหรับฉันและฉันคิดว่าสำหรับคนอื่น ๆ ที่ไม่ได้จ่ายด้วยดอลลาร์มันไม่ชัดเจนว่านิกเกิลและค่าเล็กน้อยเป็นอย่างไร มันไม่ยากที่จะคิดออก แต่บางทีคุณอาจจะเขียนได้มากกว่านี้อีกสักหน่อย?
Kritzefitz

2
@Kritzefitz ฉันได้เพิ่มเข้าไปในคำถาม
TRiG

2
@jpaugh: ในขณะที่ coin-o-philes อาจเห็นด้วยฉันต้องไม่เห็นด้วย เพนนีเป็นเหรียญมาตรฐานที่มีมูลค่าหนึ่งเซ็นต์ เซ็นต์ห้าสิบสี่เป็นจำนวนเงิน เหรียญห้าสิบสี่เป็นเหรียญห้าสิบสี่อย่างชัดเจน มันเรียกอีกอย่างว่า "เหรียญหนึ่งเซ็นต์" หรือ (เป็นทางการ) "เหรียญหนึ่งเซ็นต์" ฉันไม่สามารถนึกถึงสภาพแวดล้อมที่เป็นทางการซึ่งคำว่า "เพนนี" จะยอมรับไม่ได้ คนเหล่านี้ที่มีความเฉพาะเจาะจงเกี่ยวกับการเก็บเหรียญไม่มีปัญหาที่เรียกว่า "เพนนี"
MichaelS

คำตอบ:


12

เยลลี่ ( ส้อม ) 2 ไบต์

æf

สิ่งนี้ขึ้นอยู่กับสาขาของ Jelly ที่ฉันทำงานเกี่ยวกับการใช้ Frobenius แก้ปัญหาอะตอมดังนั้นน่าเสียดายที่คุณไม่สามารถลองออนไลน์ได้

การใช้

$ ./jelly eun 'æf' '12' '[1,5,10]'
4
$ ./jelly eun 'æf' '26' '[1,5,10,25]'
13
$ ./jelly eun 'æf' '19' '[2,7,12]'
2
$ ./jelly eun 'æf' '13' '[2,8,25]'
0

คำอธิบาย

æf  Input: total T, denominations D
æf  Frobenius count, determines the number of solutions
    of nonnegative X such that X dot-product D = T

10
... นั่นไม่ยุติธรรมเลย
ETHproductions

... และฉันพนันได้เร็วกว่ามาก!
Jonathan Allan

18

Haskell, 37 34 ไบต์

s#l@(c:d)|s>=c=(s-c)#l+s#d
s#_=0^s

ตัวอย่างการใช้งาน: ->26 # [1,5,10,25]13

วิธีเรียกซ้ำง่าย ๆ : ลองทั้งหมายเลขถัดไปในรายการ (ตราบใดที่มันน้อยกว่าหรือเท่ากับจำนวน) และข้ามมัน หากนำไปสู่การลบจำนวนปริมาณของศูนย์ที่ใช้1อื่น (หรือถ้ารายการวิ่งออกไปจากองค์ประกอบ) 0ใช้ สรุปเหล่านั้น1และ0s

แก้ไข: @Damien: บันทึก 3 ไบต์โดยชี้ไปที่ตัวพิมพ์เล็กสำหรับการเรียกซ้ำ (ซึ่งสามารถพบได้ใน@xnors คำตอบ )


s # l @ (c: d) | s> = c = (sc) # l + s # d; s # _ = 0 ^ s
ดาเมียน

และอะไรจะเป็นผลลัพธ์ของ 1209 [1,5,10,33,48] และ 6000 [1,5,10,33] ดังนั้นฉันสามารถสอบเทียบรหัสของฉันได้
RosLuP

@RosLuP: ->1209 # [1,5,10,33,48] 1314050
nimi

@nimi ok สำหรับ 1314050 ฉันมีผลลัพธ์เดียวกันที่นี่ ... ขอบคุณ ...
RosLuP

@RosLuP: ... 537min ภายหลัง: ->6000 # [1,5,10,33] 22086484
nimi

15

Mathematica, 35 22 ไบต์

ขอบคุณไมล์สำหรับการแนะนำFrobeniusSolveและการบันทึก 13 ไบต์

Length@*FrobeniusSolve

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

a1x1 + a2x2 + ... + anxn = b

สำหรับจำนวนเต็มที่ไม่เป็นลบและมอบโซลูชันทั้งหมดให้เราxi


@RosLuP คุณจะต้องเข้าถึง Mathematica เพื่อใช้งานสิ่งนี้ นอกจากนี้ยังเป็นฟังก์ชั่นที่ไม่ระบุตัวตนดังนั้นจึงสามารถเรียกมันได้ซึ่งจะแค็ปซูลไว้ในวงเล็บหรือเก็บไว้ในตัวแปร ตัวอย่างเช่น(Length@*FrobeniusSolve)[{1, 7, 9}, 18]
ไมล์

และอะไรจะเป็นผลลัพธ์ของ 1209 [1,5,10,33,48] และ 6000 [1,5,10,33] ดังนั้นฉันสามารถสอบเทียบรหัสของฉันได้
RosLuP

@RosLuP 1314050 และ 22086484 ตามลำดับ
Martin Ender

ตกลงที่นี่ผลเหมือนกันขอบคุณ ...
RosLuP

16 คะแนนสำหรับสิ่งนี้เป็นสิ่งที่ถูกต้องเฉพาะในกรณีที่โปรแกรมเมอร์ที่เขียน Length @ * FrobeniusSolve คือคุณ ...
RosLuP

12

Pyth, 8 ไบต์

/sM{yS*E

แรงเดรัจฉานดิบหน่วยความจำเข้มข้นเกินไปสำหรับการทดสอบจริง นี่คือ O (2 mn ) โดยที่nคือจำนวนเหรียญและmคือผลรวมเป้าหมาย target\n[c,o,i,n,s]จะเข้าเป็น

/sM{yS*EQQ      (implicit Q's)
      *EQ       multiply coin list by target
     S          sort
    y           powerset (all subsequences)
   {            remove duplicates
 sM             sum all results
/        Q      count correct sums

9

Haskell, 37 ไบต์

s%(h:t)=sum$map(%t)[s,s-h..0]
s%_=0^s

การใช้เหรียญทวีคูณของเหรียญแรกhลดจำนวนผลรวมที่sต้องการเป็นค่าที่ไม่เป็นลบในการดำเนินการลดลง[s,s-h..0]ซึ่งจะต้องทำกับเหรียญที่เหลืออยู่ เมื่อไม่มีเหรียญที่เหลือตรวจสอบว่าผลรวมเป็นศูนย์ arithmetically 0^sเป็น


มันน่าทึ่งที่คุณตีจำนวนไบต์เดียวกันกับ @nimi โดยใช้วิธีการอื่น
Kritzefitz

9

JavaScript (ES6), 51 48 ไบต์

f=(n,a,[c,...b]=a)=>n?n>0&&c?f(n-c,a)+f(n,b):0:1

รับเหรียญในลำดับใดก็ได้ ลองทั้งการใช้และไม่ใช้เหรียญแรกเพื่อคำนวณจำนวนชุดค่าผสมซ้ำด้วยวิธีใดวิธีหนึ่ง n==0หมายถึงการรวมกันที่ตรงกันn<0หมายความว่าเหรียญเกินปริมาณในขณะที่c==undefinedหมายความว่าไม่มีเหรียญเหลืออยู่ โปรดทราบว่าฟังก์ชั่นช้ามากและถ้าคุณมีเหรียญเพนนีดังนั้นฟังก์ชั่นต่อไปนี้จะเร็วขึ้น (ไม่ผ่านเหรียญเพนนีในแถวของเหรียญ):

f=(n,a,[c,...b]=a)=>c?(c<=n&&f(n-c,a))+f(n,b):1

... dangit ความคิดที่ดีจริง
ETHproductions

และอะไรจะเป็นผลลัพธ์ของ 1209 [1,5,10,33,48] และ 6000 [1,5,10,33] ดังนั้นฉันสามารถสอบเทียบรหัสของฉันได้
RosLuP

@RosLuP ในที่สุดรหัสที่กำหนดจะส่งกลับ 1314050 สำหรับตัวอย่างแรกของคุณ ล่ามของฉันไม่สามารถจัดการการสอบถามซ้ำที่จำเป็นในการประเมินตัวอย่างที่สอง
Neil

@RosLuP ฉันแก้ไขฟังก์ชั่นเพื่อรับเหรียญเพนนีเพิ่มเติมที่มีอยู่แล้วและส่งคืน 22086484 สำหรับ 6000 [5,10,33]
Neil

@Neil ตกลง 22086484 สำหรับ 6000 [1,5,10,33] ... แทนที่จะเป็น 11239 ที่นี่สำหรับ 6000 [5,10,33] (อาร์เรย์ที่คุณเขียน)
RosLuP

7

Perl, 45 ไบต์

จำนวนไบต์ประกอบด้วยรหัสและ-pแฟล็ก 44 ไบต์

s%\S+%(1{$&})*%g,(1x<>)=~/^$_$(?{$\++})^/x}{

รับค่าเหรียญในบรรทัดแรกและจำนวนเป้าหมายในบรรทัดที่สอง:

$ perl -pE 's%\S+%(1{$&})*%g,(1x<>)=~/^$_$(?{$\++})^/x}{' <<< "1 5 10 25
26"
13

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

-p                        # Set $_ to the value of the input, 
                          # and adds a print at the end of the code.
s%\S+%(1{$&})*%g,         # Converts each number n to (1{$&})* (to prepare the regex)
                          # This pattern does half the job.
(1x<>)                    # Converts the target to unary representation.
  =~                      # Match against.. (regex)
    /^ $_ $               # $_ contains the pattern we prepared with the first line.
     (?{$\++})            # Count the number of successful matches
     ^                    # Forces a fail in the regex since the begining can't be matched here.
    /x                    # Ignore white-spaces in the regex 
                          # (needed since the available coins are space-separated)
 }{                       # End the code block to avoid the input being printed (because of -p flag) 
                          # The print will still be executed, but $_ will be empty, 
                          # and only $\ will be printed (this variable is added after every print)

6

เยลลี่ , 10 9 ไบต์

œċЀS€€Fċ

ลองออนไลน์!

อย่างไร?

œċЀS€€Fċ - Main link: coins, target
  Ѐ      - map over right argument, or for each n in [1,2,...,target]
œċ        - combinations with replacement, possible choices of each of n coins
    S€€   - sum for each for each (values of those selections)
       F  - flatten into one list
        ċ - count occurrences of right argument

2
+1 สำหรับการใช้สัญลักษณ์ยูโรจำนวนมากในคำถามที่เกี่ยวข้องกับเงิน
steenbergh

6

JavaScript (ES6), 59 ไบต์

f=(n,c)=>n?c.reduce((x,y,i)=>y>n?x:x+f(n-y,c.slice(i)),0):1

f(26,[100,25,10,5,1])เหรียญที่มีการป้อนข้อมูลจากสูงสุดไปต่ำสุดเช่น หากคุณมีเงินให้ลบออกและใช้รุ่นที่เร็วกว่านี้แทน:

f=(n,c)=>n?c.reduce((x,y,i)=>y>n?x:x+f(n-y,c.slice(i)),1):1

วิธีนี้ใช้สูตรแบบเรียกซ้ำเช่นเดียวกับ @ nimi ฉันเคยเขียนเรื่องนี้เมื่อไม่กี่วันที่ผ่านมาเมื่อความท้าทายยังอยู่ในกล่องทราย มันดูเหมือนว่านี้:

f=(n,c=[100,25,10,5])=>n?c.reduce((x,y,i)=>y>n?x:x+f(n-y,c.slice(i)),1):1

ความแตกต่างเพียงอย่างเดียวคือค่าเริ่มต้นของc(มันมีค่าที่ตั้งไว้ในการท้าทายเดิม) และการเปลี่ยนแปลง0ใน.reduceฟังก์ชั่นเป็น1(นี่คือสองไบต์ที่สั้นกว่าและเร็วกว่าสองพันล้านครั้งc=[100,25,10,5,1])


ต่อไปนี้เป็นเวอร์ชั่นที่ปรับเปลี่ยนแล้วซึ่งส่งออกชุดค่าผสมทั้งหมดมากกว่าจำนวนชุดค่าผสม:

f=(n,c)=>n?c.reduce((x,y,i)=>y>n?x:[...x,...f(n-y,c.slice(i)).map(c=>[...c,y])],[]):[[]]

และอะไรจะเป็นผลลัพธ์ของ 1209 [1,5,10,33,48] และ 6000 [1,5,10,33] ดังนั้นฉันสามารถสอบเทียบรหัสของฉันได้
RosLuP

@RosLuP ฉันได้รับ 1314050 (หลังจาก 5 นาที) และสแต็คล้น (หลังจากหนึ่งชั่วโมง) ตามลำดับ ด้วยรุ่นที่เร็วกว่าที่ฉันเพิ่งเพิ่มเข้าไปฉันจะได้รับ 1314050 และ 22086484 ภายในไม่กี่วินาที
ETHproductions

ด้วยคอมพิวเตอร์ Pentium 2.8Gh ของฉัน 6 วินาทีสำหรับผลลัพธ์แรกเป็นเวลา 5 นาทีที่สองหรือหรือ -
RosLuP

5

PHP, 327 ไบต์

function c($f,$z=0){global$p,$d;if($z){foreach($p as$m){for($j=0;$j<=$f/$d[$z];){$n=$m;$n[$d[$z]]=$j++;$p[]=$n;}}}else for($p=[],$j=0;$j<=$f/$d[$z];$j++)$p[]=[$d[$z]=>$j];if($d[++$z])c($f,$z);}$d=$_GET[a];c($e=$_GET[b]);foreach($p as$u){$s=0;foreach($u as$k=>$v)$s+=$v*$k;if($s==$e&count($u)==count($d))$t[]=$u;}echo count($t);

ลองมัน


5

ความจริง63 62 ไบต์

บันทึก 1 ไบต์โดย @JonathanAllan

f(n,l)==coefficient(series(reduce(*,[1/(1-x^i)for i in l])),n)

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

ครั้งแรกที่มีการเรียกใช้ฟังก์ชั่นนี้จะเป็นการเตือนที่น่ากลัว แต่ก็ยังให้ผลลัพธ์ที่ถูกต้อง หลังจากนั้นทุกอย่างก็โอเคตราบเท่าที่รายการไม่ว่างเปล่า


1
ฉันไม่รู้จัก Axiom - เป็นไปได้ไหมที่จะลบพื้นที่ก่อนfor?
Jonathan Allan

1
@JanathanAllan ใช่มันเป็น! สัญชาตญาณการเล่นกอล์ฟที่ดีขอบคุณ!
Christian Sievers

5

R, 81 76 63 ไบต์

ขอบคุณ @rturnbull สำหรับการเล่นกอล์ฟที่ห่างไกล 13 ไบต์!

function(u,v)sum(t(t(expand.grid(lapply(u/v,seq,f=0))))%*%v==u)

ตัวอย่าง (โปรดทราบว่าc(...)เป็นวิธีที่คุณส่งผ่านเวกเตอร์ของค่าไปยัง R):

f(12,c(1,5,10))
[1] 4

คำอธิบาย:

uคือค่าที่ต้องการvคือเวกเตอร์ของค่าเหรียญ

expand.grid(lapply(u/v,seq,from=0))

สร้าง data frame ที่มีความเป็นไปได้รวมกัน 0 ถึง k coins (k ขึ้นอยู่กับหน่วยเงิน) โดยที่ k คือค่าต่ำสุดที่ k คูณค่าของเหรียญนั้นอย่างน้อย u (ค่าที่จะทำให้สำเร็จ)

โดยปกติเราจะใช้as.matrixเปลี่ยนเป็นเมทริกซ์ แต่นั่นคือตัวละครมากมาย แต่เราใช้ทรานสโพสของ transpose (!) ซึ่งทำการรวมกันโดยอัตโนมัติ แต่ใช้อักขระน้อยลง

%*% vจากนั้นคำนวณค่าเงินของแต่ละแถว uขั้นตอนสุดท้ายคือการนับจำนวนของค่าเหล่านั้นจะเท่ากับค่าที่ต้องการ

โปรดทราบว่าความซับซ้อนของการคำนวณและความต้องการหน่วยความจำของสิ่งนี้น่ากลัวมาก


1
ใช้งานได้ดีexpand.grid! และฉันรักt(t())เคล็ดลับ เนื่องจากฟังก์ชั่นของคุณเกี่ยวข้องกับรหัสบรรทัดเดียวคุณจึงสามารถลบเครื่องหมายปีกกาแบบโค้งได้ซึ่งจะช่วยให้คุณประหยัดได้ 2 ไบต์ นอกจากนี้คุณสามารถสลับไปdo.call(expand.grid,lapply(u/v,seq,from=0))มาได้เพียงแค่expand.grid(lapply(u/v,seq,f=0))ประหยัด 11 ไบต์
rturnbull

ขอบคุณสำหรับสิ่งเหล่านั้น! ฉันไม่เคยรู้เลยว่าexpand.gridจะใช้รายการเป็นอินพุต มันเป็นความอัปยศที่":"ไม่สามารถทำงานได้ดีกับผู้ที่ไม่ใช่จำนวนเต็มมิฉะนั้นlapply(u/v,":",0)จะช่วยให้ประหยัดได้มากขึ้น
JDL

do.call(x,y)เหมือนกันx(y)ดังนั้นจึงไม่เกี่ยวกับประเภทของอินพุตที่ยอมรับ หากคุณต้องการใช้:ฉันคิดว่าคุณสามารถใช้lapply(u%/%v,`:`,0)แต่นับเป็นจำนวนไบต์เดียวกัน
rturnbull

1
" do.call(x,y)เหมือนกับx(y)" --- เฉพาะในกรณีที่yไม่ใช่รายการซึ่งเป็นในกรณีนี้ เห็นด้วยกับประเด็นที่สองของคุณ
JDL

3

J, 27 ไบต์

1#.[=](+/ .*~]#:,@i.)1+<.@%

การใช้

   f =: 1#.[=](+/ .*~]#:,@i.)1+<.@%
   12 f 1 5 10
4
   26 f 1 5 10 25
13
   19 f 2 7 12
2
   13 f 2 8 25
0

คำอธิบาย

1#.[=](+/ .*~]#:,@i.)1+<.@%  Input: target T (LHS), denominations D (RHS)
                          %  Divide T by each in D
                       <.@   Floor each
                             These are the maximum number of each denomination
                     1+      Add 1 to each, call these B
                ,@i.         Forms the range 0 the the product of B
             ]               Get B
              #:             Convert each in the range to mixed radix B
     ]                       Get D
       +/ .*~                Dot product between D and each mixed radix number
                             These are all combinations of denominations up to T
   [                         Get T
    =                        Test if each sum is equal to T
1#.                          Convert as base 1 digits to decimal (takes the sum)
                             This is the number of times each sum was true

J นั้นยอดเยี่ยมมาก แต่ก็บ้าด้วยเช่นกัน
CommaToast

2

TSQL, 105 ไบต์

สิ่งนี้สามารถจัดการได้มากถึงหนึ่งดอลลาร์ด้วยเหรียญ 4 ประเภทเหล่านี้ รุ่นที่ไม่ได้รับการอวดสามารถจัดการได้ถึงประมาณ 4 ดอลลาร์ แต่ช้ามาก - ในกล่องของฉันใช้เวลา 27 วินาที ผลลัพธ์คือ 10045 รวมกัน btw

แข็งแรงเล่นกอล์ฟ:

DECLARE @ INT = 100
DECLARE @t table(z int)
INSERT @t values(1),(5),(10),(25)
;WITH c as(SELECT 0l,0s UNION ALL SELECT z,s+z FROM c,@t WHERE l<=z and s<@)SELECT SUM(1)FROM c WHERE s=@

Ungolfed:

-- input variables
DECLARE @ INT = 100
DECLARE @t table(z int)
INSERT @t values(1),(5),(10),(25)

-- query
;WITH c as
(
  SELECT 0l,0s
  UNION ALL
  SELECT z,s+z
  FROM c,@t
  WHERE l<=z and s<@
)
SELECT SUM(1)
FROM c
WHERE s=@
-- to allow more than 100 recursions(amounts higher than 1 dollar in this example)
OPTION(MAXRECURSION 0)

ซอ


2

tinylisp repl, 66 ไบต์

(d C(q((Q V)(i Q(i(l Q 0)0(i V(s(C(s Q(h V))V)(s 0(C Q(t V))))0))1

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

Ungolfed (กุญแจสู่บิวอิน: d= define, q= quote, i= if, l= less-than, s= ลบ, h= head, t= tail):

(d combos
 (q
  ((amount coin-values)
   (i amount
    (i (l amount 0)
     0
     (i coin-values
      (s
       (combos
        (s amount (h coin-values))
        coin-values)
       (s
        0
        (combos
         amount
         (t coin-values))))
      0))
    1))))

ตัวอย่างการใช้งาน:

tl> (d C(q((Q V)(i Q(i(l Q 0)0(i V(s(C(s Q(h V))V)(s 0(C Q(t V))))0))1
C
tl> (C 12 (q (1 5 10)))
4
tl> (C 26 (q (1 5 10 25)))
13
tl> (C 19 (q (2 7 12)))
2
tl> (C 13 (q (2 8 25)))
0
tl> (C 400 (q (1 5 10 25)))
Error: recursion depth exceeded. How could you forget to use tail calls?!

1

PHP, 130 ไบต์

function r($n,$a){if($c=$a[0])for(;0<$n;$n-=$c)$o+=r($n,array_slice($a,1));return$o?:$n==0;}echo r($argv[1],array_slice($argv,2));

ฟังก์ชั่นเรียกซ้ำ 99 ไบต์ (และ 31 ไบต์ของการเรียกมัน) ที่ซ้ำ ๆ จะลบมูลค่าของเหรียญปัจจุบันจากเป้าหมายและเรียกตัวเองด้วยค่าใหม่และเหรียญอื่น ๆ นับจำนวนครั้งที่เป้าหมายมาถึง 0 อย่างแน่นอน ทำงานเหมือน:

 php -r "function r($n,$a){if($c=$a[0])for(;0<$n;$n-=$c)$o+=r($n,array_slice($a,1));return$o?:$n==0;}echo r($argv[1],array_slice($argv,2));" 12 1 5 10

หากเรียกด้วยเหรียญมากกว่า 97 ชนิดที่แตกต่างกันมันจะตายแบบเรียกซ้ำโดยไม่คืนสิ่งใดเลย แต่เนื่องจากมันเป็นเหรียญประเภทต่าง ๆ ที่ไกลกว่านั้นเราต้องให้การสนับสนุนเป็นอย่างดี
user59178

1

แร็กเก็ต 275 ไบต์

(set! l(flatten(for/list((i l))(for/list((j(floor(/ s i))))i))))(define oll'())(for((i(range 1(add1(floor(/ s(apply min l)))))))
(define ol(combinations l i))(for((j ol))(set! j(sort j >))(when(and(= s(apply + j))(not(ormap(λ(x)(equal? x j))oll)))(set! oll(cons j oll)))))oll

Ungolfed:

(define(f s l)
  (set! l              ; have list contain all possible coins that can be used
        (flatten
         (for/list ((i l))
           (for/list ((j              
                       (floor
                        (/ s i))))
             i))))
  (define oll '())                    ; final list of all solutions initialized
  (for ((i (range 1  
                  (add1
                   (floor             ; for different sizes of coin-set
                    (/ s
                       (apply min l)))))))
    (define ol (combinations l i))          ; get a list of all combinations
    (for ((j ol))                           ; test each combination
      (set! j (sort j >))
      (when (and
             (= s (apply + j))              ; sum is correct
             (not(ormap                     ; solution is not already in list
                  (lambda(x)
                    (equal? x j))
                  oll)))
        (set! oll (cons j oll))             ; add found solution to final list
        )))
  (reverse oll))

การทดสอบ:

(f 4 '[1 2])
(println "-------------")
(f 12 '[1 5 10])
(println "-------------")
(f 19 '[2 7 12])
(println "-------------")
(f 8 '(1 2 3))

เอาท์พุท:

'((2 2) (2 1 1) (1 1 1 1))
"-------------"
'((10 1 1) (5 5 1 1) (5 1 1 1 1 1 1 1) (1 1 1 1 1 1 1 1 1 1 1 1))
"-------------"
'((12 7) (7 2 2 2 2 2 2))
"-------------"
'((3 3 2) (2 2 2 2) (3 2 2 1) (3 3 1 1) (2 2 2 1 1) (3 2 1 1 1) (2 2 1 1 1 1) (3 1 1 1 1 1) (2 1 1 1 1 1 1) (1 1 1 1 1 1 1 1))

วิธีการแก้ปัญหาแบบเรียกซ้ำมีข้อผิดพลาด:

(define (f s l)                      ; s is sum needed; l is list of coin-types
  (set! l (sort l >))
  (define oll '())                   ; list of all solution lists
  (let loop ((l l)   
             (ol '()))               ; a solution list initialized
    (when (not (null? l))
        (set! ol (cons (first l) ol)))
    (define ols (apply + ol))        ; current sum in solution list
    (cond
      [(null? l) (remove-duplicates oll)]
      [(= ols s) (set! oll (cons ol oll))
                 (loop (rest l) '()) 
                 ]
      [(> ols s) (loop (rest l) (rest ol))
                 (loop (rest l) '())   
                 ]
      [(< ols s) (loop l ol) 
                 (loop (rest l) ol)
                 ])))

ทำงานไม่ถูกต้องสำหรับ:

(f 8 '[1 2 3])

เอาท์พุท:

'((1 1 1 2 3) (1 2 2 3) (1 1 1 1 1 1 1 1) (2 3 3) (1 1 1 1 1 1 2) (1 1 1 1 2 2) (1 1 2 2 2) (2 2 2 2))

(1 1 3 3) เป็นไปได้ แต่ไม่ได้มาในรายการโซลูชัน


ฉันไม่คุ้นเคยกับแร็กเก็ต แต่ฉันได้เขียนวิธีแก้ปัญหาใน Clojure สำหรับปัญหาที่คล้ายกันนี้เมื่อไม่กี่ปีที่ผ่านมาที่ใช้reduce
ไมล์

'ลด' ไม่ได้เป็นส่วนหนึ่งของภาษาแร็กเก็ตฐานแม้ว่าจะสามารถใช้งาน 'fold' ได้ ฉันได้เพิ่มโซลูชันที่แก้ไขด้านบนเนื่องจากโซลูชันก่อนหน้ามีข้อผิดพลาด
rnso

ดูเหมือนว่าผู้ที่ชื่นชอบ Lisp จะมารวมตัวกัน ... และสร้างแร็กเก็ต
Joe

1
ผู้ที่ชื่นชอบ Lisp บางคนแรกสร้างScheme( groups.csail.mit.edu/mac/projects/scheme ) ก่อนซึ่งในที่สุดก็นำไปสู่การเป่าเต็มรูปแบบRacket( racket-lang.org , stackoverflow.com/questions/3345397/ …)!
rnso

1

เยลลี่ 15 ไบต์

s+\Fṁḷ
2*BW;ç/Ṫ

ลองออนไลน์! หรือตรวจสอบกรณีทดสอบทั้งหมด

นี่เป็นแบบฝึกหัดเพิ่มเติมในการเขียนเวอร์ชันที่มีประสิทธิภาพใน Jelly โดยไม่ต้องใช้ builtins สิ่งนี้ขึ้นอยู่กับวิธีการเขียนโปรแกรมแบบไดนามิกทั่วไปที่ใช้ในการคำนวณจำนวนวิธีในการเปลี่ยนแปลง

คำอธิบาย

s+\Fṁḷ  Helper link. Input: solutions S, coin C
s       Slice the solutions into non-overlapping sublists of length C
 +\     Cumulative sum
   F    Flatten
     ḷ  Left, get S
    ṁ   Mold the sums to the shape of S

2*BW;ç/Ṫ  Main link. Input: target T, denominations D
2*        Compute 2^T
  B       Convert to binary, creates a list with 1 followed by T-1 0's
          These are the number of solutions for each value from 0 to T
          starting with no coins used
   W      Wrap it inside another array
    ;     Concatenate with D
     ç/   Reduce using the helper link
       Ṫ  Tail, return the last value which is the solution

1

ที่จริงแล้ว 15 ไบต์

ยินดีต้อนรับคำแนะนำการเล่นกอล์ฟ ลองออนไลน์!

╗;R`╜∙♂S╔♂Σi`Mc

Ungolfing

         Implicit input n, then the list of coins a.
╗        Save a to register 0.
;R       Duplicate n and create a range [1..n] from that duplicate.
`...`M   Map the following function over that range. Variable i.
  ╜        Push a from register 0.
  ∙        Push the i-th Cartesian power of a.
  ♂S       Sort each member of car_pow.
  ╔        Uniquify car_pow so we don't count too any duplicate coin arrangements.
  ♂Σ       Take the sum of each coin arrangement.
  i        Flatten the list.
c        Using the result of the map and the remaining n, push map.count(n).
         Implicit return.

0

Python ขนาด 120 ไบต์

from itertools import*
lambda t,L:[sum(map(lambda x,y:x*y,C,L))-t for C in product(range(t+1),repeat=len(L))].count(0)

Bruteforces ผ่านการรวมกันของเหรียญทั้งหมดจนถึงค่าเป้าหมาย (แม้ว่าจะน้อยที่สุดไม่ใช่ 1)

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