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 xhalkanın belirsizine atayacağız R. Şimdi, ne zaman xGAP'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_ringbir tamsayı alır ve onu ilgili halka elemanına eşler. Her ikili algoritma, bir dönüşüm kullanarak gerçekleştirir 1ikili katılacağını bir değiştirilir x^nnerede nnumara 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_intsbir 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));
PCLMULQDQCLMUL uzantısından gelen 6 bayt x86 komutudur. Maalesef önceden ayarlanmış x86 komutları hakkındaki bilgilerimden dolayı hak kazandım (PEXT/PDEPBu konuda), bu yüzden burada sadece yorum olarak bırakacağım.