ডলার বিভাজ্যতা এবং নিখুঁত পরিবর্তন


11

আমার পকেটে 15 ডলার আছে তেমনি, আমি এমন একটি দোকানে আছি যা পরিবর্তন দেয় না। ব্রাউজ করার সময়, আমি একটি আইটেম দেখি যার দাম $ 10 (ট্যাক্স অন্তর্ভুক্ত)। আমি কি কোনও অর্থ না হারিয়ে সেই জিনিসটি কিনতে পারি?

এই ক্ষেত্রে, উত্তর হ্যাঁ। আমার $ 15 কে কীভাবে বিভক্ত করা হবে (এক 10 এবং এক 5, বা তিন 5s বা অন্য কিছু), আমার সর্বদা সঠিক 10 ডলার প্রয়োজন।

দ্বিতীয় উদাহরণ হিসাবে, আমার পকেটে $ 0.16 রয়েছে। আমি অন্য কোন পরিমাণ অর্থের সঠিক মূল্য দিতে সক্ষম হব?

Possible Divisions:
0.01, 0.05, 0.10
0.01, 0.05 x 3
0.01 x 16
Guaranteed Exact Change:
0.01, 0.05, 0.06, 0.10, 0.11, 0.15, 0.16

আমার পকেটে যদি $ 0.27 থাকে?

Possible Divisions:
0.01 x 2, 0.25
0.01 x 2, 0.05, 0.10 x 2
0.01 x 2, 0.05 x 3, 0.10
0.01 x 2, 0.05 x 5
0.01 x 27
Guaranteed Exact Change:
0.01, 0.02, 0.25, 0.26, 0.27

উপরের ক্ষেত্রে, কেবলমাত্র কয়েকটি পরিমাণ অর্থ ছিল যার জন্য আমার সর্বদা নিখুঁত পরিবর্তন হবে।

তোমার কাজ

সংক্ষিপ্ততম প্রোগ্রাম (বা নামকৃত ফাংশন) লিখুন যা ক) একটি পূর্ণসংখ্যক অর্থ এবং খ) ইনপুট হিসাবে সম্ভাব্য সংখ্যার তালিকা করে এবং যে পরিমাণ অর্থের জন্য আমার নিখুঁত পরিবর্তন করতে হবে তার একটি তালিকা বের করে দেয়। ইনপুটটি হয় STDIN বা প্রোগ্রাম বা ফাংশনের পক্ষে যুক্তি হতে পারে। আমি ইনপুট ফর্ম্যাটিংয়ের উপর কঠোর হতে যাচ্ছি না; এটি কীভাবে আপনার ভাষার বিন্যাসগুলি অ্যারে করে তা মিলতে পারে।

সম্ভবত আরও বিস্তারিত ব্যাখ্যা

আমার পকেটে একটি নির্দিষ্ট পরিমাণ অর্থ রয়েছে, যা মুদ্রার সম্ভাব্য বিক্ষোভের সেট থেকে তৈরি। যদি আমার কাছে 8 ডলার থাকে এবং আমি জানি যে সম্ভাব্য সংজ্ঞাগুলি 2 ডলার এবং 3 ডলার, তবে কেবলমাত্র আমার পকেটে থাকা বিলের অনেকগুলি সংমিশ্রণ রয়েছে। এগুলি 2+2+2+2এবং 3+3+2। সঠিক পরিমাণ অর্থ উত্পাদন করতে সক্ষম হতে, আমার পকেটে থাকা কেবলমাত্র বিলগুলি ব্যবহার করে আমাকে সেই পরিমাণটি উত্পাদন করতে সক্ষম হতে হবে। আমার চারটি 2s থাকলে আমি উত্পাদন করতে পারি 2, 4, 6, or 8। আমার যদি দুটি 3s এবং 2 থাকে তবে আমি উত্পন্ন করতে 2, 3, 5, 6, or 8পারি যেহেতু আমার পকেটে এই সংমিশ্রণের মধ্যে কোনটি আসলে আমি জানি না, আমার চূড়ান্ত উত্তরটি হ্রাস পেয়েছে 2, 6, 8। এই মোট মান এবং আমি জানি যে আমি আমার পকেট থেকে উত্পাদন করতে পারি, মোট পরিমাণ এবং সম্ভাব্য সংখ্যার দিক দিয়ে।

