*, /, +, -% অপারেটর ব্যবহার না করে একটি সংখ্যা 3 দিয়ে ভাগ করুন


684

আপনি কিভাবে ব্যবহার না করেই 3 দ্বারা একটি সংখ্যা বিভক্ত করতে চাইবে *, /, +, -, %, অপারেটর?

নম্বরটি স্বাক্ষরিত বা স্বাক্ষরযুক্ত হতে পারে।


13
@AlexandreC। - এই কৌশলগুলি যদিও যোগ (+) ব্যবহার করছে।
হ্যাচেট -

19
এটি ওরাকল ছিল সুতরাং ওরাকলের কোন অংশগুলি আপনাকে ব্যবহারের অনুমতি পেয়েছিল?
হোগান

8
চিহ্নিত নকলটি সদৃশ নয়। মনে রাখবেন যে বেশ কয়েকটি উত্তর এখানে বিট শিফটিং বা সংযোজন ব্যবহার করে না কারণ এই প্রশ্নটি সেই ক্রিয়াকলাপগুলির সমাধান সীমাবদ্ধ করে না।
মাইকেল বুড়

66
... এবং এখানে PL / SQL জন্মগ্রহণ করে।
সেদাত কাপানোগলু

22
এই প্রশ্নটি এসও-র কাছে অফটোপিক। এটি কোডগলফ.স্ট্যাকেক্সচেঞ্জ.কম
ক্রোমস্টার

উত্তর:


548

এটি একটি সাধারণ ফাংশন যা পছন্দসই অপারেশন সম্পাদন করে। তবে এটি +অপারেটরের প্রয়োজন , সুতরাং আপনারা যা করতে বাকি তা হ'ল বিট-অপারেটরগুলির সাথে মান যুক্ত করা:

// replaces the + operator
int add(int x, int y)
{
    while (x) {
        int t = (x & y) << 1;
        y ^= x;
        x = t;
    }
    return y;
}

int divideby3(int num)
{
    int sum = 0;
    while (num > 3) {
        sum = add(num >> 2, sum);
        num = add(num >> 2, num & 3);
    }
    if (num == 3)
        sum = add(sum, 1);
    return sum; 
}

জিম এই কাজগুলির মন্তব্য হিসাবে, কারণ:

  • n = 4 * a + b
  • n / 3 = a + (a + b) / 3
  • সুতরাং sum += a, n = a + bএবং পুনরাবৃত্তি

  • কখন a == 0 (n < 4), sum += floor(n / 3);অর্থাত্ 1,if n == 3, else 0


96
ওরাকল সম্ভবত এটির উত্তর খুঁজছেন। এটি আপনাকে জানায় যে কীভাবে সিপিইউতে +, -, * এবং / অপারেটরগুলি বাস্তবায়িত হয়: সাধারণ বিটওয়াইজ অপারেশন।
ক্রেগ 65535

21
এটি কাজ করে কারণ n = 4a + b, n / 3 = a + (a + b) / 3, সুতরাং যোগফল = = a, n = a + b, এবং পুনরাবৃত্তি হবে। যখন a == 0 (n <4), যোগফল = = তল (n / 3); অর্থাত্, 1 যদি এন == 3, অন্য 0
জিম বাল্টার

7
এখানে একটি কৌশল খুঁজে পেয়েছি যা আমাকে অনুরূপ সমাধান পেয়েছে। দশমিক:: 1 / 3 = 0.333333পুনরাবৃত্তি সংখ্যা ব্যবহার করে এটি গণনা করা সহজ করে a / 3 = a/10*3 + a/100*3 + a/1000*3 + (..)। বাইনারি এটি প্রায় একই 1 / 3 = 0.0101010101 (base 2):, যা বাড়ে a / 3 = a/4 + a/16 + a/64 + (..)। 4 দ্বারা বিভাজন করা যেখানে বিট শিফট আসে। Num == 3 এ শেষ চেকটি দরকার কারণ আমাদের সাথে কাজ করার জন্য কেবল পূর্ণসংখ্যা পেয়েছি।
ইয়োরিক সিজলিং

4
বেস 4 এটা আরও ভাল,: a / 3 = a * 0.111111 (base 4) = a * 4^-1 + a * 4^-2 + a * 4^-3 + (..) = a >> 2 + a >> 4 + a >> 6 + (..)। বেস 4 এছাড়াও কেন কেবল 3 টি বৃত্তাকার শেষ হয় তা ব্যাখ্যা করে, যখন 1 এবং 2 টি বৃত্তাকার হয়ে যেতে পারে।
ইয়োরিক সিজলিং

2
@ while1: এটি বিটওয়াস এবং অপারেশন। এছাড়াও, একটি সুপরিচিত সত্য n == 2^kনিম্নলিখিতগুলির জন্য সত্য: x % n == x & (n-1)সুতরাং এখানে অনুমোদিত নয় যখন num & 3সম্পাদন করতে ব্যবহৃত হয় । num % 4%
অ্যাপলভিন

436

বোকা পরিস্থিতি একটি বোকা সমাধানের জন্য কল করে:

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

int main()
{
    FILE * fp=fopen("temp.dat","w+b");
    int number=12346;
    int divisor=3;
    char * buf = calloc(number,1);
    fwrite(buf,number,1,fp);
    rewind(fp);
    int result=fread(buf,divisor,number,fp);
    printf("%d / %d = %d", number, divisor, result);
    free(buf);
    fclose(fp);
    return 0;
}

যদি দশমিক অংশও প্রয়োজন হয়, কেবল resultহিসাবে ঘোষণা doubleকরুন এবং এর ফলাফলটি যুক্ত করুন fmod(number,divisor)

