तुलना संचालकों के बिना C या C ++ में दो पूर्णांकों की तुलना करें


13

सबसे छोटे प्रोग्राम का निर्माण करें जिसमें दो हस्ताक्षर किए गए पूर्णांकों को इनपुट के रूप में (स्टड के माध्यम से या तर्कों के रूप में) लिया जाता है और 3 अलग-अलग आउटपुट प्रदर्शित करता है जो इस बात पर निर्भर करता है कि पहला नंबर (1) से बड़ा है, (2) दूसरे से छोटा है, या (3) के बराबर है नंबर।

कैच

आप अपने प्रोग्राम में निम्न में से किसी का उपयोग नहीं कर सकते हैं:

  • मानक तुलना ऑपरेटरों: <, >, <=, >=, ==, !=
  • अलग से कोई लाइब्रेरी फ़ाइल conio, stdioया iostream
  • कोई भी गैर- ASCII या गैर-मुद्रण योग्य ASCII वर्ण।

विजेता

कम से कम वर्णों वाला कार्यक्रम जीतता है।


मुझे लगता है कि लाइब्रेरी फ़ाइल abs को शामिल किए बिना चीजों का उपयोग करना (क्योंकि कंपाइलर इसे वैसे भी जानता है) या तो अनुमति नहीं है?
मार्टिन एंडर

1
@ मार्टिनबटनर हाँ, यह एक सही धारणा होगी। :)
ग्रोव

5
C (++) पर प्रतिबंध क्यों? यदि ऐसा इसलिए है क्योंकि आप सी के मूल प्रकारों की अप्रत्यक्षता के बावजूद पोर्टेबल होना चाहते हैं तो आपको यह बताना चाहिए। यदि यह एक मनमाना प्रतिबंध है, तो आपको पता होना चाहिए कि इस साइट पर एक भाषा के लिए मनमाना प्रतिबंध अलोकप्रिय हैं।
पीटर टेलर

8
@PeterTaylor यह चुनौती का हिस्सा है। यह एक बहुत ही अलग ballgame होगा अगर सवाल भाषा-अज्ञेय था। इसे C / C ++ में प्रतिबंधित करने से समस्या के समीप आने पर उपयोग की जाने वाली रणनीतियाँ बदल जाती हैं। मैं अधिक लोगों द्वारा भागीदारी को बढ़ावा देने के लिए अधिकांश भाषाओं के लिए खुले रहने के लिए प्रश्नों की आवश्यकता को पहचानता हूं, लेकिन इस विशेष समस्या में C / C ++ और उनके विशिष्ट ऑपरेटरों और विधियों के लिए प्रतिबंध चुनौती का एक अभिन्न अंग है।
ग्रोव

1
@EvilTeach हाँ; यदि प्रश्न में कुछ भी स्पष्ट रूप से निषिद्ध नहीं है, तो इसकी अनुमति है।
ग्रोव

जवाबों:


2

53 बाइट्स

main(a,b){scanf("%d%d",&a,&b);printf("%ld",0l+a-b);}

केवल आउटपुट का पहला वर्ण प्रासंगिक है। तीन अलग-अलग आउटपुट हैं:

  1. '-' अगर बी> ए
  2. '0' अगर a == बी
  3. किसी भी अन्य चरित्र अगर एक> बी

यह सभी प्लेटफार्मों पर int के पूर्ण इनपुट रेंज के लिए काम करता है जहां sizeof (long)> sizeof (int)।

संपादित करें: केस 3 को प्रिंट करने के लिए एक अतिरिक्त वर्ण की लागत होती है, इसके बजाय '+' को प्रिंट करें:

main(a,b){scanf("%d%d",&a,&b);printf("%+ld",0l+a-b);}

6

शायद मुझे नियमों में कुछ याद आ रहा है, लेकिन ...

81 बाइट्स

main(a,b){scanf("%d%d",&a,&b);long long l=a;l-=b;printf("%lld%d",--l>>63,l>>63);}

Ouputs 00अगर a > b, -10अगर a == b, और -1-1यदि a < b


इस तरह के कोड के रूप में आम है, सी गारंटी नहीं है कि यह काम करता है। long long64 से अधिक बिट्स intहो सकते हैं , बड़े हो सकते हैं इसलिए आप अतिप्रवाह कर सकते हैं, सही शिफ्टिंग नकारात्मक मानों का परिणाम कार्यान्वयन है। बहुत अधिक सभी सी-व्युत्पन्न उत्तरों में समान मुद्दे हैं।
यन वर्नियर

