*, /, +, -,% ऑपरेटरों का उपयोग किए बिना एक संख्या को 3 से विभाजित करें


684

कैसे आप का उपयोग किए बिना 3 से एक नंबर को विभाजित होगा *, /, +, -, %, ऑपरेटरों?

संख्या पर हस्ताक्षर किए या अहस्ताक्षरित हो सकते हैं।


13
@AlexandreC। - हालांकि वे तकनीक इसके अतिरिक्त (+) का उपयोग कर रहे हैं।
हैचेट -

19
यह ओरेकल था इसलिए ऑरेकल के किन हिस्सों को आपको इस्तेमाल करने की अनुमति थी?
होगन

8
पहचाना गया डुप्लिकेट एक डुप्लिकेट नहीं है। ध्यान दें कि यहां कई उत्तर न तो बिट शिफ्टिंग या जोड़ का उपयोग करते हैं क्योंकि यह प्रश्न उन कार्यों के समाधान को प्रतिबंधित नहीं करता है।
माइकल बूर

66
... और यहां बताया गया है कि PL / SQL कैसे पैदा होता है।
सेदत कपपनोग्लू

22
यह सवाल एसओ के लिए अपमानजनक है। यह codegolf.stackexchange.com
Kromster

जवाबों:


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, इसलिए sum + = a, n = a + b, और iterate। जब एक == 0 (एन <4), राशि + = मंजिल (एन / 3); यानी, 1 अगर n == 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 को गोल किया जा सकता है।
योरिक सिज़लिंग 13

2
@ जबकि 1: यह बिटवाइज़ और ऑपरेशन है। इसके अलावा, एक सर्वविदित तथ्य यह है कि 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
@ IvoFlipse से मैं साफ कर सकता हूं, आप एक बड़ी चीज प्राप्त करते हैं और इसे तीन बार बहुत छोटे से हिलाते हैं , और फिर देखते हैं कि इसमें कितना फिट है।
प्यूरफेरेट

27
कोड समझाने के लिए हमारी कंपनी में सबसे अच्छा सी प्रोग्रामर (और सबसे सामाजिक रूप से अजीब) पूछा। उसने किया के बाद, मैंने कहा कि यह बहुत सरल था। उन्होंने कहा कि 'इस dreck एक समाधान नहीं है' और मुझे अपनी मेज छोड़ने के लिए कहा
cvursache

6
@cvursache मुझे लगता है कि यह मुद्दा इतना ब्रेन डेड है, कि एक ब्रेन डेड जवाब की अनुमति है। आपकी कंपनी में "सबसे अच्छा सी प्रोग्रामर" बस इतनी आसानी से कहा जा सकता है कि "
मलबे

17
@JeremyP: बिल्कुल। मेरा कहना यह है कि अगर वास्तविक जीवन में मुझे अंकगणित के समर्थन के बिना एक संकलक दिया जाता है तो केवल एक समझदार चीज़ एक बेहतर संकलक के लिए पूछी जाएगी , क्योंकि उन परिस्थितियों में काम करने का कोई मतलब नहीं है। यदि साक्षात्कारकर्ता मेरे ज्ञान की जांच करना चाहता था कि बिटवाइज़ ऑपरेशंस के साथ डिवीज़न को कैसे लागू किया जाए तो वह सीधा हो सकता है और इसे एक सैद्धांतिक प्रश्न के रूप में पूछ सकता है; इस तरह के "ट्रिक एक्सरसाइज" इस तरह के उत्तरों के लिए चिल्लाते हैं।
मैट्टो इटालिया

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

2
यह वास्तव में काम कर सकता है यदि ठीक से गोल हो और यदि संख्या बहुत बड़ी न हो।
मिस्टिक जूल

252
बेहतर संस्करण: लॉग (पॉव (एक्सपी (संख्या), पाप) (एटैन 2 (1, sqrt (8))))
एलन करी

@bitmask, गणित कार्यों को आमतौर पर सीधे asm में लागू किया जाता है।
SingerOfTheFall

7
मैंने इसे अपने js कंसोल में टाइप किया, यह 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)))))
Shaheer

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
@JeremyP आपकी टिप्पणी इस धारणा पर विफल नहीं है कि उत्तर C में नहीं लिखा जा सकता है? प्रश्न को सभी के बाद "सी" टैग किया गया है।
सेठ कार्नेगी