এটি কীভাবে কাজ করে তার ব্যাখ্যা

  1. fwriteলিখেছেন numberবাইট (নম্বর উপরোক্ত উদাহরণের 123456 হচ্ছে)।
  2. rewind ফাইলের সামনে ফাইল পয়েন্টার পুনরায় সেট করে।
  3. freadফাইলটি দৈর্ঘ্যে সর্বাধিক number"রেকর্ডস" পড়ে divisorএবং এটি পড়ে থাকা উপাদানগুলির সংখ্যা প্রদান করে।

আপনি যদি 30 বাইট লিখে থাকেন তবে 3 টি ইউনিটে ফাইলটি আবার পড়ুন, আপনি 10 "ইউনিট" পান। 30/3 = 10


13
@ আইরেলনামলেস: তারা ভিতরে কী ব্যবহার করে তা আপনি জানেন না, তারা "বাস্তবায়ন সংজ্ঞায়িত" ব্ল্যাক বক্সে রয়েছে। কিছুই কেবল বিটওয়াইস অপারেটর ব্যবহার করতে বাধা দেয় না; যাইহোক, তারা আমার কোডের ডোমেনের বাইরে রয়েছে, সুতরাং এটি আমার সমস্যা নয়। :)
মাত্তেও ইটালিয়া

8
আমি আইভোফ্লিপস থেকে পরিষ্কার করতে পারি, আপনি একটি বড় কিছু পেয়ে যান এবং এটিকে তিনবার খুব ছোট কিছুতে ফেলে দেন এবং তারপরে দেখুন কতটা ফিট ted এটি তৃতীয়।
পিওরফেরেট

27
কোডটি ব্যাখ্যা করতে আমাদের সংস্থার সেরা সি প্রোগ্রামার (এবং সবচেয়ে সামাজিকভাবে বিশ্রী) বলেছিলেন। তার করার পরে, আমি বলেছিলাম এটি বেশ বুদ্ধিমান। তিনি বলেছিলেন যে 'এই ড্র্যাক কোনও সমাধান নয়' এবং আমাকে তার ডেস্কটি ছেড়ে যেতে বলেছে
cvursache

6
@cvursache আমি মনে করি মূল বক্তব্যটি হ'ল প্রশ্নটি এতটাই মস্তিষ্কের মৃত, যে কোনও মস্তিষ্কের মৃত উত্তর মঞ্জুরিপ্রাপ্ত। আপনার কোম্পানির "সেরা সি প্রোগ্রামার" ঠিক সহজেই বলতে পারত "যে ড্রেইক একটি (যথাযথ) প্রশ্ন নয়"
জেরেমিপ

17
@ জেরেমিপি: হুবহু আমার বক্তব্যটি হ'ল যদি সত্যিকারের জীবনে গাণিতিকের সমর্থন ছাড়াই আমাকে একটি সংকলক দেওয়া হয় তবে একমাত্র বুদ্ধিমান জিনিসটি আরও ভাল সংকলক চেয়েছিল , কারণ এই পরিস্থিতিতে কাজ করার কোনও মানে হয় না। যদি সাক্ষাত্কারকারক বিটওয়াইজ অপারেশনগুলির সাথে বিভাগ কীভাবে প্রয়োগ করতে হয় সে সম্পর্কে আমার জ্ঞানটি পরীক্ষা করতে চান তবে তিনি কেবল সোজা হয়ে থাকতে পারেন এবং তাত্ত্বিক প্রশ্ন হিসাবে এটি জিজ্ঞাসা করতে পারেন; এই জাতীয় "কৌশল অনুশীলন" কেবল উত্তরগুলির জন্য চিৎকার করে।
মাত্তেও ইটালিয়া

306
log(pow(exp(number),0.33333333333333333333)) /* :-) */

2
এটি যথাযথভাবে গোল করা এবং সংখ্যাটি খুব বেশি বড় না হলে কাজ করতে পারে।
রহস্যময়