1
@ यान्वर्नियर: समझ गया। मैं अनुमान लगा रहा हूं कि 100% मूर्खतापूर्ण समाधान एक राक्षस होगा, क्योंकि केवल एक चीज जो हम सुरक्षित रूप से कर सकते हैं (यानी शिफ्टिंग या अतिप्रवाह के बिना) थोड़ी चक्करदार है, और ऐसा करने के लिए सुरक्षित रूप से हमें ऑपरेंड की लंबाई निर्धारित करने की आवश्यकता होगी sizeof
सीओटीओ

6

90 बाइट्स

यदि हम उपयोग कर सकते हैं stdio, तो तुलना करने के लिए इसकी प्रारूपण क्षमताओं का उपयोग क्यों न करें?

main(a,b){scanf("%d%d",&a,&b);snprintf(&a,2,"%d",b-a);a&=63;putchar(51-!(a-45)-!!(a-48));}

ASCII- संगत एन्कोडिंग और थोड़ा-सा अंतकरण मानता है।

72 बाइट्स

मरीजों को शून्य की ओर गोल किया जाता है, लेकिन दाएं-शिफ्ट्स (व्यवहार में) "गोल नीचे" होते हैं। यह एक मृत जीव है।

main(a,b){scanf("%d%d",&a,&b);a-=b;putchar(a?a|=1,a/2-(a>>1)?60:62:61);}

65 79 बाइट्स

नकारात्मक संख्याओं की एक और विशिष्ट संपत्ति यह है कि वे नकारात्मक मोडुलो का उत्पादन करते हैं। यह एक पूर्णांक प्रतिनिधित्व पर निर्भर नहीं करता है; यह भी मेरे 8 बिट अतिरिक्त 127 टोस्टर पर काम करता है! ओह, और जब से हम उपयोग कर सकते हैं conio, तो दो बाइट्स के साथ क्यों नहीं बचाएं putch? अब, अगर मैं केवल TurboC की अपनी प्रति पा सकता था ...

main(a,b){scanf("%d%d",&a,&b);long long d=a;d-=b;putch(d?d|=1,d%2-1?60:62:61);}

संपादित करें : संभालने वाले बड़े अंतर की long longतुलना में व्यापक है int


मुझे पूरा यकीन है कि आपको %dअपने scanfदो पूर्णांकों को स्पष्ट रूप से पार्स करने के लिए एस के बीच एक सीमांकक की आवश्यकता है । हालांकि अच्छा विचार है!
मार्टिन एंडर

1
@ मर्टिन: ठीक है, यह जीसीसी के साथ काम करता है , लेकिन मुझे यकीन नहीं है कि यह बोना फाइड है।
एलएल

मेरा क्या मतलब है, आप इनपुट a = 1, b = 23और के बीच अंतर कैसे करते हैं a = 12, b = 3। क्या आपको 123किसी भी स्थिति में एसटीडीआईएन डालने की आवश्यकता नहीं होगी ?
मार्टिन एंडर

1
जैसा मैंने कहा था, यह काम करने लगता है ( इनपुट के साथ 1 23और 12 3)।
एलए

2
ओह, आप इनपुट में रिक्त स्थान शामिल करते हैं। हाँ, मुझे आश्चर्य नहीं है कि वास्तव में काम करता है।
मार्टिन एंडर

5

64 61 अक्षर

main(a,b){scanf("%d%d",&a,&b);for(a-=b;a/2;a/=2);putchar(a);}

क्रमशः, -1, 0, और 1 के चरित्र मानों को क्रमशः से कम, के बराबर या उससे अधिक प्रिंट करता है।

यह कार्यान्वयन bप्रकार के होने intऔर सीमा के बाहर के इनपुट के लिए अपरिभाषित व्यवहार पर निर्भर करता INT_MIN / 2है INT_MAX / 2। उन प्लेटफार्मों पर जहां हस्ताक्षरित अतिप्रवाह चारों ओर घूमता है, चाहे 2-पूरक (मूल रूप से उन सभी) या साइन-परिमाण, यह वैध जोड़े के 25% के लिए विफल हो जाएगा int। दिलचस्प है (मुझे वैसे भी), यह उन प्लेटफार्मों पर सही ढंग से काम करेगा जहां हस्ताक्षर किए गए अतिप्रवाह संतृप्त हैं।


a-bओवरफ्लो होने पर यह काम नहीं करेगा ।
डेनिस

