Codegolf - Определите Конечное Поле Gf(9)

  • Автор темы Pingas
  • Обновлено
  • 22, Oct 2024
  • #1

\$GF(9)\$ или \$GF(3^2)\$ — наименьший конечное поле чей порядок не является простым числом или степенью двойки. Конечные поля простого порядка не представляют особого интереса, а для \$GF(2^8)\$ (связь) и \$GF(2^{64})\$ (связь).

Испытание

Сначала определите девять элементов поля. Это должны быть различные целые числа от 0 до 255, или однобайтовые символы, которые представляют их кодовые точки. Укажите в ответе, какое представление вы выберете.

Затем реализуйте две бинарные операции: сложение и умножение, удовлетворяющие аксиомам поля:

  • Обе операции должны быть коммутативными и ассоциативными.
  • Сложение имеет единичный элемент \$0\$ и аддитивный обратный для каждого элемента.
  • Умножение имеет единичный элемент \$1\$ и обратный мультипликативный элемент для каждого элемента, кроме \$0\$.
  • Умножение распределяется по сложению: \$a·(b+c) = (a·b)+(a·c)\$

Сложение и умножение можно реализовать как функции или программы, принимающие два элемента поля и производящие один элемент поля.

Поскольку поле очень маленькое, вы можете полностью протестировать аксиомы, чтобы проверить свою реализацию или проверить таблицы сложения и умножения.

Математическая конструкция

Элементы \$GF(3^2)\$ можно интерпретировать как многочлены вида \$P(x)=a x+b\$ над \$GF(3)\$. (Сложение и умножение в \$GF(3)=\{0,1,2\}\$ являются стандартными целочисленными операциями по модулю 3.)

Тогда сложение в \$GF(3^2)\$ — это просто сложение двух многочленов. Умножение определяется произведением двух многочленов, уменьшенным по модулю многочлена степени 2, который равен нередуцируемый над \$GF(3)\$.

Пример

Сопоставление полиномов с целыми числами с \$n=3a+b\$ и использование неприводимого многочлена \$x^2+1\$ дает следующие таблицы сложения и умножения. Обратите внимание, что существуют и другие возможные изоморфизмы этих таблиц.

 +   0 1 2 3 4 5 6 7 8   *   0 1 2 3 4 5 6 7 8

------------------      ------------------
0 | 0 1 2 3 4 5 6 7 8   0 | 0 0 0 0 0 0 0 0 0
1 | 1 2 0 4 5 3 7 8 6   1 | 0 1 2 3 4 5 6 7 8
2 | 2 0 1 5 3 4 8 6 7   2 | 0 2 1 6 8 7 3 5 4
3 | 3 4 5 6 7 8 0 1 2   3 | 0 3 6 2 5 8 1 4 7
4 | 4 5 3 7 8 6 1 2 0   4 | 0 4 8 5 6 1 7 2 3
5 | 5 3 4 8 6 7 2 0 1   5 | 0 5 7 8 1 3 4 6 2
6 | 6 7 8 0 1 2 3 4 5   6 | 0 6 3 1 7 4 2 8 5
7 | 7 8 6 1 2 0 4 5 3   7 | 0 7 5 4 2 6 8 3 1
8 | 8 6 7 2 0 1 5 3 4   8 | 0 8 4 7 3 2 5 1 6
 

Проверка дистрибутивности с использованием приведенных выше таблиц:

$$5 · (2 + 7) = 5 · 6 = 4$$ $$(5 · 2) + (5 · 7) = 7 + 6 = 4$$

Обратите внимание, что простое сложение и умножение по модулю 9 не сработает.

Подсчет очков

Это кодекс гольфа. Ваш результат — это сумма байтов функций (или программ) сложения и умножения. Выигрывает наименьшее количество байтов.

#код-гольф #математика #полиномы #абстрактная алгебра #открытая функция

Pingas


Рег
22 Feb, 2011

Тем
65

Постов
186

Баллов
531
  • 26, Oct 2024
  • #2