252
উন্নত সংস্করণ: লগ (পাও (এক্সপ্রেস (সংখ্যা), পাপ (আতান 2 (1, বর্গ (8%))))
অ্যালান কারি

@ বিটমাস্ক, গণিত ফাংশনগুলি সাধারণত asm এ প্রয়োগ করা হয়।
সিঙ্গার অফ দ্যফাল

7
আমি এটি কেবল আমার জেএস কনসোলে টাইপ করেছি, এটি 709 এর চেয়ে বেশি সংখ্যক (এটি কেবল আমার সিস্টেম হতে পারে) Math.log(Math.pow(Math.exp(709),0.33333333333333333333))এবংMath.log(Math.pow(Math.exp(709),Math.sin(Math.atan2(1,Math.sqrt(8)))))
শাহির

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

int main(int argc, char *argv[])
{

    int num = 1234567;
    int den = 3;
    div_t r = div(num,den); // div() is a standard C function.
    printf("%d\n", r.quot);

    return 0;
}

113

আপনি (প্ল্যাটফর্ম নির্ভর) ইনলাইন সমাবেশ, উদাহরণস্বরূপ, x86 এর জন্য ব্যবহার করতে পারেন: (নেতিবাচক সংখ্যার জন্যও কাজ করে)

#include <stdio.h>

int main() {
  int dividend = -42, divisor = 5, quotient, remainder;

  __asm__ ( "cdq; idivl %%ebx;"
          : "=a" (quotient), "=d" (remainder)
          : "a"  (dividend), "b"  (divisor)
          : );

  printf("%i / %i = %i, remainder: %i\n", dividend, divisor, quotient, remainder);
  return 0;
}

2
@ জেরেমিপি এই উত্তরটি সিতে লেখা যায় না এমন ধারণা নিয়ে ব্যর্থ হয় না? প্রশ্নটি সর্বোপরি "সি" ট্যাগ করা আছে।
শেঠ কার্নেগি

1
@ শেঠ কার্নেগি উত্তর সি তে লেখা নেই আমার বক্তব্য। x86 এসেম্বলার স্ট্যান্ডার্ডের অংশ নয়।
জেরেমিপ

1
@ জেরেমিপি এটি সত্য, তবে asmনির্দেশিকাটি। এবং আমি যুক্ত করব যে সি সংকলকগুলি কেবলমাত্র ইনলাইন এসেম্বেবলারগুলিই নয়, ডেলফিরও এটি রয়েছে।
শেঠ কারনেগি

7
@ শেঠ কার্নেগি asmনির্দেশটি কেবলমাত্র পরিশিষ্ট জে - সাধারণ এক্সটেনশনের অধীনে C99 স্ট্যান্ডার্ডে উল্লেখ করা হয়েছে।
জেরেমিপি

2
আর্ম-ইবি-জিসিসিতে ব্যর্থ।
দামিয়ান ইয়ারিক

106

বেস 3 স্ট্রিংয়ে রূপান্তর করতে itoa ব্যবহার করুন । শেষ ট্রিটটি ফেলে দিন এবং বেস 10 এ ফিরে রূপান্তর করুন।

// Note: itoa is non-standard but actual implementations
// don't seem to handle negative when base != 10.
int div3(int i) {
    char str[42];
    sprintf(str, "%d", INT_MIN); // Put minus sign at str[0]
    if (i>0)                     // Remove sign if positive
        str[0] = ' ';
    itoa(abs(i), &str[1], 3);    // Put ternary absolute value starting at str[1]
    str[strlen(&str[1])] = '\0'; // Drop last digit
    return strtol(str, NULL, 3); // Read back result
}

4
@ সিসেম্বি আমি আসলে জানতাম না যে itoaএকটি স্বেচ্ছাসেবীর বেস ব্যবহার করতে পারে। আপনি যদি একটি সম্পূর্ণ কাজ বাস্তবায়ন করেন তবে itoaআমি আপভোট করব।
রহস্যময়

2
বাস্তবায়নে অন্তর্ভুক্ত থাকবে /এবং %... :-)
আর .. গিথহাব বন্ধ করুন

2
@ আর .. সুতরাং printfআপনার দশমিক ফলাফল প্রদর্শন করার জন্য বাস্তবায়ন করে ।
দামিয়ান ইয়ারিক

57

(দ্রষ্টব্য: আরও ভাল সংস্করণের জন্য নীচে সম্পাদনা 2 দেখুন!)

এটি যেমনটি শোনায় ততটা জটিল নয়, কারণ আপনি "[..] +[..] অপারেটর ব্যবহার না করে" বলেছিলেন । নীচে দেখুন, আপনি যদি +সমস্ত একসাথে চরিত্রটি ব্যবহার করতে নিষেধ করতে চান ।

unsigned div_by(unsigned const x, unsigned const by) {
  unsigned floor = 0;
  for (unsigned cmp = 0, r = 0; cmp <= x;) {
    for (unsigned i = 0; i < by; i++)
      cmp++; // that's not the + operator!
    floor = r;
    r++; // neither is this.
  }
  return floor;
}

তারপরে কেবল div_by(100,3)ভাগ 100করে বলুন 3


সম্পাদনা করুন : আপনি যান এবং ++অপারেটর পাশাপাশি প্রতিস্থাপন করতে পারেন :

unsigned inc(unsigned x) {
  for (unsigned mask = 1; mask; mask <<= 1) {
    if (mask & x)
      x &= ~mask;
    else
      return x & mask;
  }
  return 0; // overflow (note that both x and mask are 0 here)
}

সম্পাদনা করুন 2: সামান্য দ্রুত কোনো অপারেটর যে রয়েছে ব্যবহার না করেই সংস্করণ +, -, *, /, % অক্ষর

unsigned add(char const zero[], unsigned const x, unsigned const y) {
  // this exploits that &foo[bar] == foo+bar if foo is of type char*
  return (int)(uintptr_t)(&((&zero[x])[y]));
}

unsigned div_by(unsigned const x, unsigned const by) {
  unsigned floor = 0;
  for (unsigned cmp = 0, r = 0; cmp <= x;) {
    cmp = add(0,cmp,by);
    floor = r;
    r = add(0,r,1);
  }
  return floor;
}

আমরা addফাংশনটির প্রথম যুক্তিটি ব্যবহার করি কারণ আমরা *অক্ষরটি ব্যবহার না করে পয়েন্টারগুলির ধরণটি বোঝাতে পারি না , ফাংশন প্যারামিটার তালিকাগুলি ব্যতীত যেখানে বাক্য গঠনটি type[]অনুরূপ type* const

এফডাব্লুআইডাব্লু, আপনি সহজেই অ্যান্ড্রেটির0x55555556 প্রস্তাবিত ট্রিকটি ব্যবহার করতে অনুরূপ কৌশল ব্যবহার করে একটি গুণ গুণ কার্যকর করতে পারেন :

int mul(int const x, int const y) {
  return sizeof(struct {
    char const ignore[y];
  }[x]);
}

5
প্রশ্নটি ট্যাগ করা হয়েছে সি , এসকিউএল নয়, এমনকি ওরাকলের উল্লেখ রয়েছে।
বিটমাস্ক

3
এটি আসলে এসকিউএল এর মতো দেখাচ্ছে না!
মূইলিপ