अफसोस की बात है कि यह सच है, लेकिन मैं तुलनात्मक ऑपरेटरों के बिना इससे बचने के लिए किसी भी मंच अज्ञेय के बारे में नहीं सोच सकता था। प्रश्न इनपुट की एक श्रेणी निर्दिष्ट नहीं करता है जिसके लिए परिणाम मान्य होना चाहिए। इस उत्तर की गारंटी मानक द्वारा सभी इनपुट प्लेटफार्मों के बीच -(2^14)और सभी इनपुट के लिए काम करने के लिए दी गई 2^14 - 1है, और यह संभवतः अधिकांश प्लेटफार्मों पर एक बड़ी रेंज के लिए काम करेगा। इस बिंदु पर अन्य सभी उत्तर प्रकार के आकार, प्रकार के सापेक्ष आकार, या प्रतिनिधित्व के बारे में धारणा बनाते हैं।
laindir

प्रश्न कहता है कि दो हस्ताक्षरित पूर्णांक इनपुट के रूप में हैं , इसलिए मैं कहूंगा कि इसे सभी जोड़ों के लिए काम करना है। main(a,b)पहले से ही अपरिभाषित व्यवहार है, इसलिए जवाब में से कोई भी काम करने की गारंटी नहीं है। कोई बात नहीं।
डेनिस

आप अपरिभाषित व्यवहार के बारे में बिल्कुल सही हैं, इसलिए मेरा कार्यान्वयन वास्तव में मानक द्वारा कुछ भी गारंटी नहीं देता है। मैं एक नोट जोड़ूंगा जो यह दर्शाता है कि इसकी सीमाएँ क्या हैं।
laindir

4

 ५ ९    ५४ अक्षर

54 संकलक के साथ एक संकलक जैसे gcc जो इस पर गंजा नहीं है main(x,y):

main(x,y){scanf("%d%d",&x,&y);y-=x;putchar(y>>31|!y);}

59 वर्ण अन्यथा:

main(){int x,y;scanf("%d%d",&x,&y);y-=x;putchar(y>>31|!y);}

आउटपुट:

  • ASCII कोड 0x00 यदि x <y
  • ASCII कोड 0xFF यदि x> y है
  • ASCII कोड 0x01 यदि x == y

1
मैं आपको आश्वासन दे सकता हूं, main(x,y)जीसीसी में काम करता है, इसलिए अपने चरित्र की गिनती से उन 5 बाइट्स को छोड़ने के लिए स्वतंत्र महसूस करें।
मार्टिन एंडर

मुख्य (x, y) मेरे gcc पर काम नहीं करता है। शायद एक संकलक विकल्प की आवश्यकता है। लेकिन आप मुख्य (x, y) को x; मुख्य (y) से बदल सकते हैं।
फ्लोरियन एफ

3

66 102 बाइट्स

main(a,b,c,d,e){scanf("%d %d",&a,&b);e=1<<31;c=a&e;d=b&e;putchar(a-b?c&~d?48:d&~c?49:a-b&e?48:49:50);}

STDIN और प्रिंट्स 0(a <b), 1(a> b) या 2(a == b) से पूर्णांक पढ़ता है ।

संपादित करें: अब यह उन अंतरों के लिए भी काम करना चाहिए जो 32-बिट पूर्णांक में फिट होने के लिए बहुत बड़े हैं। मुझे यकीन है कि नेस्टेड टर्नरी को कुछ अधिक बिट-जादू के साथ छोटा किया जा सकता है।


अगर मैं गलत हूं तो मुझे सुधारो, लेकिन मैं तुम्हारी आंतरिक गुत्थी में एक <0 देख रहा हूं।
ओवरएक्टर

@overactor तय
मार्टिन

3

52 बाइट्स

अफसोस की बात है कि यह केवल सकारात्मक पूर्णांक के लिए काम करता है, लेकिन मुझे लगा कि विशुद्ध रूप से अंकगणितीय ऑपरेटरों का उपयोग करने की अवधारणा दिलचस्प थी:

main(a,b){scanf("%d%d",&a,&b);putchar(b%a/b-a%b/a);}

आउटपुट:

  • ASCII कोड 0xFF: b से कम है
  • ASCII कोड 0x00: b के बराबर
  • ASCII कोड 0x01: b से बड़ा

यदि आप केवल सकारात्मक पूर्णांक के लिए जा रहे हैं, putchar(a/b-b/a)तो बहुत कम है।
डेनिस

