GAP , 368 Bayt
Matematikçiler için bu, F_2 [x] polinom halkasında çarpma olup, x = 2'de Z üzerinden bir polinom olarak değerlendirilerek doğal sayılarla polinomları tanımlar.
Tabii, hadi yapalım şunu! (bu sadece loosly golfed olup, nokta F taşımak more 2 [x] 've kazanan bir giriş olarak herhangi bir girişim çok daha hesaplamaları yapmak)
İşte kod
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;
İşte açıklama ile ungolfed kodu:
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;
Tamam, ilk olarak, biz bu alanda F üzerinde tek değişkenli polinom halkası oluşturmak 2 ve diyoruz R
. GAP'ta GF(2)
F 2 olduğuna dikkat edin .
R:=PolynomialRing(GF(2));
Daha sonra, GAP değişkenini x
halkanın belirsizine atayacağız R
. Şimdi, ne zaman x
GAP'ta söylesem , sistem halkanın belirsizliğinden bahsettiğimi bilecek R
.
x:=IndeterminatesOfPolynomialRing(R);
x:=x[1];
Sonra, birbirimizin ters haritası olan iki işleve sahibiz. Bu haritalar her ikisinde de var, ancak bunlar yapıyı koruyamıyorlar, bu yüzden GAP'ta uygulamak için daha iyi bir yol bulamadım. Neredeyse kesinlikle daha iyi bir yol var, eğer biliyorsanız, lütfen yorum yapın!
İlk harita, to_ring
bir tamsayı alır ve onu ilgili halka elemanına eşler. Her ikili algoritma, bir dönüşüm kullanarak gerçekleştirir 1
ikili katılacağını bir değiştirilir x^n
nerede n
numara gerçekten de ikili olsaydı 2 alacağını uygun gücüdür.
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;
Bir sonraki işlev bunu tersine çevirir. to_ints
bir halka elemanı alır ve karşılık gelen tamsayıya eşler. Bunu, polinomun katsayılarının bir listesini alarak ve sıfır olmayan her katsayı için ikilik ondalık sayıya dönüştürdüğümüz gibi sonuç 2 ^ n artırıyor.
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;
Son adım için bu fonksiyonları çağırıyoruz. İki tamsayı girişini alıyoruz, bunları halkadaki elementlere dönüştürüyoruz R
, sonra bu elemanları bir araya çarpıyoruz ve ürünü tekrar tamsayılara gönderiyoruz.
return to_ints( to_ring(i)*to_ring(j));
PCLMULQDQ
CLMUL uzantısından gelen 6 bayt x86 komutudur. Maalesef önceden ayarlanmış x86 komutları hakkındaki bilgilerimden dolayı hak kazandım (PEXT/PDEP
Bu konuda), bu yüzden burada sadece yorum olarak bırakacağım.