XOR गुणन


33

आपका लक्ष्य XOR ( लापरवाह ) गुणन के संचालन को लागू करना है, जो नीचे परिभाषित है, संभव के रूप में कुछ बाइट्स में।

अगर हम बिटवाइर XOR ( ^) को बिना ले जाने के बाइनरी जोड़ के रूप में सोचते हैं

   101   5
^ 1001   9
  ----  
  1100  12

  5^9=12

हम @बाइनरी लॉन्ग- गुणा करके एक्सओआर गुणा कर सकते हैं लेकिन बिटवाइज एक्सओआर के रूप में बिना जोड़कर कदम उठा सकते हैं ^

     1110  14
   @ 1101  13
    -----
     1110
       0
   1110
^ 1110 
  ------
  1000110  70

  14@13=70

(गणितज्ञों के लिए, यह बहुपद की अंगूठी में गुणा है F_2[x], x=2Z पर एक बहुपद के रूप में मूल्यांकन करके प्राकृतिक संख्या के साथ बहुपद की पहचान करना )

XOR गुणन बिटकॉइन XOR पर कमिट a@b=b@a, सहयोगी (a@b)@c=a@(b@c)और वितरित करता है a@(b^c)=(a@b)^(a@c)। वास्तव में, यह अनोखा ऐसा ऑपरेशन है जो a@b=a*bजब भी गुणन से मेल खाता है aऔर bजैसी शक्तियां 2हैं 1,2,4,8...

आवश्यकताएँ

इनपुट और आउटपुट के रूप में दो गैर-नकारात्मक पूर्णांक लें या उनके XOR- उत्पाद को प्रिंट करें। यह संख्याओं या उनके दशमलव स्ट्रिंग अभ्यावेदन के रूप में होना चाहिए, न कि उनके द्विआधारी विस्तार से। सबसे कम बाइट्स जीतता है।

पूर्णांक overflows के बारे में चिंता मत करो।

यहाँ कुछ परीक्षण मामलों को स्वरूपित किया गया है a b a@b

0 1 0
1 2 2
9 0 0
6 1 6
3 3 5
2 5 10
7 9 63
13 11 127
5 17 85
14 13 70
19 1 19
63 63 1365

13
इसे "कैरी-लेस गुणा" के रूप में जाना जाता है, जिसे आप प्रश्न शीर्षक जोड़ना चाह सकते हैं, और उच्च संभावना के साथ सबसे छोटी प्रविष्टि PCLMULQDQCLMUL एक्सटेंशन से 6-बाइट x86 निर्देश है। दुर्भाग्य से मैं पहले (संबंधित PEXT/PDEP) के x86 निर्देश के अपने ज्ञान के लिए नीच हो गया , इसलिए मैं इसे केवल एक टिप्पणी के रूप में यहाँ छोड़ने जा रहा हूं।
इविलनोटिक्सिस्ट इडोनोटेक्सिस्ट

@IwillnotexistIdonotexist नोट के लिए धन्यवाद, Google के लिए नाम रखना अच्छा है।
xnor

यदि वह ऊपर "xor" नहीं है, तो आपको अलग तरीके से xorc या xornc के रूप में कॉल करना होगा ... यह xor नहीं है
RosLuP

1
@RosLuP यह xor नहीं है, यह xor गुणन है।
xnor

@boboquack वास्तव में, मेरा मानना ​​है कि निम्बर गुणा अलग है। उदाहरण के लिए, इसमें 2 * 2 == 3 है। ये दोनों निम जोड़ पर वितरित करते हैं, लेकिन इस चुनौती में से एक 2 की शक्तियों पर गुणा से मेल खाता है, जबकि निंबर केवल 2 ^ (2 ^ n) पर मेल खाता है।
xnor

जवाबों:


36

x86 मशीन कोड: 7 बाइट्स

66 0F 3A 44 C1 00 C3  pclmulqdq xmm0, xmm1, 0 \ ret

केवल दो निर्देश। pclmulqdqहेवी लिफ्टिंग करता है, यह शाब्दिक रूप से एक्सोर-गुणा का प्रकार लागू करता है। retइसे कॉल करने योग्य फ़ंक्शन बनाने के लिए, उम्मीद है कि परिणाम "आउटपुट" की आवश्यकता को संतुष्ट करें (वापसी मूल्य में xmm0)। आर्ग में पूर्णांक तर्क देना xmmथोड़ा असामान्य है, लेकिन मुझे आशा है कि आप मुझे क्षमा करेंगे।