64
আপনি যদি ব্যবহার করতে পারেন ++: আপনি কেবল ব্যবহার করছেন না কেন /=?
কিওয়ার্টজ

5
@ বিটমাস্ক: ++এটিও একটি শর্টকাট: জন্য num = num + 1
কিওয়ার্টজ

4
@ বিটমাস্ক হ্যাঁ, তবে +=শেষ পর্যন্ত এটি একটি শর্টকাট num = num + 1
কিওয়ার্টজ

44

সেটুন কম্পিউটারে এটি সহজেই সম্ভব ।

একটি পূর্ণসংখ্যা 3 দ্বারা বিভক্ত করতে ডানদিকে 1 স্থান স্থানান্তর করুন

যদিও আমি নিশ্চিত নই যে এই জাতীয় প্ল্যাটফর্মে যদিও মানানসই সি সংকলকটি প্রয়োগ করা কঠোরভাবে সম্ভব। আমাদের "কমপক্ষে 8 টি বিট" "-128 থেকে +127 এর মধ্যে কমপক্ষে পূর্ণসংখ্যা রাখতে সক্ষম" হিসাবে ব্যাখ্যা করার মতো নিয়মগুলি কিছুটা প্রসারিত করতে হতে পারে।


8
সমস্যা হল আপনি সি অপারেটর একটি "1 টি স্থান দ্বারা শিফট অধিকার" have না >>অর্থাত এটা গাণিতিক না মেশিন উপস্থাপনা পরিপ্রেক্ষিতে উল্লেখিত থাকে, তবে অপারেটর অপারেটর "2 ^ n দ্বারা বিভাজন" হয়।
আর .. গিটহাব বন্ধ করুন ICE

সেটুন কম্পিউটার শব্দের কোনও অর্থে বাইনারি নয়, সুতরাং নির্দেশিকা সেট অবশ্যই আলাদা হতে হবে। তবে, আমি সেই কম্পিউটারটির অপারেশন সম্পর্কে মোটেই পরিচিত নই, সুতরাং প্রতিক্রিয়াটি সত্য কিনা তা নিশ্চিত করতে পারছি না - তবে কমপক্ষে এটি উপলব্ধি করে - এবং অত্যন্ত আসল original +1
ভাইরোলিনো

32

যেহেতু এটি ওরাকল থেকে এসেছে, প্রাক গণনা করা উত্তরের একটি সারণী সম্পর্কে কীভাবে। :-D


32

এখানে আমার সমাধান:

public static int div_by_3(long a) {
    a <<= 30;
    for(int i = 2; i <= 32 ; i <<= 1) {
        a = add(a, a >> i);
    }
    return (int) (a >> 32);
}

public static long add(long a, long b) {
    long carry = (a & b) << 1;
    long sum = (a ^ b);
    return carry == 0 ? sum : add(carry, sum);
}

প্রথম, এটি নোট করুন

1/3 = 1/4 + 1/16 + 1/64 + ...

এখন, বাকি কি সহজ!

a/3 = a * 1/3  
a/3 = a * (1/4 + 1/16 + 1/64 + ...)
a/3 = a/4 + a/16 + 1/64 + ...
a/3 = a >> 2 + a >> 4 + a >> 6 + ...

এখন আমাদের যা করতে হবে তা হ'ল এক সাথে এই বিট স্থানান্তরিত মানগুলি যুক্ত করতে! ওহো! আমরা যদিও যোগ করতে পারি না, তার পরিবর্তে, বিট-বুদ্ধিমান অপারেটরগুলি ব্যবহার করে আমাদের একটি অ্যাড ফাংশন লিখতে হবে! আপনি যদি বিট-বুদ্ধিমান অপারেটরগুলির সাথে পরিচিত হন তবে আমার সমাধানটি মোটামুটি সহজ দেখানো উচিত ... তবে আপনি যদি না হন তবে আমি শেষের একটি উদাহরণ দিয়ে যাব।

আরেকটি বিষয় লক্ষণীয় যে আমি প্রথমে 30 দ্বারা বামে স্থানান্তরিত করব! এটি ভগ্নাংশগুলি বৃত্তাকার বন্ধ না হয় তা নিশ্চিত করা হয়।

11 + 6

1011 + 0110  
sum = 1011 ^ 0110 = 1101  
carry = (1011 & 0110) << 1 = 0010 << 1 = 0100  
Now you recurse!

1101 + 0100  
sum = 1101 ^ 0100 = 1001  
carry = (1101 & 0100) << 1 = 0100 << 1 = 1000  
Again!

1001 + 1000  
sum = 1001 ^ 1000 = 0001  
carry = (1001 & 1000) << 1 = 1000 << 1 = 10000  
One last time!

0001 + 10000
sum = 0001 ^ 10000 = 10001 = 17  
carry = (0001 & 10000) << 1 = 0

Done!

আপনি কেবল ছোটবেলায় শিখেছেন এটি কেবল সংযোজন বহন করে!

111
 1011
+0110
-----
10001

এই বাস্তবায়ন ব্যর্থ হয়েছে কারণ আমরা সমীকরণের সমস্ত শর্তাদি যুক্ত করতে পারি না:

a / 3 = a/4 + a/4^2 + a/4^3 + ... + a/4^i + ... = f(a, i) + a * 1/3 * 1/4^i
f(a, i) = a/4 + a/4^2 + ... + a/4^i

ধরুন, div_by_3(a)= x এর পুনঃসূচনা x <= floor(f(a, i)) < a / 3। কখন a = 3k, আমরা ভুল উত্তর পাই।


2
এটি 3 ইনপুট জন্য কাজ করে? ১/৪, ১/১ all, ... সমস্ত 3 এর জন্য 0 ফিরে আসে, তবে 0 এর সমষ্টি হবে, তবে 3/3 = 1.
হ্যাচেট - 27:55