1
@SethCarnegie उत्तर C में नहीं लिखा गया है, मेरी बात है। x86 कोडांतरक मानक का हिस्सा नहीं है।
जेरेमीपीप

1
@JeremyP जो सत्य है, लेकिन asmनिर्देश है। और मैं जोड़ूंगा कि सी कंपाइलर केवल वे नहीं हैं जो इनलाइन असेंबलर हैं, डेल्फी के पास भी है।
सेठ कार्नेगी

7
@SethCarnegie asmनिर्देश केवल परिशिष्ट J के तहत C99 मानक में उल्लिखित है - सामान्य एक्सटेंशन।
जेरेमीप

2
बांह-एब्बी-जीसीसी में विफल।
डेमियन येरिक जूल

106

आधार 3 स्ट्रिंग में बदलने के लिए इटोआ का उपयोग करें । अंतिम ट्रिट ड्रॉप करें और वापस बेस 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
@cshemby मैं वास्तव में नहीं जानता था कि itoaएक मनमाना आधार का उपयोग कर सकता है। यदि आप एक पूरी तरह से काम कर रहे कार्यान्वयन का उपयोग कर itoaमैं upvote हूँ।
मिस्टिक जूल

2
कार्यान्वयन में शामिल होंगे /और %... :-)
R .. GitHub STOP की मदद से IC

2
@R .. तो 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

FWIW, आप AndreyT0x55555556 द्वारा प्रस्तावित चाल का उपयोग करने के लिए एक समान चाल का उपयोग करके आसानी से एक गुणन फ़ंक्शन को लागू कर सकते हैं :

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

5
ओरेकल का जिक्र होने पर भी प्रश्न को c नहीं, बल्कि SQL को टैग किया जाता है।
बिटमैस्क

3
यह वास्तव में एसक्यूएल की तरह नहीं दिखता है!
मूओइप जूल

64
यदि आप उपयोग कर सकते हैं ++: आप बस उपयोग क्यों नहीं कर रहे हैं /=?
क्वाटर्ज़

5
@bitmask: ++भी एक शॉर्टकट है: के लिए num = num + 1
क्वाटर्ज़

4
@bitmask हाँ, लेकिन +=अंत में इसके लिए एक शॉर्टकट है num = num + 1
क्वाटर्ज़

44

यह सेतुन कंप्यूटर पर आसानी से संभव है

पूर्णांक को 3 से विभाजित करने के लिए, दाईं ओर 1 स्थान पर शिफ्ट करें

मुझे यकीन नहीं है कि इस तरह के एक मंच पर एक अनुरूप सी कंपाइलर को लागू करना कड़ाई से संभव है या नहीं। हमें नियमों को थोड़ा लंबा खींचना पड़ सकता है, जैसे "कम से कम 8 बिट्स" की व्याख्या "-128 से +127 तक कम से कम पूर्णांक रखने में सक्षम"।


8
समस्या यह है कि आपके पास सी में "1 स्थान पर शिफ्ट राइट" ऑपरेटर नहीं है। >>ऑपरेटर "डिवीजन बाय 2 ^ एन" ऑपरेटर है, अर्थात यह अंकगणितीय के संदर्भ में निर्दिष्ट है, मशीन प्रतिनिधित्व नहीं।
आर .. गिटहब स्टॉप हेल्पिंग ICE

सेटुन कंप्यूटर शब्द के किसी भी अर्थ में बाइनरी नहीं है, इसलिए निर्देश सेट निश्चित रूप से अलग होना चाहिए। हालांकि, मैं उस कंप्यूटर के संचालन से बिल्कुल परिचित नहीं हूं, इसलिए मैं पुष्टि नहीं कर सकता कि क्या प्रतिक्रिया वास्तव में सही है - लेकिन कम से कम यह समझ में आता है - और अत्यधिक मूल है। +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 + ...

अब हमें बस इतना करना है कि इन बिट्स को एक साथ स्थानांतरित कर दिया जाए! ऊप्स! हम हालांकि जोड़ नहीं सकते, इसलिए इसके बजाय, हमें बिट-वार ऑपरेटरों का उपयोग करके एक ऐड फंक्शन लिखना होगा! यदि आप बिट-वार ऑपरेटर्स से परिचित हैं, तो मेरा समाधान काफी सरल दिखना चाहिए ... लेकिन सिर्फ मामले में आप नहीं हैं, मैं अंत में एक उदाहरण के माध्यम से चलूँगा।

