47
\$\begingroup\$

You goal is to implement the operation of XOR (carryless) multiplication, defined below, in as few bytes as possible.

If we think of bitwise XOR (^) as binary addition without carrying

   101   5
^ 1001   9
  ----  
  1100  12
  
  5^9=12

we can perform XOR multiplication @ by doing binary long-multiplication but doing the adding step without carrying as bitwise XOR ^.

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

(For mathematicians, this is multiplication in the polynomial ring \$F_2[x]\$, identifying polynomials with natural numbers by evaluating at \$x=2\$ as a polynomial over \$\mathbb Z\$.)

XOR multiplication commutes a@b=b@a, associates (a@b)@c=a@(b@c), and distributes over bitwise XOR a@(b^c)=(a@b)^(a@c). In fact, it is the unique such operation that matches multiplication a@b=a*b whenever a and b are powers of 2 like 1,2,4,8....

Requirements

Take two non-negative integers as input and output or print their XOR-product. This should be as numbers or their decimal string representations, not their binary expansions. Fewest bytes wins.

Don't worry about integer overflows.

Here are some test cases formatted as 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
\$\endgroup\$
5
  • 17
    \$\begingroup\$ This is better known as "carry-less multiplication", which you might want to add the the question title, and with high probability the smallest entry is the 6-byte x86 instruction PCLMULQDQ from the CLMUL extension. Unfortunately I got downvoted for my knowledge of the x86 instruction set before (Related to PEXT/PDEP), so I'm going to just leave this as a comment here. \$\endgroup\$ Commented May 16, 2015 at 16:14
  • \$\begingroup\$ @IwillnotexistIdonotexist Thanks for the note, it's nice to have a name to Google. \$\endgroup\$
    – xnor
    Commented May 16, 2015 at 21:04
  • \$\begingroup\$ If that above is not "xor" you have to call in a different way as xorc or xornc ... It is not xor \$\endgroup\$
    – user58988
    Commented Dec 4, 2016 at 9:33
  • 2
    \$\begingroup\$ @RosLuP It's not xor, it's xor multiplication. \$\endgroup\$
    – xnor
    Commented Dec 4, 2016 at 9:39
  • \$\begingroup\$ @boboquack Actually, I believe nimber multiplication is different. For instance, it has 2*2==3. Both of these distribute over nim addition, but the one in this challenge matches multiplication on powers of 2, whereas the nimber on matches only on 2^(2^n). \$\endgroup\$
    – xnor
    Commented Dec 4, 2016 at 23:39

36 Answers 36

36
\$\begingroup\$

x86 machine code: 7 bytes

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

Only two instructions. pclmulqdq does the heavy lifting, it literally implements that type of xor-multiplication. ret to make it a callable function, hopefully satisfying the requirement of "outputting" the result (in the return value, xmm0). Putting integer arguments in xmm args is a bit unusual, but I hope you'll forgive me.

\$\endgroup\$
7
  • 1
    \$\begingroup\$ Using a built in operation sounds like cheating... \$\endgroup\$
    – CJ Dennis
    Commented May 17, 2015 at 12:59
  • 4
    \$\begingroup\$ @CJDennis On the Standard Loopholes meta post, there is no consensus on whether it should be banned or not. There are 44 votes for banning, 31 votes against. \$\endgroup\$
    – isaacg
    Commented May 18, 2015 at 4:45
  • 1
    \$\begingroup\$ @isaacg I'm really not trying to be nit-picky but the wording of the question is: Your goal is to implement the operation of XOR (carryless) multiplication. Does this answer "implement" the operation itself or simply call someone else's function? All the other answers do the hard work themselves, often within a few bytes of this answer. I think they're all a lot cleverer and deserve upvoting more than this one. \$\endgroup\$
    – CJ Dennis
    Commented May 18, 2015 at 5:22
  • 11
    \$\begingroup\$ I don't really feel able to blame an answer if the question is so trivial it is implemented directly by a common CPU, one can hardly get any lower level than that. It isn't particularly interesting or memorable but does seem a valid answer, so +1. \$\endgroup\$
    – Vality
    Commented May 18, 2015 at 9:03
  • 15
    \$\begingroup\$ I have no problem with a built-in being used to solve this -- otherwise, I wouldn't have know such a built-in exists. \$\endgroup\$
    – xnor
    Commented May 21, 2015 at 4:12