1
যুক্তিটি ভাল তবে বাস্তবায়ন সমস্যাযুক্ত। সিরিজটির আনুমানিক n/3পরিমাণ সর্বদা কম n/3যার অর্থ কোনও n=3kফলাফলের k-1পরিবর্তে হয় k
Xyand

@ অ্যালবার্ট, আমি এই প্রথম পদ্ধতির চেষ্টা করলাম, কয়েকটি পরিবর্তনের সাথে, তবে তারা সকলেই কিছু নির্দিষ্ট সংখ্যায় 3 টি দ্বারা সমানভাবে বিভাজ্য বা 2 দ্বারা সমানভাবে বিভাজ্য (ভিন্নতার উপর নির্ভরশীল) ব্যর্থ হয়েছিল। তাই আমি আরও সোজা কিছু চেষ্টা করেছিলাম tried আমি এই পদ্ধতির একটি বাস্তবায়ন দেখতে চাই যা কাজ করে, আমি কোথায় স্ক্রু করছি তা দেখতে।
হ্যাচিট -

@ হ্যাচেট, প্রশ্নটি বন্ধ রয়েছে তাই আমি একটি নতুন উত্তর পোস্ট করতে পারি না তবে বাইনারি ডিভ বাস্তবায়ন করার ধারণাটি। এটি সন্ধান করা আমার সহজ হওয়া উচিত।
Xyand


25

একটি 32-বিট সংখ্যা 3 দ্বারা বিভক্ত করতে একজন এটির দ্বারা গুণ করতে পারে 0x55555556এবং তারপরে bit৪ বিটের ফলাফলের উপরের 32 বিট নিতে পারে।

এখন যা করতে হবে তা হ'ল বিট ক্রিয়াকলাপ এবং শিফ্ট ব্যবহার করে গুণ প্রয়োগ করা ...


1
ধীর বিভাজনের আশেপাশে কাজ করার এটি একটি সাধারণ সংকলক কৌশল। তবে আপনাকে সম্ভবত কিছু ফিক্স আপগুলি করতে হবে, যেহেতু 0x55555556 / 2 ** 32 ঠিক 1/3 নয়।
কোডসইনচাউস

multiply it। এটি কি নিষিদ্ধ *অপারেটরটি ব্যবহার করে বোঝায় না ?
লুস্কুবাল

8
@ লুইসুবল: না, তা হবে না। এ কারণেই আমি বলেছিলাম: "এখন যা করা বাকি তা হ'ল বিট ক্রিয়াকলাপ এবং শিফট ব্যবহার করে গুণ প্রয়োগ করা "
এন্ট

18

তবুও আরেকটি সমাধান। এটির জন্য কোনও int এর ন্যূনতম মান ব্যতীত সমস্ত ইনট (নেতিবাচক ints সহ) হ্যান্ডেল করা উচিত, যা একটি হার্ড কোডেড ব্যতিক্রম হিসাবে হ্যান্ডেল করা প্রয়োজন। এটি মূলত বিয়োগফল দ্বারা বিভাজন করে তবে কেবল বিট অপারেটর (শিফট, এক্সওর, এবং পরিপূরক) ব্যবহার করে। দ্রুত গতির জন্য, এটি 3 * বিয়োগ করে (2 এর পাওয়ার হ্রাস)। সি # তে, এটি মিলি সেকেন্ডের জন্য এই ডিভাইডবাই 3 কলগুলির প্রায় 444 টি (1000,000 বিভাজনের জন্য 2.2 সেকেন্ড) কার্যকর করে, তাই ভয়াবহরূপে ধীর হয় না, তবে সরল এক্স / 3 এর মতো দ্রুততর কাছাকাছি নয়। তুলনা করে, কোডির দুর্দান্ত সমাধানটি এর চেয়ে 5 গুণ বেশি দ্রুত faster

public static int DivideBy3(int a) {
    bool negative = a < 0;
    if (negative) a = Negate(a);
    int result;
    int sub = 3 << 29;
    int threes = 1 << 29;
    result = 0;
    while (threes > 0) {
        if (a >= sub) {
            a = Add(a, Negate(sub));
            result = Add(result, threes);
        }
        sub >>= 1;
        threes >>= 1;
    }
    if (negative) result = Negate(result);
    return result;
}
public static int Negate(int a) {
    return Add(~a, 1);
}
public static int Add(int a, int b) {
    int x = 0;
    x = a ^ b;
    while ((a & b) != 0) {
        b = (a & b) << 1;
        a = x;
        x = a ^ b;
    }
    return x;
}

এটি সি # কারণ এটি আমার পক্ষে কার্যকর ছিল তবে গ এর থেকে পার্থক্যগুলি সামান্য হওয়া উচিত।


আপনার কেবল একবার সাব বিয়োগের চেষ্টা করা দরকার, কারণ আপনি যদি এটির দু'বার বিয়োগ করতে পারতেন তবে আপনি আগের পুনরাবৃত্তিটি বিয়োগ করতে পারতেন যখন এটি এখনকার চেয়ে দ্বিগুণ was
নীল

না (a >= sub)একটি বিয়োগ যেমন গণনা?
নীল

@ নীল, আমি মনে করি আপনি ঠিক বলেছেন লুপের দ্বিতীয় পুনরাবৃত্তি থেকে একটি অনির্দিষ্ট তুলনা সংরক্ষণ করা হলে অভ্যন্তরীণটি একটি সাধারণ দ্বারা প্রতিস্থাপন করা যেতে পারে। সম্পর্কিত> = বিয়োগফল হচ্ছে ... আমি আশা করি না, কারণ এটি এটি করা বেশ কঠিন করে তুলবে! আমি আপনার বক্তব্যটি দেখতে পাচ্ছি, তবে আমি মনে করি যে আমি যে দিকে বলি> = বিয়োগফল হিসাবে গণ্য হয় না on
হ্যাচিট - 0