ध्यान देने वाली एक और बात यह है कि पहले मैं ३० के द्वारा छोड़ दिया गया था! यह सुनिश्चित करने के लिए है कि अंश गोल-गोल न हो जाएं।

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 के इनपुट के लिए काम करता है? 1/4, 1/16, ... सभी 3 के लिए 0 लौटाते हैं, इसलिए 0 पर राशि होगी, लेकिन 3/3 = 1.
हैच - SOverflow

1
तर्क अच्छा है लेकिन कार्यान्वयन समस्याग्रस्त है। की श्रृंखला सन्निकटन n/3हमेशा से कम होती है, n/3जिसका अर्थ है कि किसी भी n=3kपरिणाम के लिए k-1इसके बजाय होगा k
जियान

@ अल्बर्ट, यह पहला तरीका था जो मैंने कोशिश की थी, एक दो रूपों के साथ, लेकिन वे सभी कुछ निश्चित संख्याओं पर समान रूप से 3 या समान रूप से विभाज्य से 2 (भिन्नता के आधार पर) में विफल रहे। तो मैंने कुछ और सीधा करने की कोशिश की। मैं इस दृष्टिकोण के कार्यान्वयन को देखना चाहता हूं जो काम करता है, यह देखने के लिए कि मैं कहां से पेंच कर रहा हूं।
हैचेट -

@hatchet, प्रश्न बंद है, इसलिए मैं एक नया उत्तर पोस्ट नहीं कर सकता, लेकिन विचार द्विआधारी div को लागू करना है। मुझे इसे देखना आसान होना चाहिए।
Xyand


25

32-बिट संख्या को 3 से विभाजित करने के लिए इसे गुणा कर सकते हैं 0x55555556और फिर 64 बिट परिणाम के ऊपरी 32 बिट्स ले सकते हैं।

अब बस इतना करना बाकी है कि बिट ऑपरेशंस और शिफ्ट्स का उपयोग करके गुणा को लागू करें ...


1
धीमी विभाजनों के आसपास काम करने के लिए यह एक सामान्य संकलक चाल है। लेकिन आपको शायद कुछ फिक्स अप करने की आवश्यकता है, क्योंकि 0x55555556 / 2 ** 32 बिल्कुल 1/3 नहीं है।
कोडइन्चौसोस

multiply it। निषिद्ध *ऑपरेटर का उपयोग करने का मतलब यह नहीं होगा ?
20

8
@ ल्युसिकुबल: नहीं, यह नहीं होगा। यही कारण है कि मैंने कहा: "अब यह सब करना बाकी है, बिट ऑपरेशंस और शिफ्ट्स का उपयोग करके गुणा लागू करना है "
AnT

18

फिर भी एक और उपाय। यह एक इंट के न्यूनतम मूल्य को छोड़कर सभी ints (निगेटिव इन्टस सहित) को संभालना चाहिए, जिसे हार्ड कोडिंग अपवाद के रूप में नियंत्रित करने की आवश्यकता होगी। यह मूल रूप से घटाव द्वारा विभाजन करता है लेकिन केवल बिट ऑपरेटरों (शिफ्ट्स, एक्सआर, और पूरक) का उपयोग करता है। तेज गति के लिए, यह 3 * (2 की घटती हुई शक्तियों) को घटाता है। C # में, यह इन DivideBy3 कॉलों में से लगभग 444 प्रति मिलीसेकंड (1,000,000 विभाजनों के लिए 2.2 सेकंड) को निष्पादित करता है, इसलिए भयावह रूप से धीमी गति से नहीं, लेकिन जहां साधारण x / 3 के रूप में तेजी से पास नहीं है। तुलना करके, Coodey का अच्छा समाधान इस से लगभग 5 गुना तेज है।

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;
}

यह c # है क्योंकि यही मेरे पास था, लेकिन c से मतभेद मामूली होना चाहिए।


आपको केवल एक बार उप को घटाने की कोशिश करने की आवश्यकता है, क्योंकि यदि आप इसे दो बार घटा सकते हैं तो आप इसे पिछले पुनरावृत्ति को घटा सकते हैं जब यह दो गुना बड़ा था।
नील