15
\$\begingroup\$

Z80, 11 bytes

B7 CB 32 30 01 B3 C8 CB 23 18 F6   

The code is called as a function. a and b are in D and E (the order doesn't matter) and the answer is stored in A when the code returns (there are no I/O functions).

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

It produces the correct results for all test input except 63@63 which returns 85 because all the registers are 8-bit and 1365 mod 256 = 85 (integer overflow).

\$\endgroup\$
9
\$\begingroup\$

Pyth, 13 12 bytes

uxyG*HQjvz2Z

Demonstration.

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.

Old version, 13 bytes:

xFm*vz.&Q^2dQ

Demonstration.

\$\endgroup\$
2
  • \$\begingroup\$ I guess then there isn't a good way to avoid vz in taking two integer inputs. \$\endgroup\$
    – xnor
    Commented May 15, 2015 at 20:51
  • \$\begingroup\$ @xnor No, unfortunately. \$\endgroup\$
    – isaacg
    Commented May 15, 2015 at 20:54
9
\$\begingroup\$

C, 44 38 bytes

Thanks to nimi, we now use recursion for 6 fewer bytes!

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

We define a function f which takes a, b.

This can be called like:

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

Which outputs:

13 @ 14 = 70

Try the test cases online!

\$\endgroup\$
5
  • 1
    \$\begingroup\$ Why not a recursive version f(a,b)={return(b)?(b&1)*a^f(2*a,b/2):0;}? \$\endgroup\$
    – nimi
    Commented May 15, 2015 at 22:40
  • \$\begingroup\$ @nimi Ah, clever! I knew there was a way to get rid of that dumb parameter. I've got 38 bytes now. Thanks! \$\endgroup\$
    – BrainSteel
    Commented May 16, 2015 at 0:14
  • 1
    \$\begingroup\$ Struck out 44 is still regular 44. :( \$\endgroup\$
    – Alex A.
    Commented May 16, 2015 at 1:35
  • \$\begingroup\$ The inputs are non-negative so you can replace (b&1) with b%2 to save a further two bytes since % has the same left-to-right precedence level as *. \$\endgroup\$
    – CL-
    Commented May 16, 2015 at 8:23
  • 1
    \$\begingroup\$ Suggest b%2 instead of (b&1) \$\endgroup\$
    – ceilingcat
    Commented Sep 21, 2020 at 22:04
8
\$\begingroup\$

J, 14 bytes

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

Usage:

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

Explanation (reading mostly from right to left; u and v stand for arbitrary functions):

  • u&.#: applies u to the vectors of the binary representations of the input numbers then turn the result back to an integer (u&.v == v_inverse(u(v(input_1), v(input_2))))
  • */ products (*) of inputs in the Descartes product (/) of the two binary vector
  • v(u@) apply u to v (to the Descartes product)
  • u/. apply u to every anti-diagonal of the Descartes product (anti-diagonals represent the 1st, 2nd, ... digits in the binary representation)
  • ~:/ reduce (/) an anti-diagonal with XOR operation (~:)
  • The last step is generating an integer from the binary vector which the first point takes care of.

Try it online here.

\$\endgroup\$
8
\$\begingroup\$

CJam, 14 13 bytes

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

How it works:

We first get the long multiplication results and then work our way up starting from the bottom two pairs.

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

Try it online here

\$\endgroup\$
0
8
\$\begingroup\$

Python 2, 35 bytes

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

Call like f(13, 14). I think most languages with a similar construct will converge on something like this.

\$\endgroup\$
6
\$\begingroup\$

Java, 62

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

Expanded

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));
    }
}
\$\endgroup\$
3
  • 1
    \$\begingroup\$ Is there a reason you prefer for(;i<32;) to while(i<32)? They're the same length, but the second seems like a more natural way to write it. \$\endgroup\$
    – JohnE
    Commented May 15, 2015 at 23:18
  • 2
    \$\begingroup\$ @JohnE I would guess that i++ was originally in the for loop and got golfed to its present position. Since while isn't any smaller there's no reason to change it. \$\endgroup\$
    – CJ Dennis
    Commented May 16, 2015 at 13:10
  • \$\begingroup\$ I know it's been 7 years, but (y>>i)%2 can be y>>i&1 for -2 bytes and (x,y)-> can be a currying lambda x->y-> for an additional -1 byte: try it online. \$\endgroup\$ Commented Sep 24, 2022 at 21:42