@ নীল, আমি এই পরিবর্তন করেছি, যা সময়কে অর্ধেক কেটে ফেলেছিল (অবিবাহিত নেগেটসও সংরক্ষণ করেছিল)।
হ্যাচিট -

16

এটা সত্যিই বেশ সহজ।

if (number == 0) return 0;
if (number == 1) return 0;
if (number == 2) return 0;
if (number == 3) return 1;
if (number == 4) return 1;
if (number == 5) return 1;
if (number == 6) return 2;

(আমি অবশ্যই ব্র্যাভিটির জন্য প্রোগ্রামের কিছু বাদ দিয়েছি)) প্রোগ্রামার যদি এই সমস্ত টাইপ করে ক্লান্ত হয়ে যায় তবে আমি নিশ্চিত যে সে বা সে তার জন্য এটি তৈরি করতে একটি আলাদা প্রোগ্রাম লিখতে পারে could আমি কোনও নির্দিষ্ট অপারেটর সম্পর্কে সচেতন হতে পারি /, এটি তার কাজকে অত্যন্ত সহজ করবে।


8
আপনি Dictionary<number, number>বারবার ifবিবৃতিগুলির পরিবর্তে একটি ব্যবহার করতে পারেন যাতে আপনার O(1)সময় জটিলতা থাকতে পারে!
পিটার ওলসন

@ এএনসনাল নো, সংখ্যাটি বাড়ার সাথে সাথে সময় রৈখিকভাবে বৃদ্ধি পায়, কারণ বিবৃতিগুলি যদি বেশি বেশি অতিক্রম করতে হয়।
পিটার ওলসন

তাত্ত্বিকভাবে এটি বৃদ্ধি পায় না :)
টোটেন্ট

@ পিটারলসন, এরেসউনাল যদি আমি একটি স্যুইচ স্টেটমেন্ট ব্যবহার করি তবে এটি ও (1) :-) হতে হবে
থাইডেটর্স

অথবা আপনি একটি অ্যারে তৈরি করতে এবং ডায়নামিক প্রোগ্রামিং ব্যবহার করতে পারেন। যদি x / 3 = y হয় তবে y << 2 + y = x - x% 3।
lsiebert

14

কাউন্টারগুলি ব্যবহার করা একটি মৌলিক সমাধান:

int DivBy3(int num) {
    int result = 0;
    int counter = 0;
    while (1) {
        if (num == counter)       //Modulus 0
            return result;
        counter = abs(~counter);  //++counter

        if (num == counter)       //Modulus 1
            return result;
        counter = abs(~counter);  //++counter

        if (num == counter)       //Modulus 2
            return result;
        counter = abs(~counter);  //++counter

        result = abs(~result);    //++result
    }
}

এটি একটি মডুলাস ফাংশন সম্পাদন করা সহজ, মন্তব্যগুলি পরীক্ষা করুন।


@ এনেস ইউনাল: অল্প সংখ্যার জন্য নয় :) এই অ্যালগরিদমটি খুব বেসিক।
জিজে

প্রতিটি
আদিমতায়

11

এটি একটি বেস 2 এর শাস্ত্রীয় বিভাগ অ্যালগরিদম:

#include <stdio.h>
#include <stdint.h>

int main()
{
  uint32_t mod3[6] = { 0,1,2,0,1,2 };
  uint32_t x = 1234567; // number to divide, and remainder at the end
  uint32_t y = 0; // result
  int bit = 31; // current bit
  printf("X=%u   X/3=%u\n",x,x/3); // the '/3' is for testing

  while (bit>0)
  {
    printf("BIT=%d  X=%u  Y=%u\n",bit,x,y);
    // decrement bit
    int h = 1; while (1) { bit ^= h; if ( bit&h ) h <<= 1; else break; }
    uint32_t r = x>>bit;  // current remainder in 0..5
    x ^= r<<bit;          // remove R bits from X
    if (r >= 3) y |= 1<<bit; // new output bit
    x |= mod3[r]<<bit;    // new remainder inserted in X
  }
  printf("Y=%u\n",y);
}

10

প্যাসকেলে প্রোগ্রামটি লিখুন এবং DIVঅপারেটরটি ব্যবহার করুন ।

যেহেতু প্রশ্ন ট্যাগ করা হয়েছে , আপনি সম্ভবত পাস্কলে একটি ফাংশন লিখতে পারেন এবং এটি আপনার সি প্রোগ্রাম থেকে কল করতে পারেন; এটি করার পদ্ধতিটি সিস্টেম-নির্দিষ্ট।

তবে এখানে একটি উদাহরণ যা আমার উবুন্টু সিস্টেমে ফ্রি প্যাস্কেল fp-compilerপ্যাকেজ ইনস্টল থাকা সাথে কাজ করে । (আমি নিছক ভুল জায়গায় জেদ করে এই কাজটি করে যাচ্ছি; আমি দাবি করি না যে এটি দরকারী)

divide_by_3.pas :

unit Divide_By_3;
interface
    function div_by_3(n: integer): integer; cdecl; export;
implementation
    function div_by_3(n: integer): integer; cdecl;
    begin
        div_by_3 := n div 3;
    end;
end.

main.c :

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

extern int div_by_3(int n);