करता है (a >= sub)एक घटाव के रूप में गिनती?
नील

@ नील, मुझे लगता है कि आप सही हो सकते हैं। जबकि आंतरिक लूप के दूसरे पुनरावृत्ति से एक अनावश्यक तुलना की बचत, एक साधारण के साथ प्रतिस्थापित किया जा सकता है। के बारे में> = घटाव होने के नाते ... मुझे उम्मीद है कि नहीं, क्योंकि इससे यह काफी मुश्किल हो जाएगा! मैं आपकी बात देख रहा हूं, लेकिन मुझे लगता है कि मैं उस तरफ झुकूंगा जो कहता है कि = = घटाव के रूप में नहीं गिना जाता है।
हैचेट - SOverflow

@ नील, मैंने वह बदलाव किया, जिसने समय को आधे में काट दिया (अनावश्यक रूप से नकारात्मक को भी बचाया)।
हैचेट -

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;

(मैं निश्चित रूप से संक्षिप्तता के लिए कार्यक्रम के कुछ छोड़ दिया है।) यदि प्रोग्रामर यह सब टाइप करने के लिए थक गया, मुझे यकीन है कि वह या वह उसके लिए इसे उत्पन्न करने के लिए एक अलग कार्यक्रम लिख सकता है। मुझे एक निश्चित ऑपरेटर के बारे में पता होना चाहिए /, इससे उसकी नौकरी सरल हो जाएगी।


8
आप Dictionary<number, number>बार-बार के ifबयानों के बजाय उपयोग कर सकते हैं ताकि आपके पास O(1)समय जटिलता हो सके!
पीटर ओल्सन

@EnesUnal नहीं, संख्या बढ़ने पर समय रैखिक रूप से बढ़ता है, क्योंकि यदि बयानों को अधिक से अधिक करना है।
पीटर ओल्सन


@PeterOlson, EresUnal अगर मैंने एक स्विच स्टेटमेंट का उपयोग किया है, तो यह O (1) :-) होगा
thedttts

या आप एक सरणी उत्पन्न कर सकते हैं, और गतिशील प्रोग्रामिंग का उपयोग कर सकते हैं। यदि 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और स्ट्रिंग समंजन द्वारा धोखा देने के लिए होगा ?

उदाहरण के लिए, Javacript में आप कर सकते हैं

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

7

PHP में BC गणित का उपयोग करना :

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

MySQL (यह Oracle से एक साक्षात्कार है)

> 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);
}

जहाँ fmamath.h हेडर में परिभाषित एक मानक लाइब्रेरी फ़ंक्शन है ।


यह न -ही *ऑपरेटर का उपयोग कैसे कर रहा है ?
बिटमैस्क

4

इस दृष्टिकोण (c #) के बारे में कैसे?

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;
    }

यह C टैग किया गया है और पहले दिन से ही ऐसा है।
लंडिन

4

मुझे लगता है कि सही उत्तर है:

मैं मूल ऑपरेशन करने के लिए एक मूल ऑपरेटर का उपयोग क्यों नहीं करूंगा?


क्योंकि वे जानना चाहते हैं कि क्या आप जानते हैं कि प्रोसेसर आंतरिक रूप से कैसे काम करता है ... एक गणित ऑपरेटर का उपयोग करके अंत में उपरोक्त उत्तर के समान एक ऑपरेशन किया जाएगा।
RaptorX

या वे यह जानना चाहते हैं कि क्या आप एक बेकार समस्या को पहचान सकते हैं।
ग्रेगोइरे

1
@Gregoire मैं सहमत हूं, इस तरह के कार्यान्वयन को करने के लिए एबोलुस्लेटी की आवश्यकता नहीं है, बिट इन कॉमेरियल लाइफ (ओर्काले) बेकार आवश्यकताओं को पूरा करने से बचने के लिए यह आवश्यक है: सही उत्तर है: "यह बिल्कुल भी समझ में नहीं आता है, ढीले पैसे क्यों उसके लिए? ")
अलेक्सविएन

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


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)
}

हालांकि यह उपयोग करता है +, लेकिन किसी को पहले से ही बिटवाइज़ ऑप द्वारा लागू होता है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.