1
बिल्ट इन ऑपरेशन का उपयोग करते हुए लगता है ...
सीजे डेनिस

4
@CJDennis स्टैंडर्ड लोफॉल्स मेटा पोस्ट पर, इस पर कोई सहमति नहीं है कि इसे प्रतिबंधित किया जाना चाहिए या नहीं। प्रतिबंध लगाने के लिए 44 वोट हैं, 31 के खिलाफ वोट।
isaacg

1
@ आईआईएसएसीजी मैं वास्तव में नाइट-पिकी होने की कोशिश नहीं कर रहा हूं, लेकिन सवाल का शब्द है: आपका लक्ष्य एक्सओआर (कैरीलेस) गुणा के संचालन को लागू करना है । क्या यह उत्तर ऑपरेशन को "कार्यान्वित" करता है या बस किसी और के फ़ंक्शन को कॉल करता है? अन्य सभी उत्तर स्वयं कड़ी मेहनत करते हैं, अक्सर इस उत्तर के कुछ बाइट्स के भीतर। मुझे लगता है कि वे सभी बहुत चतुर हैं और इस एक से अधिक उत्थान के लायक हैं।
सीजे डेनिस

8
मैं वास्तव में एक जवाब को दोष देने में सक्षम महसूस नहीं करता हूं यदि प्रश्न इतना तुच्छ है तो इसे सीधे एक सामान्य सीपीयू द्वारा लागू किया जाता है, कोई भी इससे कम स्तर प्राप्त कर सकता है। यह विशेष रूप से दिलचस्प या यादगार नहीं है, लेकिन एक वैध जवाब लगता है, इसलिए +1।
वैधता

9
मुझे इसे बनाने में कोई समस्या नहीं है - इसका उपयोग करने के लिए - अन्यथा, मुझे इस तरह के अंतर्निहित अस्तित्व का पता नहीं होगा।
xnor

14

Z80, 11 बाइट्स

B7 CB 32 30 01 B3 C8 CB 23 18 F6   

कोड को एक फ़ंक्शन के रूप में कहा जाता है। aऔर bमें हैं Dऔर E(क्रम आवश्यक नहीं है) और जवाब में संग्रहित है Aजब कोड रिटर्न (कोई आई / ओ कार्यों देखते हैं)।

B7      XOR A     //  A^=A (A=0)
CB 32   SRL D     //    CARRY = lsb(D), D>>=1, ZERO = D==0
30 01   JR NC, 1  //    jump 1 byte if not CARRY
B3      XOR E     //      A^=E, ZERO = A==0
C8      RET Z     //    return if ZERO
CB 23   SLA E     //    E<<=1
18 F6   JR -10    //    jump -10 bytes

यह सभी परीक्षण इनपुट के लिए सही परिणाम 63@63देता है, सिवाय इसके कि रिटर्न 85क्योंकि सभी रजिस्टर 8-बिट और 1365 मॉड 256 = 85 (पूर्णांक ओवरफ़्लो) हैं।


10

सी, 44 38 बाइट्स

निम्मी के लिए धन्यवाद, अब हम 6 कम बाइट्स के लिए पुनरावृत्ति का उपयोग करते हैं!

f(a,b){return b?(b&1)*a^f(a*2,b/2):0;}

हम एक समारोह को परिभाषित fजो लेता है a, b

इसे इस तरह कहा जा सकता है:

printf("%d @ %d = %d\n", 13, 14, f(13, 14));

कौन से आउटपुट:

13 @ 14 = 70

ऑनलाइन परीक्षण मामलों की कोशिश करो !


1
क्यों नहीं एक पुनरावर्ती संस्करण f(a,b)={return(b)?(b&1)*a^f(2*a,b/2):0;}?
नीमी

@ नमि आह, चतुर! मुझे पता था कि उस गूंगे पैरामीटर से छुटकारा पाने का एक तरीका है। मुझे अब 38 बाइट्स मिल गए हैं। धन्यवाद!
ब्रेनसटेल