int main(void) {
    int n;
    fputs("Enter a number: ", stdout);
    fflush(stdout);
    scanf("%d", &n);
    printf("%d / 3 = %d\n", n, div_by_3(n));
    return 0;
}

গঠন করা:

fpc divide_by_3.pas && gcc divide_by_3.o main.c -o main

নমুনা কার্যকর:

$ ./main
Enter a number: 100
100 / 3 = 33

8
int div3(int x)
{
  int reminder = abs(x);
  int result = 0;
  while(reminder >= 3)
  {
     result++;

     reminder--;
     reminder--;
     reminder--;
  }
  return result;
}

3
++ এবং - অপারেটরগুলি + এবং - অপারেটরগুলি থেকে ডিফেরেন্ট হয়! অ্যাসেম্বলি ভাষার ক্ষেত্রে দুটি নির্দেশনা রয়েছে ADDএবং INCসেগুলির ওপোকডগুলি একই নয়।
আমির সানিয়ান

7

এই উত্তরটি ইতিমধ্যে প্রকাশিত হয়েছে কিনা তা ক্রস-চেক করেনি। যদি প্রোগ্রামটি ভাসমান সংখ্যায় প্রসারিত করা প্রয়োজন, সংখ্যাগুলি যথাযথতার 10 * সংখ্যা দ্বারা গুণ করা যায় এবং তারপরে নিম্নলিখিত কোডটি আবার প্রয়োগ করা যেতে পারে।

#include <stdio.h>

int main()
{
    int aNumber = 500;
    int gResult = 0;

    int aLoop = 0;

    int i = 0;
    for(i = 0; i < aNumber; i++)
    {
        if(aLoop == 3)
        {
           gResult++;
           aLoop = 0;
        }  
        aLoop++;
    }

    printf("Reulst of %d / 3 = %d", aNumber, gResult);

    return 0;
}

7

এটি কেবল তিনটি নয়, কোনও বিভাজনের পক্ষে কাজ করা উচিত। বর্তমানে কেবল স্বাক্ষরবিহীন, তবে এটি স্বাক্ষরিত পর্যন্ত প্রসারিত করা এতটা কঠিন হওয়া উচিত নয়।

#include <stdio.h>

unsigned sub(unsigned two, unsigned one);
unsigned bitdiv(unsigned top, unsigned bot);
unsigned sub(unsigned two, unsigned one)
{
unsigned bor;
bor = one;
do      {
        one = ~two & bor;
        two ^= bor;
        bor = one<<1;
        } while (one);
return two;
}

unsigned bitdiv(unsigned top, unsigned bot)
{
unsigned result, shift;

if (!bot || top < bot) return 0;

for(shift=1;top >= (bot<<=1); shift++) {;}
bot >>= 1;

for (result=0; shift--; bot >>= 1 ) {
        result <<=1;
        if (top >= bot) {
                top = sub(top,bot);
                result |= 1;
                }
        }
return result;
}

int main(void)
{
unsigned arg,val;

for (arg=2; arg < 40; arg++) {
        val = bitdiv(arg,3);
        printf("Arg=%u Val=%u\n", arg, val);
        }
return 0;
}

7

/অপারেটরটিকে "পর্দার অন্তরালে" ব্যবহার করে evalএবং স্ট্রিং কনকনেটেশন দিয়ে প্রতারণা করা হবে ?

উদাহরণস্বরূপ, জাভাক্রিপ্টে, আপনি এটি করতে পারেন

function div3 (n) {
    var div = String.fromCharCode(47);
    return eval([n, div, 3].join(""));
}

7

ব্যবহার বিসি ম্যাথ মধ্যে পিএইচপি :

<?php
    $a = 12345;
    $b = bcdiv($a, 3);   
?>

মাইএসকিউএল (এটি ওরাকল থেকে প্রাপ্ত একটি সাক্ষাত্কার)

> SELECT 12345 DIV 3;

পাস্কাল :

a:= 12345;
b:= a div 3;

x86-64 সমাবেশের ভাষা:

mov  r8, 3
xor  rdx, rdx   
mov  rax, 12345
idiv r8

1
দুর্দান্ত গল্প, এটি সি ট্যাগ করা হয়েছে এবং প্রথম দিন থেকেই তাই হয়েছে। তদতিরিক্ত, আপনি প্রশ্নের বিন্দু উপলব্ধি করতে সম্পূর্ণরূপে ব্যর্থ হন।
লন্ডিন

6

প্রথম যে আমি সঙ্গে এসেছি।

irb(main):101:0> div3 = -> n { s = '%0' + n.to_s + 's'; (s % '').gsub('   ', ' ').size }
=> #<Proc:0x0000000205ae90@(irb):101 (lambda)>
irb(main):102:0> div3[12]
=> 4
irb(main):103:0> div3[666]
=> 222

সম্পাদনা: দুঃখিত, আমি ট্যাগটি লক্ষ্য করিনি C। তবে আপনি স্ট্রিং ফর্ম্যাটিং সম্পর্কে ধারণাটি ব্যবহার করতে পারেন, আমার ধারণা ...


5

নিম্নলিখিত স্ক্রিপ্টটি একটি সি প্রোগ্রাম উত্পন্ন করে যা অপারেটরগুলি ব্যবহার না করেই সমস্যার সমাধান করে * / + - %:

#!/usr/bin/env python3

print('''#include <stdint.h>
#include <stdio.h>
const int32_t div_by_3(const int32_t input)
{
''')

for i in range(-2**31, 2**31):
    print('    if(input == %d) return %d;' % (i, i / 3))


print(r'''
    return 42; // impossible
}
int main()
{
    const int32_t number = 8;
    printf("%d / 3 = %d\n", number, div_by_3(number));
}
''')

5

