Xác định một trường có 256 phần tử


14

Một trường trong toán học là một tập hợp các số, với các phép toán cộng và nhân được định nghĩa trên nó, sao cho chúng thỏa mãn các tiên đề nhất định (được mô tả trong Wikipedia; xem thêm bên dưới).

Một trường hữu hạn có thể có các phần tử p n , trong đó plà số nguyên tố và nlà số tự nhiên. Trong thử thách này, chúng ta hãy thực hiện p = 2n = 8, vì vậy hãy tạo một trường có 256 phần tử.

Các phần tử của trường phải là các số nguyên liên tiếp trong một phạm vi có chứa 01:

  • -128 ... 127
  • 0 ... 255
  • hoặc bất kỳ phạm vi khác như vậy

Xác định hai hàm (hoặc chương trình, nếu dễ hơn), a(x,y)cho m(x,y)"phép cộng" trừu tượng và cho "phép nhân" trừu tượng, sao cho chúng thỏa mãn các tiên đề của trường:

  • Tính nhất quán: a(x,y)m(x,y)tạo ra kết quả tương tự khi được gọi với cùng các đối số
  • Độ kín: Kết quả của amlà một số nguyên trong phạm vi có liên quan
  • Associativity: cho bất kỳ x, yztrong phạm vi, a(a(x,y),z)bằng a(x,a(y,z)); tương tự chom
  • Giao hoán: cho bất kỳ xytrong phạm vi, a(x,y)bằng a(y,x); tương tự chom
  • Phân phối: cho bất kỳ x, yztrong phạm vi, m(x,a(y,z))bằnga(m(x,y),m(x,z))
  • Các yếu tố trung tính: cho bất kỳ xtrong phạm vi, a(0,x)bằng xm(1,x) bằngx
  • Phủ định: đối với bất kỳ xtrong phạm vi, tồn tại như vậy yđó a(x,y)0
  • Nghịch đảo: đối với bất kỳ x≠0trong phạm vi, tồn tại như vậy yđó m(x,y)1

Tên amchỉ là ví dụ; bạn có thể sử dụng các tên khác hoặc các hàm không tên. Điểm của câu trả lời của bạn là tổng độ dài byte cho am .

Nếu bạn sử dụng hàm dựng sẵn, vui lòng mô tả bằng từ mà kết quả mà nó tạo ra (ví dụ: cung cấp bảng nhân).


3
@LeakyNun "bổ sung" chỉ là một hoạt động trừu tượng ở đây đáp ứng các thuộc tính trên. Không cần a(2,1) = 3, bạn có thể có a(2,1) = 5miễn là các tiên đề trên được thỏa mãn. akhông phải làm bất cứ điều gì với phép cộng thông thường mà bạn đã sử dụng, ví dụ như từ trường số hữu tỷ.
Martin Ender

2
Một vòng giao hoán là tầm thường. Một lĩnh vực ... không dễ dàng như vậy.
Neil

Có điều gì sai với a=+ m=×?
Adám

4
@ Adám Có - 2 sẽ không có nghịch đảo nếum=×
Sp3000

Câu trả lời:


4

Hoon , 22 byte

[dif pro]:(ga 8 283 3)

Hoon đã có chức năng ++ga tạo Trường Galois, để sử dụng trong triển khai AES. Điều này trả về một tuple của hai chức năng, thay vì sử dụng hai chương trình.

Hoạt động trong miền [0...255]

Người kiểm tra:

=+  f=(ga 8 283 3)
=+  n=(gulf 0 255)

=+  a=dif:f
=+  m=pro:f

=+  %+  turn  n
    |=  x/@
    ?>  =((a 0 x) x)
    ?>  =((m 1 x) x)
    ~&  outer+x

    %+  turn  n
      |=  y/@
      ?>  =((a x y) (a y x))
      ?>  &((lte 0 (a x y)) (lte (a x y) 255))
      ?>  &((lte 0 (m x y)) (lte (m x y) 255))

      %+  turn  n
        |=  z/@
        ?>  =((a (a x y) z) (a x (a y z)))
        ?>  =((m x (a y z)) (a (m x y) (m x z)))
        ~
"ok"

Đăng một bảng nhân sẽ là khổng lồ, vì vậy đây là một số thử nghiệm ngẫu nhiên:

20x148=229
61x189=143
111x239=181
163x36=29
193x40=1

13

Python 2, 11 + 45 = 56 byte

Ngoài ra (11 byte):

int.__xor__

Phép nhân (45 byte):

m=lambda x,y:y and m(x*2^x/128*283,y/2)^y%2*x

Lấy số đầu vào trong phạm vi [0 ... 255] . Phép cộng chỉ là XOR bitwise, phép nhân là phép nhân đa thức với hệ số trong GF2 với nông dân Nga .

Và để kiểm tra:

a=int.__xor__
m=lambda x,y:y and m(x*2^x/128*283,y/2)^y%2*x

for x in range(256):
    assert a(0,x) == a(x,0) == x
    assert m(1,x) == m(x,1) == x

    assert any(a(x,y) == 0 for y in range(256))

    if x != 0:
        assert any(m(x,y) == 1 for y in range(256))

    for y in range(256):
        assert 0 <= a(x,y) < 256
        assert 0 <= m(x,y) < 256
        assert a(x,y) == a(y,x)
        assert m(x,y) == m(y,x)

        for z in range(256):
            assert a(a(x,y),z) == a(x,a(y,z))
            assert m(m(x,y),z) == m(x,m(y,z))
            assert m(x,a(y,z)) == a(m(x,y), m(x,z))

Một người trong chúng ta sẽ phải thay đổi: P
Mego

@Mego Hah, à ... Tôi sẽ thử xem tôi có thể tìm thấy phương pháp nào khác không. Có thể khó đánh bại mặc dù.
Sp3000

1
Nó dựa vào đa thức nào?
frageum

1
@LSpice Bây giờ tôi nhận ra rằng tôi có thể dễ dàng tìm thấy đa thức bằng cách chạy m(2,128)kết quả trong 27 = 283 - 256, vì vậy bạn đã đúng và đa thức là x^8 + x^4 + x^3 + x + 1.
frageum

1
@LSpice Trong câu trả lời của Neil, anh ấy đưa ra một trang Wikipedia làm nguồn cho thuật toán, vì vậy có lẽ mọi người đều đọc nó. Nhưng dù sao nó cũng là sự lựa chọn rõ ràng nhất cho môn đánh gôn vì nó là đa thức nhỏ nhất không thể thay đổi của mức 8 trong biểu diễn này.
frageum

6

JavaScript (ES6), 10 + 49 = 59 byte

a=(x,y)=>x^y
m=(x,y,p=0)=>x?m(x>>1,2*y^283*(y>>7),p^y*(x&1)):p

Tên miền là 0 ... 255. Nguồn .


2
Bạn có thể nên chỉ định phạm vi bạn đang sử dụng.
Martin Ender

4

Intel x86-64 + AVX-512 + GFNI, 11 byte

add:
    C5 F0 57 C0     # vxorps     xmm0, xmm1, xmm0
    C3              # ret
mul:
    C4 E2 79 CF C1  # vgf2p8mulb xmm0, xmm0, xmm1
    C3              # ret

Sử dụng GF2P8MULBhướng dẫn mới trên CPU Ice Lake.

Lệnh nhân các phần tử trong trường hữu hạn GF (2 8 ), hoạt động trên một byte (phần tử trường) trong toán hạng nguồn đầu tiên và byte tương ứng trong toán hạng nguồn thứ hai. Trường GF (2 8 ) được biểu diễn dưới dạng đa thức với đa thức khử x 8 + x 4 + x 3 + x + 1.


1

Mã máy IA-32, 22 byte

"Phép nhân", 18 byte:

33 c0 92 d1 e9 73 02 33 d0 d0 e0 73 02 34 1b 41
e2 f1

"Bổ sung", 4 byte:

92 33 c1 c3

Điều này kéo dài quy tắc một chút: mã "nhân" thiếu mã thoát hàm; nó dựa vào mã "bổ sung" trong bộ nhớ ngay sau đó, vì vậy nó có thể "rơi qua". Tôi đã làm nó để giảm kích thước mã xuống 1 byte.

Mã nguồn (có thể được lắp ráp bởi mlMS Visual Studio):

    TITLE   x

PUBLIC @m@8
PUBLIC @a@8

_TEXT   SEGMENT USE32
@m@8    PROC
    xor eax, eax;
    xchg eax, edx;