Попробуйте онлайн!, 24 17 16 байт

Использует 0, 1, 2, 10, 11, 12, 20, 21, 22 в качестве 9 элементов поля.

Дополнение, 5 байт:

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 k=flip mod
q=l.k 30
l a=a-z+k 3 z where z=k 10 a
p=((q.k 98.k 300).).(*)
s=(q.).(+)
 

Попробуйте онлайн! или распечатать всю таблицу.

.text .global gf9_multiply .global gf9_add .intel_syntax noprefix gf9_multiply: mul edx # Multiply EAX by EDX, placing the product in EDX:EAX. aad 0x02 # AL := 2 * AH + AL (AL is the low byte of EAX; AH is the next byte.) # AH := 0 Reduces the polynomial modulo X^2 - 2. gf9_add: # When falling through, EDX=0; the next instruction will do nothing. add eax, edx# Add EDX to EAX. Coming from either start point, # this produces in EAX a polynomial equivalent to the result mod 3. cdq # Set each bit of EDX to the high bit of EAX, here 0. repeat: aam 0x30 # (AH, AL) := (quotient, remainder) of AL / 0x30 # Reduces the coefficient of X modulo 3. rol al, 4 # Rotate left by 4 places, swapping the positions of the coefficients. # Next, we need to execute the same two instructions again, # to reduce the other coefficient modulo 3 and swap them back. # Simply repeating those instructions would take 5 bytes. # It is instead done in 4 bytes, including the earlier cdq: dec edx # Decrement EDX, to -1 the first time and -2 the second time. jpe repeat # Jump back if the sum of the eight low bits is even. # This is true for -1 (...11111111) but not for -2 (...11111110). ret # Return.

Умножение, 11 байт:

f7 e2 d5 02 01 d0 99 d4 30 c0 c0 04 4a 7a f8 c3

Попробуйте онлайн! или распечатать всю таблицу.

ret ||answer||

Хаскелл, 118 112 107 байт

Здесь я использую числа \$n= 0,1,2,\ldots,8\$ для обозначения элементов поля. Внутренне они преобразуются в список \$[a,b]\$, который представляет многочлен \$aX+b\$ (используя \$a = \lfloor n/3 \rfloor\$ и \$b = n \ bmod 3 \$ или \$n=3a+b\$), а затем действуем с помощью обычной арифметики, используя эти полиномы в \$(\mathbb Z / 3\mathbb Z)[X]/(X^2+ 1)\$. В этом случае мы имеем

$$(aX+b) + (cX+d) = (a+c)X + (b+d)$$

и аналогично

$$\begin{выравнивание*}

(aX+b) \cdot (cX+d) &= acX^2+(ad+bc)X + bd

aam

\\

& \equiv ac(-1) +(ad+bc)X + bd \pmod {X^2+1} \\

& \equiv (ad+bc)X+(bd-ac)\end{align*}$$

Спасибо за -6 байт @WheatWizard! aam 0x30 format and formats the results into a square.

Попробуйте онлайн!

test

 

Ouyarang


Рег
21 Mar, 2007

Тем
63

Постов
210

Баллов
535
  • 26, Oct 2024
  • #3
Ретина 0.8.2

test

, 53 + 111 = 164 23 + 61 = 84 байта

sub

Изменить: сохранено 80 байт за счет переключения на формат ввода-вывода @Grimmy. Однако предоставленные ссылки включают нижний колонтитул, который преобразует выходные данные обратно в

daa

Дополнение (53 23 байта):

Попробуйте онлайн!

jnz repeat

Ссылка включает набор тестов. Объяснение: Преобразуйте оба аргумента в унарные.

test al, 8

Возьмите сумму и преобразуйте ее в десятичную.

sub al, 3

По модулю последнюю цифру на 3 и по модулю на 30.

daa

Умножение (111 61 байт):

add

Попробуйте онлайн!

daa

Ссылка включает набор тестов. Объяснение:

Преобразовать в унарный.

Возьмите продукт.