হ্যাকার ডিলাইট ম্যাজিক নম্বর ক্যালকুলেটর ব্যবহার করে

int divideByThree(int num)
{
  return (fma(num, 1431655766, 0) >> 32);
}

যেখানে এফএমএ হ্যাডারে সংজ্ঞায়িত করা একটি স্ট্যান্ডার্ড লাইব্রেরি ফাংশন math.h


এটি কীভাবে অপারেটরটি ব্যবহার করছে -না *?
বিটমাস্ক

4

এই পদ্ধতির (সি #) কীভাবে?

private int dividedBy3(int n) {
        List<Object> a = new Object[n].ToList();
        List<Object> b = new List<object>();
        while (a.Count > 2) {
            a.RemoveRange(0, 3);
            b.Add(new Object());
        }
        return b.Count;
    }

এটি সি ট্যাগ করা হয়েছে এবং প্রথম দিন থেকেই তাই হয়েছে।
লন্ডিন

4

আমি মনে করি সঠিক উত্তর:

আমি কেন বেসিক অপারেটরটি বেসিক অপারেশন করতে ব্যবহার করব না?


কারণ তারা কী জানতে চায় আপনি যদি জানেন যে প্রসেসরটি অভ্যন্তরীণভাবে কীভাবে কাজ করে ... গণিত অপারেটরটি ব্যবহার করা শেষ পর্যন্ত উপরের উত্তরের সাথে একই রকম একটি ক্রিয়াকলাপ সম্পাদন করে।
র‌্যাপ্টোরএক্স

অথবা তারা জানতে চান যে আপনি কোনও অকেজো সমস্যাটি চিনতে পারেন কিনা।
গ্রেগোয়ার

1
@ গ্রেগোয়ার আমি একমত, এ জাতীয় বাস্তবায়ন করার দরকার নেই, কৌতুকজীবনে বিট (অর্কেলে) অকেজো প্রয়োজনীয়তা এড়াতে এটি প্রয়োজনীয়: সঠিক উত্তরটি: "এটি কোনও অর্থই দেয় না, কেন অর্থের অর্থ কেন? তার জন্য? ")
অ্যালেক্সওয়েন

4

সমাধান fma () লাইব্রেরি ফাংশন ব্যবহার করে , যেকোন ধনাত্মক সংখ্যার জন্য কাজ করে:

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

int main()
{
    int number = 8;//Any +ve no.
    int temp = 3, result = 0;
    while(temp <= number){
        temp = fma(temp, 1, 3); //fma(a, b, c) is a library function and returns (a*b) + c.
        result = fma(result, 1, 1);
    } 
    printf("\n\n%d divided by 3 = %d\n", number, result);
}

আমার অন্য উত্তর দেখুন


লাইব্রেরির দুর্দান্ত ব্যবহার। আপনি সরাসরি ফলাফল ++ ব্যবহার করেননি কেন?
সবুজ গাবলিন

তারপরে লোকেরা বলতে পারে যে + ব্যবহার করা হয়েছে।
আট

3

ওএস এক্স এর ত্বরণ কাঠামোর অংশ হিসাবে অন্তর্ভুক্ত সিবি্লাস ব্যবহার করুন ।

[02:31:59] [william@relativity ~]$ cat div3.c
#import <stdio.h>
#import <Accelerate/Accelerate.h>

int main() {
    float multiplicand = 123456.0;
    float multiplier = 0.333333;
    printf("%f * %f == ", multiplicand, multiplier);
    cblas_sscal(1, multiplier, &multiplicand, 1);
    printf("%f\n", multiplicand);
}

[02:32:07] [william@relativity ~]$ clang div3.c -framework Accelerate -o div3 && ./div3
123456.000000 * 0.333333 == 41151.957031

ঠিক আছে, এটি কেবল একটি বাস্তবায়ন বিশদ ছিল তাই আমি এটিকে 0.333333 এর পরিবর্তে 3.0 / 1.0 টাইপ করতে পারি, তবে আমার নিয়ম অনুসারে খেলা উচিত। সংশোধন করা হয়েছে!
wjl

আমার কাছে এটি মূলত 3.0 / 1.0 হিসাবে ছিল যা আমার পরীক্ষায় হয়েছিল। উচ্চতর নির্ভুলতা নম্বর ব্যবহার করে তাদের যুক্তিসঙ্গতভাবে সঠিক ফলাফল পাওয়া উচিত। gist.github.com/3401496
wjl 20'12


3

প্রথম:

x/3 = (x/4) / (1-1/4)

তারপরে এক্স / (1 - y) কীভাবে সমাধান করবেন তা নির্ধারণ করুন:

x/(1-1/y)
  = x * (1+y) / (1-y^2)
  = x * (1+y) * (1+y^2) / (1-y^4)
  = ...
  = x * (1+y) * (1+y^2) * (1+y^4) * ... * (1+y^(2^i)) / (1-y^(2^(i+i))
  = x * (1+y) * (1+y^2) * (1+y^4) * ... * (1+y^(2^i))

y = 1/4 সহ:

int div3(int x) {
    x <<= 6;    // need more precise
    x += x>>2;  // x = x * (1+(1/2)^2)
    x += x>>4;  // x = x * (1+(1/2)^4)
    x += x>>8;  // x = x * (1+(1/2)^8)
    x += x>>16; // x = x * (1+(1/2)^16)
    return (x+1)>>8; // as (1-(1/2)^32) very near 1,
                     // we plus 1 instead of div (1-(1/2)^32)
}

যদিও এটি ব্যবহার করে +তবে ইতিমধ্যে কেউ প্রয়োগ করে বিটওয়াইস অপ দিয়ে যোগ করে।

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