এন-অঙ্কের নির্ভুলতার সাথে আনুমানিক ভাসমান পয়েন্ট সংখ্যা


9

আমাদের r0 এবং 1 এর মধ্যে একটি ভাসমান পয়েন্ট সংখ্যা এবং একটি পূর্ণসংখ্যা রয়েছে p

ক্ষুদ্রতম ডিনোমিনেটরের সাথে পূর্ণসংখ্যার ভগ্নাংশটি সন্ধান করুন, যা rকমপক্ষে- pডিজিট নির্ভুলতার সাথে প্রায় হয় ।

  • ইনপুট: r(একটি ভাসমান পয়েন্ট সংখ্যা) এবং p(পূর্ণসংখ্যা)।
  • আউটপুট: aএবং bপূর্ণসংখ্যা, যেখানে
    • a/b(ভাসমান হিসাবে) অঙ্কগুলি rঅবধি প্রায়p
    • b সম্ভাব্যতম ধনাত্মক পূর্ণসংখ্যার পূর্ণসংখ্যা।

উদাহরণ স্বরূপ:

  • যদি r=0.14159265358979এবং p=9,
  • তারপর ফল a=4687এবং b=33102,
  • কারণ 4687/33102=0.1415926530119026

যে কোনও সমাধানে তাত্ক্ষণিকভাবে সুনির্দিষ্ট-নির্ভুলতার ধরণের কাজ করতে হবে তবে বাস্তবায়নের স্থির-নির্ভুলতার কারণে সীমাবদ্ধতাগুলি গুরুত্বপূর্ণ নয়।

যথার্থতা মানে " 0." এর পরে অঙ্কগুলির সংখ্যা r। সুতরাং, r=0.0123এবং যদি p=3, তারপর a/bদিয়ে শুরু করা উচিত 0.012। যদি pভগ্নাংশের প্রথম অঙ্কগুলি r0 হয় তবে অপরিজ্ঞাত আচরণ গ্রহণযোগ্য।

বিজয়ী মানদণ্ড:

  • অ্যালগোরিদম দ্রুততম অ্যালগরিদম জিতেছে। গতি ও (পি) পরিমাপ করা হয়।
  • যদি একাধিক দ্রুততম অ্যালগরিদম হয় তবে সংক্ষিপ্ততম জেতে।
  • আমার নিজস্ব উত্তর সম্ভাব্য বিজয়ীদের সেট থেকে বাদ দেওয়া হয়েছে।

গণিত অংশটি PS হিসাবে মনে হয় আসলে অনেক সহজ, আমি এই পোস্টটি পড়ার পরামর্শ দিই ।

উত্তর:


7

জাভাস্ক্রিপ্ট, ও (10 পি ) এবং 72 বাইট

r=>p=>{for(a=0,b=1,t=10**p;(a/b*t|0)-(r*t|0);a/b<r?a++:b++);return[a,b]}

লুপটি বেশিরভাগ ও (10 পি ) পুনরাবৃত্তির পরে করা হবে তা প্রমাণ করা তুচ্ছ ।

নীলের ধারণাকে অনেক ধন্যবাদ, 50 টি বাইট সংরক্ষণ করুন।


কেন তুমি নিয়ে তুচ্ছ হয় padEndএবং match? আপনি কি sliceপ্রতিটি প্রতিটি স্ট্রিং সঠিক দৈর্ঘ্যে না রেখে সেগুলি বিয়োগ করতে পারবেন?
নীল

@ নীল দুঃখিত, আমি আপনার কথাটি ধরতে পারি নি। যোগ padEndটেস্টকেস f(0.001,2)এবং জন্য ব্যবহৃত হয় f(0.3,2)
tsh

আমি ভাবছিলাম আপনি কিছুতে সরল করতে পারবেন (r,p)=>{for(a=0,b=1;`${a/b}`.slice(0,p+2)-`${r}`.slice(0,p+2);a/b<r?a++:b++);return[a,b]}(সম্পূর্ণ গল্ফড নয়)।
নিল

@ নিল 120 ​​-> 70 বাইট। :)
tsh

ওহ, এটা আরও ভাল!
নিল

4

হাস্কেল , ও (10 পি ) সবচেয়ে খারাপ ক্ষেত্রে 121 119 বাইট

g(0,1,1,1)
g(a,b,c,d)r p|z<-floor.(*10^p),u<-a+c,v<-b+d=last$g(last$(u,v,c,d):[(a,b,u,v)|r<u/v])r p:[(u,v)|z r==z(u/v)]