По модулю на 300, 98 и 30.

daa

Преобразовать в десятичное число.

add ||answer||

По модулю последнюю цифру на 3.

 

Vlavin


Рег
25 Apr, 2011

Тем
58

Постов
175

Баллов
495
  • 26, Oct 2024
  • #5
repeat: daa calling convention – arguments in EAX and EDX, result in AL. The multiplication function begins at the start of the code, and the addition function begins after the first four bytes.

32-битный машинный код x86,

16 байт

gf9_multiply

-5 с другим, более коротким способом уменьшения коэффициентов по модулю 3.

gf9_add

Использует полиномы по модулю \$X^2 + 1\$, представленные целыми числами путем замены \$ X = 16 \$. Выбранные значения соответствуют каноническим формам \$aX + b\$ для \$a,b \in \{0,1,2\}\$ – шестнадцатеричные 00, 01, 02, 10, 11, 12, 20, 21. , 22.

gf9_add: add eax, edx

Использует
Попробуйте онлайн! sub al, ah , this adds EDX and EAX (the arguments), so that AH represents a polynomial equivalent to the result modulo 3, of the form \$ aX+b \$ for \$ 0 \le a \le 4, 0 \le b \le 4 \$.
Объяснение gf9_multiply: mul edx , EDX will be 0 when we get here, and this instruction leaves EAX unchanged.

regparm(2)

Умножьте заданные полиномы (которые есть в EAX и EDX). Поместите продукт в EDX:EAX — значение достаточно мало, чтобы поместиться в EAX, поэтому EDX становится равным 0. Вычтите AH (второй младший байт EAX) из AL (самый младший байт EAX). Это уменьшает полином по модулю \$ X^2 + 1 \$: AL теперь представляет полином, эквивалентный результату по модулю 3, вида \$ aX+b \$ для \$ 0 \le a \le 8, -4 \le b \le 4 \$..

f7 e2 28 e0 01 d0 27 2c 03 a8 08 75 f9 d4 30 c3 stands for Decimal Adjust (AL) after Addition. "Decimal" in these instruction names refers to packed BCD, which puts one decimal digit in each Здесь две функции сливаются.Для f(a)=a%3+a\3*I g(a)=[real(a),imag(a)]%3*[1,3]~ s(a,b)=g(f(a)+f(b)) p(a,b)=g(f(a)*f(b)) or similar instruction, to correct the result for BCD.

Для
Это одна из нескольких инструкций x86, предназначенных для обработки чисел в
двоично-десятичный код f(a)=a%3+a\3*x g(a)=Vecrev(a%(x^2+1),2)%3*[1,3]~ s(a,b)=g(f(a)+f(b)) p(a,b)=g(f(a)*f(b)) does.

грызть

. Как следует из названия инструкции, ее предназначение — использовать после регулярного e=@(x)mod(x,3)+i*round(x/3) d=@(x)mod(real(x)^3+3*imag(x),9) a=@(x,y)d(e(x)+e(y)) m=@(x,y)d(e(x)*e(y)) instruction based on whether it results in a carry across the centre of the byte, which covers the cases where the low nybble reaches 16 or higher and wraps back around to a valid BCD digit. The instruction e=@(x)mod(x,3)+i*fix(x/3) d=@(x)[1 3]*mod([real(x);imag(x)],3) a=@(x,y)d(e(x)+e(y)) m=@(x,y)d(e(x)*e(y)) Так какая коррекция необходима?

T`3-8`012012 also makes a similar adjustment for the high nybble of AL: if the high nybble's original value is 10 to 15, or the carry flag (CF) is 1 (which is based on carries off the top of the number), it adds 6 to the high nybble.