1
स्ट्रक आउट 44 अभी भी नियमित 44 है। :(
ए। ए

आदानों गैर नकारात्मक ताकि आप बदल सकते हैं कर रहे हैं (b&1)के साथ b%2के बाद से एक और दो बाइट्स को बचाने के लिए %के रूप में ही बाएँ से सही पूर्वता स्तर है *
सीएल-

9

पायथ, 13 12 बाइट्स

uxyG*HQjvz2Z

प्रदर्शन।

uxyG*HQjvz2Z
                  Implicit:
                  z = input()
                  Q = eval(input())
                  Z = 0

       jvz2       The first input, written in base 2, like so: [1, 0, 1, ...
u      jvz2Z      Reduce over the binary representation, starting with 0.
 x                XOR of
  yG              Twice the previous number
    *HQ           and the second input times the current bit.

पुराना संस्करण, 13 बाइट्स:

xFm*vz.&Q^2dQ

प्रदर्शन।


मुझे लगता है कि vzदो पूर्णांक इनपुट लेने से बचने का एक अच्छा तरीका नहीं है ।
xnor

@xnor नहीं, दुर्भाग्य से।
isaacg

8

CJam, 14 13 बाइट्स

q~2bf*{\2*^}*

यह कैसे काम करता है :

हम पहले लंबे गुणा परिणाम प्राप्त करते हैं और फिर नीचे दो जोड़े से शुरू करके अपना रास्ता बनाते हैं।

q~                e# Eval the input. This puts the two numbers on stack
  2b              e# Convert the second number to binary
    f*            e# Multiply each bit of second number with the first number
                  e# This leaves an array with the candidates to be added in the long
                  e# multiplication step
      {    }*     e# Reduce on these candidates. Starting from the bottom
       \2*        e# Bit shift the lower candidate
          ^       e# XOR each other and continue

इसे यहाँ ऑनलाइन आज़माएँ


7

जे, 14 बाइट्स

*/(~://.@)&.#:

उपयोग:

   5 (*/(~://.@)&.#:) 17     NB. enclosing brackets are optional
85

स्पष्टीकरण (ज्यादातर बाएं से दाएं पढ़ना; uऔर vमनमाने कार्यों के लिए खड़ा होना):

  • u&.#:uइनपुट संख्याओं के बाइनरी अभ्यावेदन के वैक्टर पर लागू होता है और फिर परिणाम को पूर्णांक पर वापस लाएँ ( u&.v == v_inverse(u(v(input_1), v(input_2))))
  • */उत्पादों ( *डेसकार्टेस उत्पाद में आदानों (के) /दो द्विआधारी वेक्टर के)
  • v(u@)लागू uकरने के लिए v(डेसकार्टेस उत्पाद के लिए)
  • u/.uडेसकार्टेस उत्पाद के प्रत्येक विरोधी-विकर्ण पर लागू होता है (एंटी-विकर्ण द्विआधारी प्रतिनिधित्व में 1, 2, ... अंकों का प्रतिनिधित्व करते हैं)
  • ~:/कम ( /) XOR ऑपरेशन के साथ एक विरोधी-विकर्ण ( ~:)
  • अंतिम चरण बाइनरी वेक्टर से एक पूर्णांक उत्पन्न कर रहा है, जिसका पहला बिंदु ध्यान रखता है।

इसे यहाँ ऑनलाइन आज़माएँ।


5

पायथन 2, 35 बाइट्स

f=lambda m,n:n and n%2*m^f(2*m,n/2)

जैसे बुलाओ f(13, 14)। मुझे लगता है कि एक समान निर्माण वाली अधिकांश भाषाएं कुछ इस तरह अभिसरण होंगी।


4

जावा, ६२

(x,y)->{int r=0,i=0;for(;i<32;)r^=x*((y>>i)%2)<<i++;return r;}

विस्तारित

class XORMultiplication {
    public static void main(String[] args) {
        IntBinaryOperator f = (x, y) -> {
                    int r = 0, i = 0;
                    for (; i < 32;) {
                        r ^= x * ((y >> i) % 2) << i++;
                    }
                    return r;
                };
        System.out.println(f.applyAsInt(14, 13));
    }
}

1
क्या कोई कारण है जिसे आप पसंद करते for(;i<32;)हैं while(i<32)? वे एक ही लंबाई के हैं, लेकिन दूसरा इसे लिखने के लिए एक अधिक प्राकृतिक तरीके की तरह लगता है।
जॉन 18

1
@ जॉनी मुझे लगता है कि i++मूल रूप से forलूप में था और अपनी वर्तमान स्थिति पर पहुंच गया। चूंकि whileकोई छोटा नहीं है इसलिए इसे बदलने का कोई कारण नहीं है।
सीजे डेनिस

3

हास्केल, 50 बाइट्स

import Data.Bits
_#0=0
a#b=b.&.1*a`xor`2*a#div b 2

@ BrainSteel के C उत्तर का अनुवाद। उपयोग उदाहरण:

map (uncurry (#)) [(0,1),(1,2),(9,0),(6,1),(3,3),(2,5),(7,9),(13,11),(5,17),(14,13),(19,1),(63,63)]
[0,2,0,6,5,10,63,127,85,70,19,1365]

3

पर्ल - 35 बाइट्स

#!perl -p
$\^=$`>>$_&1&&$'<<$_ for-/ /..31}{

एक के रूप में कमांड लाइन विकल्प की गिनती। इनपुट से लिया गया है STDIN, अंतरिक्ष अलग।

नमूना उपयोग:

$ echo 13 11 | perl xormul.pl
127
$ echo 5 17 | perl xormul.pl
85
$ echo 14 13 | perl xormul.pl
70
$ echo 19 1 | perl xormul.pl
19
$ echo 63 63 | perl xormul.pl
1365

3

जूलिया, 35 33 30 बाइट्स

f(a,b)=b%2*a$(b>0&&f(2a,b÷2))

यह एक पुनरावर्ती फ़ंक्शन बनाता है fजो दो पूर्णांक लेता है और इनपुट के XOR उत्पाद को लौटाता है।

Ungolfed:

function f(a, b)
    # Bitwise XOR : $
    # Short-circuit AND : &&

    b % 2 * a $ (b > 0 && f(2a, b ÷ 2))
end

Sp3000 से प्रोत्साहन के साथ एक युगल बाइट्स बचा लिया!


2

पायथन 2, 104 91 78 66 बाइट्स

def y(a,b,c=0):
 for _ in bin(b)[:1:-1]:c^=int(_)*a;a<<=1
 print c

स्ट्रिंग के प्रारंभ में bहिट करने '0b'से पहले समाप्त होने वाले बिट्स को रिवर्स ऑर्डर में लें । प्रत्येक को एक-एक करके aऔर xorकुल के साथ गुणा करें , फिर बाईं-पाली a। फिर कुल प्रिंट करें।



2

जीएपी , 368 बाइट्स

गणितज्ञों के लिए, यह बहुपद अंगूठी F_2 [x] में गुणा है, x = 2 पर Z के रूप में बहुपद के रूप में मूल्यांकन करके बहुपदों की पहचान प्राकृतिक संख्याओं के साथ।

ज़रूर, चलो ऐसा करते हैं! (यह केवल शिथिल रूप से गढ़ा गया है, यह बिंदु एफ 2 [x] में जाने के लिए और एक जीत प्रविष्टि होने पर किसी भी प्रयास से अधिक गणना करने के लिए अधिक था)

यहाँ कोड है

f:=function(i,j)R:=PolynomialRing(GF(2));x:=IndeterminatesOfPolynomialRing(R);x:=x[1];a:=function(i)local n,r;r:=0*x;while not i=0 do n:=0;while 2^n<=i do n:=n+1;od;n:=n-1;r:=r+x^n;i:=i-2^n;od;return r;end;b:=function(r)local c,i,n;i:=0;n:=0;for c in CoefficientsOfUnivariatePolynomial(r) do if c=Z(2)^0 then n:=n+2^i;fi;i:=i+1;od;return n;end;return b(a(i)*a(j));end;

यहाँ स्पष्टीकरण के साथ अपुष्ट कोड है:

xor_multiplication:=function(i,j)           
    R:=PolynomialRing(GF(2));
    x:=IndeterminatesOfPolynomialRing(R);
    x:=x[1];
    to_ring:=function(i)
        local n,r; 
        r:=0*x;
        while not i=0 do
            n:=0;
            while 2^n<=i do
                n:=n+1;
            od;
            n:=n-1;
            r:=r+x^n;
            i:=i-2^n;
        od;
        return r;
    end;
    to_ints:=function(r)
        local c,i,n;
        i:=0;n:=0;
        for c in CoefficientsOfUnivariatePolynomial(r) do
            if c=Z(2)^0 then
                n:=n+2^i;
            fi;
            i:=i+1;
        od;
        return n;
    end;
    return to_ints( to_ring(i)*to_ring(j));
end;

ठीक है, इसलिए सबसे पहले, हम क्षेत्र एफ 2 के ऊपर एकतरफा बहुपद अंगूठी बनाते हैं और इसे कॉल करते हैं R। ध्यान दें कि GAP में GF(2)F 2 है।

R:=PolynomialRing(GF(2));

इसके बाद, हम GAP वैरिएबल xको रिंग के अनिश्चित में असाइन करने जा रहे हैं R। अब, जब भी मैं xGAP में कहता हूं , तो सिस्टम को पता चल जाएगा कि मैं रिंग के अनिश्चित होने के बारे में बात कर रहा हूं R

x:=IndeterminatesOfPolynomialRing(R);
x:=x[1];

अगला, हमारे दो कार्य हैं, जो एक दूसरे के उल्टे नक्शे हैं। ये नक्शे दोनों पर हैं, लेकिन वे संरचना को संरक्षित नहीं कर रहे हैं, इसलिए मैं उन्हें GAP में लागू करने का बेहतर तरीका नहीं समझ सका। लगभग निश्चित रूप से एक बेहतर तरीका है, यदि आप इसे जानते हैं, तो कृपया टिप्पणी करें!

पहला नक्शा, to_ringएक पूर्णांक लेता है और इसे अपने संबंधित रिंग तत्व में मैप करता है। यह द्विआधारी एल्गोरिथ्म है, जहां हर एक रूपांतरण का उपयोग करके इस करता है 1कि द्विआधारी में दिखाई देता है एक ने ले ली है x^n, जहां nउचित शक्ति है कि 2 यदि संख्या वास्तव में द्विआधारी था ले जाएगा है।

    to_ring:=function(i)
        local n,r; 
        r:=0*x;                 # initiate r to the zero element of R
        while not i=0 do        # this is a modified binary algorithm
            n:=0;
            while 2^n<=i do
                n:=n+1;
            od;
            n:=n-1;
            r:=r+x^n;
            i:=i-2^n;
        od;
        return r;
    end;

अगला फ़ंक्शन इसे उलट देता है। to_intsएक रिंग एलिमेंट लेता है और इसे अपने संबंधित पूर्णांक पर मैप करता है। मैं बहुपद के गुणांक और प्रत्येक गैर-गुणांक गुणांक की एक सूची प्राप्त करके ऐसा करता हूं, परिणाम 2 ^ n तक बढ़ जाता है, उसी तरह जैसे कि हम बाइनरी को दशमलव में बदल देंगे।

    to_ints:=function(r)
        local c,i,n;
        i:=0;n:=0;
        for c in CoefficientsOfUnivariatePolynomial(r) do
            if c=Z(2)^0 then          

                 # ^-- Right here you'll notice that the Z(2) is basically '1' in GF(2). So Z(2)^0 ~ 1 and Z(2)*0 ~ 0  
                 # effectively, this line checks for nonzero coefficients

                n:=n+2^i;
            fi;
            i:=i+1;
        od;
        return n;
    end;

अंतिम चरण के लिए, हम इन कार्यों को कहते हैं। हम दो पूर्णांक इनपुट लेते हैं, उन्हें रिंग में तत्वों में परिवर्तित करते हैं R, फिर इन तत्वों को एक साथ गुणा करते हैं, और उत्पाद को पूर्णांक में वापस भेजते हैं।

return to_ints( to_ring(i)*to_ring(j));

1

रूबी, 76 75 73 बाइट्स

a,b=$*.map{|x|x.to_i}
o=0
while(b>0)
o^=a&-(b&1)
a<<=1
b>>=1
end
puts(o)

रूबी, 60 बाइट्स (केवल फ़ंक्शन, नहीं I / O)

def t(a,b)
o=0
while(b>0)
o^=a&-(b&1)
a<<=1
b>>=1
end
t
end


1

डार्ट, 34 32 बाइट्स

m(a,b)=>a<1?0:a%2*b^m(a~/2,b*2);

सीधे-आगे पुनरावर्ती कार्यान्वयन।



1

जीएनयू असेंबलर (x86_64 मैक ओएस एक्स), 97 बाइट्स

यह एक उचित कार्य है जिसे C से बुलाया जा सकता है:

.text
.globl _f
_f:
movq %rdi,%xmm0;movq %rsi,%xmm1;pclmulqdq $0,%xmm1,%xmm0;movq %xmm0,%rax;ret

और इस सी कार्यक्रम के साथ परीक्षण किया जा सकता है:

#include <stdio.h>
int f(int a, int b);
#define p(a,b) printf("%d %d %d\n", a, b, f(a, b))
int main(void)
{
    p(0,1);
    p(1,2);
    p(9,0);
    p(6,1);
    p(3,3);
    p(2,5);
    p(7,9);
    p(13,11);
    p(5,17);
    p(14,13);
    p(19,1);
    p(63,63);
}

ध्यान दें कि मैक ओएस एक्स पर, आपको clang -x cइसे C & Not C ++ के रूप में संकलित करने के लिए उपयोग करना होगा।

लिनक्स के लिए (यदि मुझे सही याद है), तो कोड 95 बाइट होगा:

.text
.globl f
f:
movq %rdi,%xmm0;movq %rsi,%xmm1;pclmulqdq $0,%xmm1,%xmm0;movq %xmm0,%rax;ret

अजीब तरह से, यह संस्करण वास्तव में इनलाइन असेंबली में फ़ंक्शन को परिभाषित करने से अधिक लंबा है, लेकिन यह कि हमारे पास पहले से मौजूद शुद्ध सी समाधान की तुलना में लंबा था, इसलिए मैंने असेंबली की कोशिश करने का फैसला किया।

संपादित करें

यदि यह इकट्ठे आकार (किसी भी लेबल और सी को छोड़कर) द्वारा गिना जाता है, तो यह है

x86_64 असेंबलर, 22 बाइट्स:

0:  66 48 0f 6e c7          movq         %rdi,  %xmm0
5:  66 48 0f 6e ce          movq         %rsi,  %xmm1
a:  66 0f 3a 44 c1 00       pclmullqlqdq $0,    %xmm1,%xmm0
10: 66 48 0f 7e c0          movq         %xmm0, %rax
15: c3                      ret

मुझे लगता है कि आप उनके संकलित रूप से विधानसभा भाषाओं को मापेंगे।
निसा

0

golflua 68

x,y=I.r("*n","*n")r=0~@i=0,31r=B.x(r,x*B.ls(B.rs(y,i)%2,i+1))$w(r/2)

मूलतः Ypnypn के जावा उत्तर के रूप में एक ही बिटशफ्टिंग करता है , लेकिन सही ढंग से काम करने के लिए अंत में 2 से भाग देने की आवश्यकता प्रतीत होती है। मूल्यों में स्टड के रूप में ले जाता है, नीचे उदाहरण

> 14 13 
70
> 19 1 
19
> 5 17 
85

0

सीलोन, 90 बाइट्स

alias I=>Integer;I x(I a,I b)=>[for(i in 0:64)if(b.get(i))a*2^i].fold(0)((y,z)=>y.xor(z));

गुणा: यह सिर्फ एल्गोरिथ्म वर्णन किया गया है aद्वारा 2^iजहाँ भी iवीं बिट में सेट किया गया है b, और उन सब को एक साथ जोड़ना XOR का उपयोग कर। ओवररेट्स 0:64क्योंकि जेवीएम पर चलने के दौरान सीलोन में इंटेगर 64-बिट के होते हैं (जावास्क्रिप्ट के रूप में चलने पर कम, लेकिन फिर b.get(i)झूठे होते हैं)।

प्रारूपित:

alias I => Integer;

I x(I a, I b) =>
      [
        for (i in 0:64)
            if (b.get(i))
                a * 2^i
      ].fold(0)((y, z) => y.xor(z));

उर्फ यहां एक मात्र बाइट सुरक्षित है।


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