4
\$\begingroup\$

Perl - 35 Bytes

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

Counting the command line option as one. Input is taken from STDIN, space separated.

Sample usage:

$ 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
\$\endgroup\$
4
\$\begingroup\$

Jelly, 12 bytes

BJ’2*U×B{×^/

Try it online!

How it works

BJ’2*U×B{×^/ - Main link. Takes a on the left, b on the right
B            - Binary representation of a
 J           - Replace each element with its index
  ’          - Decrement
   2*        - Raise each to the power 2
     U       - Reverse
       B{    - Yield the binary representation of a
      ×      - Multiply the bits by the powers
         ×   - Multiply b by the results
          ^/ - Reduce by XOR
\$\endgroup\$
4
\$\begingroup\$

Jelly, 7 6 bytes

Bæc/ḂḄ

Try it online!

-1 thanks to Jonathan Allan

Takes a list of [a, b]. (The dyadic equivalent is the very fun-looking BæcḂḄɓB.)

B         Convert a and b to their binary digits,
 æc/      and convolve them.
    Ḃ     Take each mod 2
     Ḅ    and convert from binary.
\$\endgroup\$
3
  • 1
    \$\begingroup\$ Hah nice, was just about to post BæcB}ḂḄ \$\endgroup\$ Commented Sep 23, 2022 at 23:56
  • 1
    \$\begingroup\$ That's what I had too, but then I realized BæcḂḄɓB had more Bs :P \$\endgroup\$ Commented Sep 23, 2022 at 23:59
  • 1
    \$\begingroup\$ 6 bytes as a monadic Link accepting a list of integers (works for any non-empty list). EDIT: sorry, less Bs :p \$\endgroup\$ Commented Sep 24, 2022 at 0:41
3
\$\begingroup\$

Haskell, 50 bytes

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

A translation of @BrainSteel's C answer. Usage example:

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]
\$\endgroup\$
3
\$\begingroup\$

Julia, 35 33 30 bytes

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

This creates a recursive function f which takes two integers and returns the XOR product of the inputs.

Ungolfed:

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

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

Saved a couple bytes with encouragement from Sp3000!

\$\endgroup\$
3
\$\begingroup\$

MMIX, 28 bytes (7 instrs)

(jelly xxd)

00000000: e3020000 7aff0001 c60202ff 3f000001  ẉ£¡¡z”¡¢İ££”?¡¡¢
00000010: 37010101 5b00fffc f8030000           7¢¢¢[¡”‘ẏ¤¡¡

Disassembly:

clmul   SETL $2,0       // r = 0
0H      ZSOD $255,$0,$1 // loop: t = a odd? b : 0
        XOR  $2,$2,$255 // r ^= t
        SRU  $0,$0,1    // a >>= 1
        SLU  $1,$1,1    // b <<= 1
        PBNZ $0,0B      // iflikely(a) goto loop
        POP  3,0        // return r

You could get a 128-bit answer out of this with about three more instructions, I think.

\$\endgroup\$
2
\$\begingroup\$

Python 2, 104 91 78 66 bytes

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

Take the bits of b in reverse order, ending before you hit the '0b' at the start of the string. Multiply each one by a and xor with the total, then left-shift a. Then print the total.

\$\endgroup\$
2
\$\begingroup\$

Mathematica, 40 bytes

BitXor@@(#2BitAnd[#,2^Range[0,Log2@#]])&
\$\endgroup\$
2
2
\$\begingroup\$

Go, 63 bytes

func f(a,b uint)uint{if a<1{return 0};return a%2*b^f(a/2,b*2)}

Complete example:

http://play.golang.org/p/-ngNOnJGyM

\$\endgroup\$
2
\$\begingroup\$

GAP, 368 Bytes

For mathematicians, this is multiplication in the polynomial ring F_2[x], identifying polynomials with natural numbers by evaluating at x=2 as a polynomial over Z.

Sure, let's do that! (this is only loosly golfed, the point was more to move into F2[x] and do the calculations more than any attempt at being a winning entry)

Here's the code

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;

Here's the ungolfed code with explanation:

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;

Okay, so first off, we create the univariate polynomial ring over the field F2 and call it R. Note that GF(2) is F2 in GAP.

R:=PolynomialRing(GF(2));

Next, we are going to assign the GAP variable x to the indeterminate of the ring R. Now, whenever I say x in GAP, the system will know I am talking about the indeterminate of the ring R.

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

Next, we have two functions, which are inverse maps of each other. These maps are both onto, but they are not structure preserving, so I couldn't figure out a better way to implement them in GAP. There almost certainly is a better way, if you know it, please comment!

The first map, to_ring takes an integer and maps it to its corresponding ring element. It does this by using a conversion to binary algorithm, where every 1 that would appear in binary is replaced by an x^n where n is the appropriate power that 2 would take if the number was indeed binary.

    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;

The next function reverses this. to_ints takes a ring element and maps it to its corresponding integer. I do this by getting a list of the coefficients of the polynomial and for each nonzero coefficient, the result is increased by 2^n, in the same way that we would convert binary to decimal.

    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;

For the final step, we call these functions. We take the two integer inputs, convert them into elements in the ring R, then multiply these elements together, and send the product back to the integers.

return to_ints( to_ring(i)*to_ring(j));
\$\endgroup\$
2
\$\begingroup\$

ARM Thumb-2 (NEON), 6 bytes

Eat my Thumb, pclmullqlqdqdqdqdq. ARM has boring builtins, too!

ef80 0e01 4770

Assembly code:

        .syntax unified
        .arch armv7-a
        .fpu neon
        .thumb
        .globl xormul_boring_neon
        .thumb_func
xormul_boring_neon:
        // q0[0-8] = d0[0-8] @ d1[0-8]
        vmull.p8 q0, d0, d1
        bx       lr

Input: two 8-bit values in d0 and d1 Output: the 16-bit product in q0

This actually multiplies 8 packed bytes together.

ARM Thumb-2, manual, 14 bytes

Ok, to make up for it, here is a fully scalar version which does a 32x32 multiply with a 32-bit result.

2300 0849 bf28 4043 0040 d1fa 4770

Assembly code:

        .syntax unified
        .arch armv6t2
        .thumb
        .globl xormul_scalar
        .thumb_func
        // r3 <- r0 @ r1
xormul_scalar:
        // acc <- 0
        movs    r3, #0
.Lloop:
        // test each bit in y by using lsrs carry-out
        lsrs    r1, r1, #1
        // was the bit set?
        it      cs
        // if so, acc ^= x
        eorcs   r3, r0
        // shift x left
        lsls    r0, r0, #1
        // loop while x is non zero
        bne     .Lloop
.Lend:
        // return in r3
        bx      lr

Equivalent C code:

uint32_t xormul_scalar(uint32_t x, uint32_t y)
{
    uint32_t acc = 0;
    do {
        if (y & 1)
            acc ^= x;
        y >>= 1;
    } while ((x <<= 1));
    return acc;
}

The numbers to be multiplied are in r0 and r1, and the result is in r3.

It is a fairly basic shift and xor loop.

Yet another case of lsls and lsrs being far too useful than they deserve to be.

Try it online! (sorta): demo in Travis

\$\endgroup\$
2
\$\begingroup\$

Jelly, 16 bytes

Ḥ⁴BL’¤Ð¡U×"⁴B¤^/

Try it online!

\$\endgroup\$
2
\$\begingroup\$

05AB1E, 8 bytes

Îbv·yI*^

Try it online or verify all test cases.

Explanation:

Î         # Push 0 and the first input
 b        # Convert it to a binary string
  v       # Loop over each bit `y` of this string:
   ·      #  Double the current integer
    y     #  Push bit `y`
     I*   #  Multiply it by the second input
       ^  #  Bitwise-XOR the two together
          # (after the loop, the result is output implicitly)
\$\endgroup\$
2
\$\begingroup\$

Wolfram Language (Mathematica) v13.3+, 38 bytes

(F=2~FiniteField~+##;F@#2F@#)@"Index"&

Input [a, b].

Version 13.3 introduced FiniteField, which is nicer to golf with than FiniteFields`GF. Getting an integer out of a FiniteFieldElement is still a little verbose, though.

test cases

\$\endgroup\$
1
\$\begingroup\$

Ruby, 76 75 73 bytes

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

Ruby, 60 bytes (function only, no I/O)

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

Dart, 34 32 bytes

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

Straight-forward recursive implementation.

\$\endgroup\$
1
\$\begingroup\$

gnuplot, 29 bytes

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

just like in Dart (see above)

\$\endgroup\$
1
\$\begingroup\$

GNU Assembler(x86_64 Mac OS X), 97 bytes

This is a proper function that can be called from C:

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

& can be tested with this C program:

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

Note that on Mac OS X, you have to use clang -x c to compile it as C & not C++.

For linux(if I remember right), the code would be 95 bytes:

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

Strangely enough, this version is actually longer than defining the function in inline assembly, but that one was longer than the pure C solution we already have, so I decided to try assembly.

edit

If it's counted by the assembled size(excluding any labels &c.), then it's

x86_64 Assembler, 22 bytes:

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
\$\endgroup\$
1
  • \$\begingroup\$ I'd think you'd measure assembly languages by their compiled form though. \$\endgroup\$
    – Nissa
    Commented Jun 6, 2018 at 16:21
1
\$\begingroup\$

R, 53 bytes

f=function(x,y)`if`(y,bitwXor(x*y%%2,2*f(x,y%/%2)),0)

Try it online!

\$\endgroup\$
1
\$\begingroup\$

JavaScript (Node.js), 29 bytes

f=(x,y)=>x&&f(x>>1,y)*2^x%2*y

Try it online!

Similar to https://codegolf.stackexchange.com/a/50246/

\$\endgroup\$
1
\$\begingroup\$

Vyxal, 9 bytes

₌0b(dn⁰*꘍

Try it Online!

Ports the 05AB1E answer, so go upvote that too

Explained

₌0b(dn⁰*꘍
₌0b       # Push 0 and the binary of the first input
   (      # to each bit:
    d     # double the top of the stack
     n⁰*  # multiply the bit by the second input
        ꘍ # and bit xor
\$\endgroup\$
1
\$\begingroup\$

Pyt, 37 bytes

ɓąƖĐŁř⁻↔2⇹^**ĐŁ2%¬?ŕ:ŕÁ0á;ĐŁ`ŕʁ⊻ĐŁ⁻łŕ

Try it online!

Takes two integers a,b on separate lines

The following is worked on a=13, b=14

Code Stack Description
ɓąƖ [1,1,0,1] Pushes the ąrray corresponding to the ɓits of 13
ĐŁř⁻↔2⇹^* [8,4,0,1] Converts array to corresponding powers of 2
* [112,56,0,14] Multiplies the array by 14
ĐŁ2%¬? [112,56,0,14], True does the array have an even length?
ŕ [112,56,0,14] If so, pop the boolean check
:ŕÁ0á (skipped in this run) Otherwise, append a 0 to the array
;ĐŁ`ŕʁ⊻ĐŁ⁻ł [70], 0 ʁeduce the array using XOR () while the Łength of the resulting array is greater than 1
ŕ [70] ŕemove the 0; implicit print
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.