Рассмотрим простой пример сложения 2 (двоичный код 00000010) и 8 (двоичный код 00001000). M`1 , which always sets them to 0 here. The low nybble is 10 to 15 iff, in the current polynomial \$ aX+b \$ (with \$ 0 \le a \le 8, -4 \le b \le 4 \$), \$ b \$ is -4 to -1, in which case adding 6 results in \$ b \$ being 2 to 5. The high nybble is 10 to 15 only if \$ a \$ is 0 in addition to \$ b \$ being negative, in which case adding 6 to the high nybble makes \$ a \$ 6.

Результатом обычного сложения является обычная цифра 10 (двоичный код 00001010), но сумма в формате BCD должна быть равна 10 в формате BCD (двоичный код 00010000). Таким образом, результат необходимо увеличить на 6, чтобы изменить 10 на 16. Это одна из вещей, которые 1{300}|1{98}|1{30} , AL still represents a polynomial equivalent to the result modulo 3 of the form \$ aX+b \$, but now with \$ 0 \le a \le 8, 0 \le b \le 5 \$.

1(?=1*;(1*))|. $1

Но как он узнает, следует ли применять этот +6? В данном случае это очевидно из самого значения, поскольку двоичное число 1010 не является допустимой цифрой BCD. Но если бы вместо этого вычисление было 8 плюс 8, результатом было бы двоичное число 00010000, которое является действительным BCD для 10, но правильная сумма BCD равна 16.

\d+ $*

Здесь на помощь приходит «флаг вспомогательного переноса» (AF). Он устанавливается

\d+ $* 1(?=1*;(1*))|. $1 1{300}|1{98}|1{30} M`1 T`3-8`012012

добавляет 6 к AL, если младший полубайт AL равен от 10 до 15 или AF равен 1. 3$ 0 T`34`_1 adds 6 to \$ b \$ while possibly changing \$ a \$ from 0 to 6, similarly to before, and then M`1 Здесь флаги AF и CF взяты из предыдущего \d+ $* sees that the eights bit is 0, and the jump does not happen again.

Таким образом, после

Вычтите 3. Снова AL представляет собой полином, эквивалентный результату по модулю 3 в виде \$ aX+b \$, и на этот раз \$ 0 \le a \le 8, -3 \le b \le 2 \$. \d+ $* M`1 3$ 0 T`34`_1 could have been omitted for -2 bytes.

0-8

Посмотрите на восьмой бит AL, который равен 1, если \$ b \$ отрицательное значение, и 0 в противном случае. i x=[div x 3,x] --conert integer to polynomial/list representation j[a,b]=mod(a*3+mod b 3)9 --inverse of i s=(.i).(j.).zipWith(+).i --"sum" m[a,b][c,d]=j[a*d+b*c,b*d-a*c] --core function of "product" p=(.i).m.i --"product" converts a regular number in AL to an unpacked BCD (one byte per decimal digit) number in AH and AL, which is done by setting AH and AL to the quotient and remainder, respectively, of AL divided by 10. However, the instruction allows that number 10 to be changed. We set it to 0x30; the important part is that AL is reduced modulo 0x30, which means \$ a \$ is reduced modulo 3.

Перейти назад, если \$ b \$ отрицательно (от -3 до -1). Если это так, то дальше

P # product of the inputs ƵÈ% # mod 300 98% # mod 98 S3%J # split, mod 3 each digit, join

берет 3 из \$b\$, оставляя его с конечным результатом +3, что помещает его в диапазон от 0 до 2, а затем

В любом случае AL теперь представляет собой полином, эквивалентный результату по модулю 3 в форме \$ aX+b \$ с \$ 0 \le a \le 8, 0 \le b \le 2 \$.

PƵÈ%98%S3%J

Если бы можно было условно прыгать по АФ, то

Это еще одна инструкция BCD. В форме по умолчанию

O # sum of the inputs S # split to a list of digits 3% # mod 3 each digit J # join ||answer||

Наконец, многочлен приведен по модулю 3 к каноническому виду.Возвращаться.

Предыдущее решение, также 16 байт 05AB1EСборка:

OS3%J
 

Honolula


Рег
28 Jul, 2014

Тем
74

Постов
182

Баллов
582
Тем
403,760
Комментарии
400,028
Опыт
2,418,908

Интересно