এটি অনলাইন চেষ্টা করুন!

লাইকোনি ধন্যবাদ 2 বাইট সংরক্ষণ করা

আমি /math/2432123/how-to-find-the-fration-of-integers-with-t چھوٹے-sodominator-matching-an-i থেকে অ্যালগরিদম ব্যবহার করেছি ।

প্রতিটি পদক্ষেপে, নতুন বিরতি পূর্ববর্তী বিরতির এক অর্ধেক। সুতরাং, বিরতি আকার 2**-n, nবর্তমান পদক্ষেপ যেখানে । কখন 2**-n < 10**-p, আমাদের কাছে সঠিক অনুমানের বিষয়টি নিশ্চিত। তা সত্ত্বেও যদি n > 4*pতারপর 2**-n < 2**-(4*p) == 16**-p < 10**-p। উপসংহারটি হ'ল অ্যালগরিদম O(p)

সম্পাদনা হিসাবে একটি মন্তব্যে orlp দ্বারা নির্দেশিত, উপরের দাবিটি মিথ্যা। সবচেয়ে খারাপ ক্ষেত্রে, r = 1/10**p( r= 1-1/10**pঅনুরূপ), সেখানে থাকবে 10**pধাপ: 1/2, 1/3, 1/4, ...। আরও ভাল সমাধান আছে, তবে এটি ঠিক করার জন্য আমার কাছে এখনই সময় নেই।


আমি জানি কোড গল্ফটি কেবলমাত্র দ্বিতীয় লক্ষ্য, তবে আপনি এটিকে বাদ দিয়ে f=দুটি বাইট সংরক্ষণ করতে পারেন z<-floor.(*10^p),u<-a+c,v<-b+d
লাইকনি

@ লাইকনি আমি দুটি বাইট গণনা করি নি। আমি জানি না কীভাবে f=হাস্কেল কোডে টিআইওতে সরিয়ে ফেলা যায়।
jferard

আপনি -cppসংকলক পতাকা যুক্ত করতে পারেন এবং f=\ শিরোনামে লিখতে পারেন : এটি অনলাইনে চেষ্টা করুন!
লাইকনি

"প্রতিটি পদক্ষেপে, নতুন ব্যবধানটি পূর্ববর্তী বিরতির এক অর্ধেক।" তুমি ইহা কিভাবে জানো? প্রথম পদক্ষেপটি হ'ল 1/2, হ্যাঁ, তবে তারপরের পরবর্তী পদক্ষেপটি উদাহরণস্বরূপ 1/2 এবং 1/1 প্রদান করে 2/3 দেয় যা অন্তরকে অর্ধেক করে দেয় না।
orlp

@orlp আপনি নিখুঁত ঠিক আছেন। আমি অনেক বেশি আশাবাদী ছিলাম এবং জটিলতাটি সবচেয়ে খারাপ ক্ষেত্রে ও (10 ^ পি)। আমার আরও ভাল সমাধান আছে তবে এখনই এটি লেখার সময় নেই।
jferard

0

সি, 473 বাইট (প্রসঙ্গ ছাড়াই), ও (পি), প্রতিযোগী ing

এই সমাধানটি এই দুর্দান্ত পোস্টে বিস্তারিত গণিত অংশটি ব্যবহার করে । আমি কেবল calc()উত্তর আকারে গণনা করেছি ।

#include <stdio.h>
#include <stdlib.h>
#include <math.h>

void calc(float r, int p, int *A, int *B) {
  int a=0, b=1, c=1, d=1, e, f;
  int tmp = r*pow(10, p);
  float ivl = (float)(tmp) / pow(10, p);
  float ivh = (float)(tmp + 1) / pow(10, p);

  for (;;) {
    e = a + c;
    f = b + d;

    if ((ivl <= (float)e/f) && ((float)e/f <= ivh)) {
      *A = e;
      *B = f;
      return;
    }

    if ((float)e/f < ivl) {
      a = e;
      b = f;
      continue;
    } else {
      c = e;
      d = f;
      continue;
    }
  }
}

int main(int argc, char **argv) {
  float r = atof(argv[1]);
  int p = atoi(argv[2]), a, b;
  calc(r, p, &a, &b);
  printf ("a=%i b=%i\n", a, b);
  return 0;
}

এটি কমপক্ষে প্রচলিত মেশিনে, সিপিইউ চক্রের অর্থে সম্ভবত দ্রুততম সমাধানটি সন্নিকটে।
পিটারহ - মনিকা
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.