@ डेनिस जो (50,1) और (51,1) के लिए उदाहरण के लिए अलग-अलग आउटपुट पैदा करता है। लेकिन मैं हालांकि थोड़ा छोटा था।
डिजिटल ट्रॉमा

1
हां, ठीक से नहीं सोच रहा था ...
डेनिस

2

66 बाइट्स

main(a,b){scanf("%d%d",&a,&b);putchar((0l+b-a>>63)-(0l+a-b>>63));}

बाइट 0x00 को प्रिंट करता है a == b, 0x01 को अगर a < bऔर 0xff को अगर a > b

चूंकि [मेरे] कार्यक्रम में गैर-एएससीआईआई या गैर-मुद्रण योग्य एएससीआईआई चरित्र और यदि प्रश्न में कुछ भी स्पष्ट रूप से निषिद्ध नहीं है, तो इसकी अनुमति है , आउटपुट में अनपेक्षित वर्ण पूरी तरह से ठीक होना चाहिए।


मेरा पिछला संस्करण बहुत अच्छी तरह से अतिप्रवाह को संभाल नहीं पाया। यह x64 लिनक्स पर काम करता है, जहां long64-बिट्स है।
डेनिस

2

87 वर्ण

main(a,b,c){scanf("%d%d",&a,&b);c=1<<31;a+=c;b+=c;puts(a^b?(unsigned)a/b?">":"<":"=");}

अहस्ताक्षरित int में बदलने के लिए 2 ^ 31 चाल का उपयोग करना

विभाजन को बिना डेटा के ऊपरी बिट को संभालने के लिए अहस्ताक्षरित करना, हस्ताक्षर नहीं

^ ^ से XOR a और b का उपयोग करते हुए, जब वे इस रिटर्न के बराबर हों

नेस्टेड कंडीशंस (?) का उपयोग करके "<", ">", या "=" प्राप्त करने के लिए पुट () डालें


1

71 बाइट्स

main(x,y,z){scanf("%d%d",&x,&y);putchar((z=x-y)?(z&(z>>31))?50:49:51);}

http://ideone.com/uvXm6c


