ปัญหาเหรียญ


20

พื้นหลัง

สกุลเงินอย่างเป็นทางการของประเทศจินตนาการของ Golfenistan คือฟูและมีเหรียญสามชนิดหมุนเวียน: 3 foos, 7 foos และ 8 foos จะเห็นได้ว่าเป็นไปไม่ได้ที่จะจ่ายเงินจำนวนหนึ่งเช่น 4 foos โดยใช้เหรียญเหล่านี้ อย่างไรก็ตามสามารถสร้างจำนวนมากพอทั้งหมด งานของคุณคือการหาจำนวนเงินที่ใหญ่ที่สุดที่ไม่สามารถเกิดขึ้นกับเหรียญ (5 Foos ในกรณีนี้) ซึ่งเป็นที่รู้จักกันเป็นปัญหาเหรียญ

อินพุต

ข้อมูลที่คุณป้อนเป็นรายการจำนวนเต็มบวกซึ่งแทนค่าของเหรียญในการหมุนเวียน รับประกันสองสิ่งเกี่ยวกับมัน:L = [n1, n2, ..., nk]

  • GCD ขององค์ประกอบของLคือ 1
  • L ไม่มีหมายเลข 1

มันอาจจะไม่เรียงกันและ / หรือมีการซ้ำซ้อน (คิดว่าเหรียญฉบับพิเศษ)

เอาท์พุต

เนื่องจาก GCD ของLคือ 1 ทุกจำนวนเต็มมากพอmสามารถแสดงเป็นชุดค่าผสมเชิงเส้นที่ไม่เป็นลบขององค์ประกอบ ในคำอื่น ๆ เรามี

 m = a1*n1 + a2*n2 + ... + ak*nk 

สำหรับจำนวนเต็มบาง ผลลัพธ์ของคุณเป็นจำนวนเต็มที่มากที่สุดที่ไม่สามารถแสดงในรูปแบบนี้ โดยนัยแล้วเป็นที่ทราบกันว่าเอาต์พุตนั้นน้อยกว่าเสมอหากและเป็นองค์ประกอบสูงสุดและน้อยที่สุดของ( อ้างอิง )ai ≥ 0(n1 - 1)*(nk - 1)n1nkL

กฎระเบียบ

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

หลังจากที่ผมโพสต์ความท้าทายนี้ @vihan ใช้ชี้ให้เห็นว่ากองมากเกินมีแน่นอนซ้ำ จากการสนทนาใน Metaนี้ความท้าทายนี้จะไม่ถูกลบเหมือนการทำซ้ำ อย่างไรก็ตามฉันถามว่าคำตอบทั้งหมดตามเวอร์ชั่น SO ควรอ้างอิงต้นฉบับได้รับสถานะ Community Wiki และจะถูกลบหากผู้เขียนต้นฉบับต้องการโพสต์คำตอบของพวกเขาที่นี่

กรณีทดสอบ

[3, 7, 8] -> 5
[25, 10, 16] -> 79
[11, 12, 13, 14, 13, 14] -> 43
[101, 10] -> 899
[101, 10, 899] -> 889
[101, 10, 11] -> 89
[30, 105, 70, 42] -> 383
[2, 51, 6] -> 49

5
FrobeniusNumberใน Mathematica
alephalpha

3
มีขอบเขตบนที่ดีกว่าที่พบในบทความนี้ที่สร้าง(p - 1)(q - 1)เป็นขอบเขตบนคือที่ไหนpและqเป็นองค์ประกอบที่เล็กที่สุดและใหญ่ที่สุดของเซต
orlp

2
มีการ จำกัด เวลาใช้งานหรือการใช้หน่วยความจำหรือไม่?
Dennis


1
ฉันมีวิธีการแก้ปัญหา 13 ไบต์ Pyth ที่สามารถทำได้[2,3]ในเวลาที่เหมาะสมและไม่มีอะไรอื่น [2,5]จะสร้างรายการ Python ประมาณหนึ่งล้านรายการในหน่วยความจำ
isaacg

คำตอบ:


4

Pyth, 23 ไบต์

ef!fqTs.b*NYQY^UTlQS*FQ

มันช้ามากเพราะมันตรวจสอบค่าทั้งหมดขึ้นกับผลิตภัณฑ์ของเหรียญทั้งหมด นี่คือรุ่นที่เกือบจะเหมือนกัน แต่ 1) ลดชุดเหรียญให้เหลือน้อยกว่าที่ไม่สามารถหารได้และ 2) จะตรวจสอบค่าสูงสุด(max(coins) - 1) * (min(coins) - 1)(47 ไบต์):