হাতে গণনা উদাহরণ I / O

7 [3, 4]
3, 4, 7        //only one possible division into 3 + 4

7 [3, 2]
2, 3, 4, 5, 7  //the only division is 3 + 2 + 2

6 [2, 3, 4]
6     //divisions are 2+2+2, 3+3, 2+4 

16 [1, 5, 10, 25]          //this represents one of the examples above
1, 5, 6, 10, 11, 15, 16

27 [1, 5, 10, 25]          //another example from above
1, 2, 25, 26, 27

1500 [1, 5, 10, 25, 100, 500, 1000, 2000]
500, 1000, 1500

600 [100, 500, 1000, 2000]
100, 500, 600

600 [200, 1, 5, 10, 25, 100, 500, 1000, 2000]
600

এটা খুব অস্পষ্ট।
মোতোকু

@ ফ্রাইআম দ্য এজিগম্যান আমি একটি "সম্ভবত আরও বিস্তারিত ব্যাখ্যা" যুক্ত করেছি। যদি এটি এখনও বিভ্রান্তিকর হয় তবে আমাকে জানান। (আমি একটি প্রান্তের
মামলাটিও

আপনি কিভাবে পাচ্ছেন তা আমি দেখতে পাচ্ছি না 6 [2, 3, 4]2+2+23, এবং 3+32 এবং 4 তৈরি করতে পারবেন না ?
xnor

@xnor আপনি সঠিক, স্থির
PhiNotPi

প্রোগ্রামটি সমস্ত ইনপুটগুলির জন্য উপযুক্ত সময়ে চালানো উচিত? উদাহরণস্বরূপ আমার সংক্ষিপ্ত ধারণাটি প্রারম্ভিক পরিমাণে তাত্পর্যপূর্ণ এবং 2 ^ 1500 অনেক কিছুই।
এলোমেলো

উত্তর:


2

পাইথন 2, 200 197 193 140 বাইট

f=lambda n,D,S={0}:sum([f(n-x,D,S|{x+y for y in S})for x in D],[])if n>0else[S]*-~n
g=lambda*a:(f(*a)and reduce(set.__and__,f(*a))or{0})-{0}

(টিপসের জন্য @ ন্যাবকে ধন্যবাদ)

জিনিস শুরু করার জন্য এখানে একটি দুর্বল গল্ফযুক্ত সমাধান। কল সহ g(16, [1, 5, 10, 25])- আউটপুটটি প্রাসঙ্গিক বর্ণের সাথে সেট।

পদ্ধতিটি সোজা, এবং দুটি ধাপে বিভক্ত:

  • fnডিনোমিনেশনগুলি D(যেমন [1, 5, 10]) সহ পৌঁছানোর সমস্ত উপায় দেখায় এবং প্রতিটিটির জন্য এটি এই সংখ্যার (যেমন set([0, 1, 5, 6, 10, 11, 15, 16])) তৈরি করা যেতে পারে এমন সমস্ত পরিমাণে কাজ করে ।
  • gএর ফলাফলের ছেদগুলি গণনা করে f, তারপরে চূড়ান্ত উত্তরের জন্য 0 সরান।

প্রোগ্রামটি 1-5 এবং 7 জরিমানা কেস সমাধান করে, 6 এ স্ট্যাক ওভারফ্লো হয় এবং 8 এ চিরতরে লাগে।

যদি কোনও সমাধান (যেমন g(7, [2, 4, 6])) না থাকে তবে প্রোগ্রামটি একটি খালি সেট দেয় empty যদি এইরকম মামলার জন্য যদি কোনও ত্রুটি নিক্ষেপ করার অনুমতি দেওয়া হয় তবে এখানে একটি সংক্ষিপ্ত বিবরণ দেওয়া হবে g:

g=lambda*a:reduce(set.__and__,f(*a))-{0}

g=lambda L,c=0:L and g(L[1:],c)|g(L,c+L.pop(0))or{c}কিছুটা খাটো
ন্যাব

-{0}জি-তে সরানো এবং এর [L]*-~nপরিবর্তে ব্যবহার করে আরও কিছু[L][-n:]
নবাব

1

জাভাস্ক্রিপ্ট (ES6) 162 203 207

সম্পাদনা করুন অ্যারে দ ছেদ ফলাফলের সেট পথে পরিবর্তন হয়েছে। কিছুটা দ্রুত, তবে অ্যালগরিদম এখনও দুর্গন্ধযুক্ত।

আরও বিস্তারিত ব্যাখ্যা অনুসরণ করবে।
সংক্ষেপে: সি একটি পুনরাবৃত্ত ফাংশন যা সম্ভাব্য সমস্ত মহকুমার গণনা করে। কে একটি পুনরাবৃত্ত ফাংশন যা পুনরাবৃত্তি ছাড়াই সমস্ত সম্ভাব্য অঙ্কের অঙ্ক করে। কে ফাংশন সহ যে কোনও নতুন ফলাফল সেট পাওয়া আগের সেটগুলির সাথে তুলনা করা হয়, কেবলমাত্র সাধারণ ফলাফল রাখা হয়।

কেন এত ধীর? মোট 1500 এবং একক মান 1 এর লক্ষ্য নির্ধারণ করা, সমস্ত সম্ভাব্য অঙ্কগুলি গণনা করা ভাল ধারণা নয়।

F=(s,d,r,
  c=(s,i,t=[],v,k=(i,s,v)=>{for(;v=t[i++];)k(i,s+v);o[s]=s})=>
  {for(s||(i=k(o=[],0),r=(r||o).filter(v=>o[v]));v=d[i];++i)s<v||c(s-v,i,[...t,v])}
)=>c(s,0)||r

Ungolfed

F=(s,d)=>{
  var r
  var c=(s,i,t=[])=>
  {
    var o=[],v
    var k=(i,s)=> // find all sums for the current list t, set a flag in the o array
    {
      var v
      for(;v=t[i++];)k(i,s+v)
      o[s]=s
    }

    if (s==0) {
      k(0,0)
      if (r)
        r = r.filter(v=>o[v]) // after first loop, intersect with current
      else
        r = o.filter(v=>v) // first loop, keep all results
    } 
    else
      for(;v=d[i];++i)
      { 
        if (s >= v) 
          c(s-v, i, t.concat(v))
      }
  }
  c(s,0) // enumerate all possible set of pieces
  return r
}

টেস্ট সালে ফায়ারফক্স / ফায়ারবাগ কনসোলটি

F(16,[1,5,10,25])

[1, 5, 6, 10, 11, 15, 16]

(সময় ৮৪ ম্যাসি)

F(27, [1, 5, 10, 25]) 

[১, ২, ২৫, ২ 26, ২]]

(সময় 147252 এমসিতে, সুতরাং খুব দ্রুত নয়)


0

ওল্ফ্রাম মেটেমেটিকা, 104 বাইট

Rest@*Intersection@@Map[Total]/@Subsets/@Union[Sort/@IntegerPartitions[#,#,PadLeft[{},Length[#2]#,#2]]]&

অবহেলিত (শেষ থেকে পড়া):

Rest@* // Removing 0
  Intersection@@   // Intersecting all totals
     Map[Total]/@  // Counting total of each subset
        Subsets/@  // Getting all the subsets of each partition
           Union[  // Removing duplicates 
              Sort/@ // Sorting each partition (to remove duplicates next)
                 IntegerPartitions[#,#,PadLeft[{},Length[#2]#,#2]] // Getting all Integer partitions
                ]&
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.