myloop:
    shr ecx, 1
    jnc sk1
    xor edx, eax
sk1:
    shl al, 1
    jnc sk2
    xor al, 1bh
sk2:
    inc ecx
    loop myloop
@m@8 endp

@a@8 proc
    xchg eax, edx;
    xor eax, ecx
    ret
@a@8    ENDP
_text ENDS
END

Thuật toán là tiêu chuẩn, liên quan đến đa thức thông thường x^8 + x^4 + x^3 + x + 1, được biểu thị bằng số thập lục phân 1b. Mã "nhân" tích lũy kết quả trong edx. Khi hoàn thành, nó rơi vào mã bổ sung, di chuyển nó đến eax(thanh ghi thông thường để giữ giá trị trả về); các xorbằng ecxlà một không-op, bởi vì tại thời điểm đóecx sẽ bị xóa.

Một tính năng đặc biệt là vòng lặp. Thay vì kiểm tra số không

cmp ecx, 0
jne myloop

nó sử dụng loophướng dẫn chuyên dụng . Nhưng hướng dẫn này làm giảm "bộ đếm" vòng lặp trước khi so sánh với 0. Để bù cho điều này, mã sẽ tăng nó trước khi sử dụng looplệnh.


0

Toán học 155 byte

f[y_]:=Total[x^Reverse@Range[0,Log[2,y]]*RealDigits[y,2][[1]]];o[q_,c_,d_]:=FromDigits[Reverse@Mod[CoefficientList[PolynomialMod[q[f@c,f@d],f@283],x],2],2]

Thực hiện

(*
  in: o[Times, 202, 83]    out: 1
  in: o[Plus, 202, 83]     out: 153
*)

kiểm tra bổ sung:

(*
  in: BitXor[202, 83]      out: 153
*)

Hơn:

(*
  in: o[Times, #, #2] & @@@ {{20, 148}, {61, 189}, {111, 239}, {163, 36}, {193, 40}}
  out: {229, 143, 181, 29, 1}
*)

NB nên có thể sử dụng bất kỳ {283, 285, 299, 301, 313, 319, 333, 351, 355, 357, 361, 369, 375, 379, 391, 395, 397, 415, 419, 425, 433, 445, 451, 463, 471, 477, 487, 499, 501, 505}thay thế 283.


Chà, ở đây ít hơn 13 byte: ±y_:=Total[#&@@y~RealDigits~2x^Reverse@Range[0,2~Log~y]];p[q_,c_,d_]:=Fold[#+##&,Reverse@CoefficientList[q[±c,±d]~PolynomialMod~±283,x]~Mod~2](giả sử rằng nguồn được mã hóa theo ISO 8859-1)
Martin Ender

@MartinEnder không hoàn toàn chắc chắn về cách thực hiện đề xuất của bạn
martin

@martin Bạn có thể sử dụng chính xác như trước đây, tôi chỉ sử dụng ±thay vì fpthay vào đó o(tất nhiên bạn có thể giữ như vậy o, tôi chỉ sử dụng pđể tôi có thể kiểm tra cả hai), và sau đó lưu thêm một vài byte với tiêu chuẩn cú pháp đường cú pháp.
Martin Ender

@MartinEnder có thể ±làm việc tương tự f, nhưng không p... không chắc là tôi sẽ sai ở đâu
martin

Nếu bạn sao chép nó trực tiếp từ bình luận, có thể có một số ký tự không thể in được ở bất cứ nơi nào trình duyệt của bạn hiển thị ngắt dòng trong bình luận. Xóa các ký tự xung quanh vị trí đó sau khi sao chép và nhập lại chúng. Nếu điều đó không xảy ra, tôi không chắc vấn đề ở đâu ..
Martin Ender

-1

Brainfuck, 28 ký tự

May mắn thay, Brainfuck tiêu chuẩn thực hiện mọi thứ modulo 256.

Thêm vào: [->+<] , giả sử rằng các đầu vào ở hai vị trí đầu tiên của băng, đặt đầu ra ở vị trí 0

Phép nhân : [->[->+>+<<]>[-<+>]<<], giả sử rằng các đầu vào ở hai vị trí đầu tiên của băng, đặt đầu ra ở vị trí 3

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.