=Qu?.A<LiHdG+GHGQYef!fqTs.b*NYQY^UTlQS*thSQteSQ

คำอธิบาย

                   S            range 1 to
                    *FQ         product of input
 f                             filter by
               UT                range 0 to T 
              ^  lQ              cartesian power by number of coins
   f                            filter by
      s.b*NYQY                   sum of coin values * amounts
    qT                           equals desired number T
  !                             nothing matching that filter
e                             take last (highest) element

8

Perl, 60 54 51 ไบต์

50 ไบต์รหัส + 1 ไบต์บรรทัดคำสั่ง

$.*=$_,$r.=1x$_."|"}{$_=$.while(1x$.--)=~/^($r)+$/

จะเล่นกอล์ฟต่อไปและโพสต์คำอธิบายในภายหลัง วิธีการพื้นฐานคือการให้เอ็นจิน regex ทำงานหนักกับการจับคู่สตริง ตัวอย่างเช่นมันจะสร้าง regex ที่คล้ายกับ^(.{3})*(.{7})*(.{8})*$และจับคู่กับสตริงที่มีความยาวnซึ่งnสืบทอดมาจากผลิตภัณฑ์ของอินพุตจนกว่ามันจะล้มเหลวในการแข่งขัน

โปรดทราบว่าสิ่งนี้จะช้าลงอย่างทวีคูณเมื่อจำนวนอาร์กิวเมนต์เพิ่มขึ้น

การใช้งาน: อาร์กิวเมนต์จะอ่านจาก STDIN (คั่นบรรทัดใหม่) ตัวอย่างเช่น:

printf "101\n10" | perl -p entry.pl

3

R , 84 78 ไบต์

a1,a2,...

a=scan();max((1:(b<-min(a)*max(a)))[-colSums(combn(outer(a,0:b),sum(!!a)))])

ลองออนไลน์!

aผมoutercolSumsแทนที่จะใช้ (... , 2, ผลรวม) '

รุ่นที่เร็วขึ้น แต่ยาวขึ้น (สองไบต์) จะพิจารณาเฉพาะmax(a):

a=scan();max((1:(min(a)*(b<-max(a))))[-apply(combn(outer(a,0:b,"*"),sum(!!a)),2,sum)])

รุ่นที่สั้นกว่าเล็กน้อย (78 ไบต์) ซึ่งมักใช้เวลานานเกินไปหรือมีเนื้อที่มากเกินกว่าที่จะเรียกใช้ได้ลองออนไลน์ได้

a=scan();max((1:(b<-prod(a)))[-apply(combn(outer(a,0:b,"*"),sum(!!a)),2,sum)])

1

Python2, 188 187 ไบต์

def g(L):
 M=max(L);i=r=0;s=[0]*M;l=[1]+s[1:]
 while 1:
    if any(all((l+l)[o:o+min(L)])for o in range(M)):return~-s[r]*M+r
    if any(l[(i-a)%M]for a in L):l[i]=1
    else:r=i
    s[i]+=1;i=(i+1)%M

การเยื้องครั้งที่สองจะแสดงผลเป็นช่องว่าง 4 ช่องบน SO ซึ่งควรเป็นแท็บ

จริง 'รวดเร็ว' แก้ปัญหาไม่ Bruteforce, ใช้ 'วิลฟ์ของวิธี' ตามที่อธิบายไว้ที่นี่


1

Javascript ES6, 120 130 126 128 127 125 ตัวอักษร

f=a=>`${r=[1|a.sort((a,b)=>a-b)]}`.repeat(a[0]*a[a.length-1]).replace(/./g,(x,q)=>r[q]|a.map(x=>r[q+x]|=r[q])).lastIndexOf(0)

ทางเลือกรุ่น 126 ตัวอักษร:

f=a=>{r=[1];a.sort((a,b)=>a-b);for(q=0;q<a[0]*a[a.length-1];++q)r[q]?a.map(x=>r[q+x]=1):r[q]=0;return r.join``.lastIndexOf(0)}

ทดสอบ:

"[3, 7, 8] -> 5\n\
[25, 10, 16] -> 79\n\
[11, 12, 13, 14, 13, 14] -> 43\n\
[101, 10] -> 899\n\
[101, 10, 899] -> 889\n\
[101, 10, 11] -> 89\n\
[30, 105, 70, 42] -> 383\n\
[2, 51, 6] -> 49".replace(/(\[.*?\]) -> (\d+)/g, function (m, t, r) {
  return f(JSON.parse(t)) == r
})

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