आपके विचारधारा में चारों ओर कोष्ठक हैं z=x-yऔर मुझे पूरा यकीन है कि वे आवश्यक हैं। आप जोड़ने के बजाय 49, 50` और 51सीधे का उपयोग करके दो वर्णों को भी सहेज सकते हैं 48
मार्टिन एंडर

असाइनमेंट में टर्नरी ऑपरेटर की तुलना में कम मिसाल है: en.cppreference.com/w/c/language/operator_precedence
मार्टिन

ऊपर दिया गया आपका कोड एक अर्धविराम याद कर रहा है, और यह -2000000000 2000000000पूर्णांक में अतिप्रवाह का कारण बनने वाले पूर्णांकों के किसी भी अन्य संयोजन के लिए विफल रहता है ।
सीओटीओ

1

68 अक्षर

int main(a,b){scanf("%d%d",&a,&b);putchar(a-b?((unsigned)a-b)>>31:2);}

ASCII वर्ण 1, 2 या 3 को क्रमशः से कम या अधिक से अधिक के लिए डालता है।


1
a-bओवरफ्लो होने पर यह काम नहीं करेगा ।
डेनिस

1

88 89 बाइट्स

main(a,b){scanf("%d%d",&a,&b);a+=1<<31;b+=1<<31;for(;a&&b;a--)b--;putchar(a?b?48:49:50);}

यह a और b को जोड़कर 1<<31( INT_MIN) शुरू होता है , ताकि 0 अब मेल खाता है INT_MIN। तब लूप्स घटता है और ए और बी हर लूप को 0 तक करता है, फिर 0, 1 या 2 प्रिंट करता है, इस पर निर्भर करता है कि क्या ए, बी या दोनों 0 हैं।

120 119 बाइट्स

main(a,b,c){scanf("%d%d",&a,&b);c=1<<31;a^=c;b^=c;for(c~=c;!c;c/=2)if(a&c^b&c){putchar(a?48:49);return;}putchar(50);}

यह सबसे छोटा समाधान नहीं है क्योंकि यह मेरे से बेहतर गोल्फर द्वारा थोड़ा नीचे गोल्फ हो सकता है। (या सिर्फ मुझसे अधिक सी के ज्ञान वाले लोग)

विचार प्रत्येक बिट को मुखौटा बनाने के लिए है, बाएं से शुरू होता है और असमानता की जांच करता है। बाकी तो खुद ही समझाना चाहिए। चूंकि नकारात्मक संख्या 1 बिट से शुरू होती हैं, इसलिए मैं पहले बिट के साथ पहले पलटा करता हूं a^=1<<31


मैं इस क्षण के लिए अपने समाधान का परीक्षण नहीं कर सकता, इसलिए गलतियों को इंगित करने के लिए स्वतंत्र महसूस करें।
ओवरएक्टर

पहले समाधान में कुछ समस्याएं हैं: 1. सुखी ;)स्माइली एक उदास );स्माइली होनी चाहिए । 2. a&bकेवल परीक्षण अगर aऔर bबिट में आम है; आप की जरूरत &&
डेनिस

@ डेनिस, आप सही कह रहे हैं, धन्यवाद।
ओवरएक्टर

1

मुझे लगता है कि मैं शॉर्ट कोड लिखने की कोशिश करने वाला नहीं हूं। मैं जो प्रयास करूँगा उसकी तुलना इस तरह से करना है कि C99 युक्ति प्रति पोर्टेबल हो।

int a, b;   // Let's assume these are initialized
int sign_a = a ? ((a|7)^2)%2 + ((a|7)^3)%2 : 0;

मॉडुलो ऑपरेटर साइन को संरक्षित करता है, लेकिन यह एक शून्य (नकारात्मक शून्य सहित) का उत्पादन कर सकता है, इसलिए हम सुनिश्चित करते हैं कि हमारे पास जांच करने के लिए एक अजीब और यहां तक ​​कि मूल्य दोनों हैं (यहां तक ​​कि यह जानने के बिना कि क्या हम पूरक का उपयोग कर रहे हैं)। अंकगणित संचालन ओवरफ्लो हो सकता है, लेकिन बिटवाइज़ नहीं होगा, और यह सुनिश्चित करने से कि बिट्स सेट और क्लियर हैं, हम अनजाने में अपनी संख्या को नकारात्मक शून्य या एक जाल मूल्य में परिवर्तित करने से बचते हैं। तथ्य यह है कि दो संचालन करने के लिए इतनी अजीब तरह से काम करने की आवश्यकता नहीं है, क्योंकि संभव जाल प्रतिनिधित्व एक अपरिवर्तित व्यवहार का कारण नहीं बनता है जब तक कि एक अंतराल में नहीं डाला जाता है। बिट 0 टॉगल के साथ ऑपरेशन करना यह सुनिश्चित करता है कि हमें एक गैर-शून्य शेष मिले। दोनों संकेतों के ज्ञान के साथ सशस्त्र, हम यह तय कर सकते हैं कि तुलना के साथ कैसे आगे बढ़ना है।

char result="\0<<>=<>>\0"[4+3*sign_a+sign_b]
if (!result) {   // signs matching means subtraction won't overflow
  int diff=a-b;
  int sign_diff=diff ? (diff|7^2)%2 + (diff|7^3)%2 : 0;
  result = ">=<"[1-sign_diff];
}

यह विधि कुछ में से एक हो सकती है जो पूर्णांक ऋणात्मक शून्य का चिह्न निकालने की अनुमति देती है। हम शून्य के लिए स्पष्ट रूप से जाँच करके हल करते हैं। यदि हम वास्तविक के लिए गोल्फ कर रहे थे, तो हम निश्चित रूप से दो शून्य की तुलना को घटाव भी कर सकते हैं।


1

सी char० चरस

a,b,c=1<<31;main(){scanf("%d%d",&a,&b);putchar(a^b?(a&c^b&c?a:a-b)&c?60:62:61);}

यह '<', '>' या '=' प्रिंट करता है, जैसा कि यह होना चाहिए।

C 63 वर्ण

एक नया तरीका:

a;main(b){scanf("%d%d",&a,&b);putchar(50+(0L+a-b>>42)+!(a-b));}

प्रिंट '1', '2' या '3'।


1

बिना stdio.h के 64 वर्णों में

a,b;main(){scanf("%d%d",&a,&b);puts((a-b)>>31?"<":a^b?">":"=");}

प्रिंट '>' अगर एक> बी, '<' अगर एक <b, '=' अगर एक == बी int अतिप्रवाह यूबी है। बस अतिप्रवाह मत करो।

// declare a and b as ints
a,b;

// defaults to int
main()
{
  scanf("%d%d",&a,&b);
   /*
    * (a-b)>>31 signbit of a-b
    * a^b a xor b -> 0 if they are equal
    */
  puts(((a-b)>>31) ? "<" : (a^b) ? ">" : "=");
}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.