GAP,368个字节
对于数学家来说,这是多项式环F_2 [x]中的乘法,通过将x = 2评估为Z上的多项式来识别具有自然数的多项式。
当然,让我们这样做吧!(这只是松懈的打球,比进入任何获胜的机会更重要的是进入F 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;
好的,首先,我们在字段F 2上创建单变量多项式环,并将其称为R
。注意,在GAP 中GF(2)
为F 2。
R:=PolynomialRing(GF(2));
接下来,我们将GAP变量分配给x
ring的不确定对象R
。现在,无论我x
在GAP中说什么,系统都会知道我在说环的不确定性R
。
x:=IndeterminatesOfPolynomialRing(R);
x:=x[1];
接下来,我们有两个函数,它们是彼此的逆映射。这些映射都可以使用,但是它们并不保留结构,因此我无法找到在GAP中实现它们的更好方法。几乎可以肯定有更好的方法,如果您知道,请发表评论!
第一个映射to_ring
取一个整数并将其映射到其相应的ring元素。它通过使用转换为二进制算法来做到这一点,其中1
二进制中出现的每一个都被替换为x^n
where 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
接受一个ring元素并将其映射到其对应的整数。我通过获取多项式系数的列表来完成此操作,对于每个非零系数,结果将增加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));
PCLMULQDQ
来自CLMUL扩展名的6字节x86指令。不幸的是,我之前不了解x86指令集(与有关PEXT/PDEP
),所以对此表示不满,因此我将在此处保留其注释。