GAP , 368 বাইট
গণিতবিদদের ক্ষেত্রে এটি বহুবর্ষীয় রিং এফ 3 [এক্স] এর গুণ, x = 2 এ জেডের ওপরে বহুবর্ষ হিসাবে মূল্যায়ন করে প্রাকৃতিক সংখ্যার সাথে বহুপদী চিহ্নিতকরণ is
অবশ্যই, এটি করা যাক! (এটি কেবলমাত্র স্বল্প গল্ফযুক্ত, পয়েন্টটি এফ 2 [এক্স] এ সরানো এবং বিজয়ী এন্ট্রি হওয়ার চেয়ে কোনও প্রচেষ্টা চেয়ে গণনাগুলি আরও বেশি করে করা হয়েছিল)
এখানে কোড
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
। নোট যে GF(2)
এফ 2 জিএপি হয়।
R:=PolynomialRing(GF(2));
এর পরে, আমরা জিপি ভেরিয়েবলটি x
রিংয়ের অনির্দিষ্টকালের জন্য নির্ধারণ করতে যাচ্ছি R
। এখন, আমি যখনই x
জিএপি-তে বলব , সিস্টেমটি জানতে পারবে আমি রিংয়ের অনির্দিষ্টকালের কথা বলছি R
।
x:=IndeterminatesOfPolynomialRing(R);
x:=x[1];
এর পরে, আমাদের দুটি ফাংশন রয়েছে যা একে অপরের বিপরীত মানচিত্র। এই মানচিত্রগুলি উভয়দিকেই রয়েছে, তবে সেগুলি সংরক্ষণের কাঠামো নয়, তাই এগুলিকে জিএপি প্রয়োগ করার আরও ভাল উপায় আমি খুঁজে বের করতে পারি না। প্রায় অবশ্যই একটি ভাল উপায় আছে, আপনি যদি এটি জানেন, মন্তব্য করুন!
প্রথম মানচিত্রটি 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
একটি রিং উপাদান নেয় এবং এটি সম্পর্কিত সংখ্যায় মানচিত্র করে maps আমি বহুবর্ষের সহগের একটি তালিকা পেয়ে এবং প্রতিটি ননজারো সহগের জন্য ফলাফলটি 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
সিএমএমএল এক্সটেনশান থেকে 6-বাইট x86 নির্দেশনা রয়েছে । দুর্ভাগ্যক্রমে আমি x86 নির্দেশাবলী সম্পর্কে আমার জ্ঞানের জন্য নিম্নচেতন হয়ে পড়েছি (সম্পর্কিতPEXT/PDEP
), সুতরাং আমি কেবল এখানে একটি মন্তব্য হিসাবে রেখে যাচ্ছি।