256 öğeden oluşan bir alan tanımlama


15

Matematikteki bir alan , belirli aksiyomları tatmin edecek şekilde toplama ve çarpma işlemleri ile tanımlanmış bir sayı kümesidir (Wikipedia'da tanımlanmıştır; ayrıca aşağıya bakınız).

Sonlu bir alanda asal bir sayı olan ve doğal bir sayı olan p n öğeleri bulunabilir . Bu meydan okuma olarak ele alalım ve bu yüzden en 256 unsurlarla bir alan yapalım.pnp = 2n = 8

Alanın unsurları içeren bir aralıkta ardışık tamsayılar olmalıdır 0ve 1:

  • -128 ... 127
  • 0 ... 255
  • veya böyle bir aralık

Soyut "toplama" ve soyut "çarpma" için alan aksiyomlarını tatmin edecek şekilde iki fonksiyon (veya daha kolaysa programlar) tanımlayın :a(x,y)m(x,y)

  • Tutarlılık: a(x,y)ve m(x,y)aynı argümanlarla çağrıldığında aynı sonucu verir
  • Kapalılık: İlgili aralıktaki sonuç ave mtam sayıdır
  • Birleşim: herhangi x, yve zaralığında a(a(x,y),z)eşittir a(x,a(y,z)); aynısım
  • Yerdeğiştirme: herhangi xve yaralığında a(x,y)eşittir a(y,x); aynısım
  • Distributivity: herhangi x, yve zaralığında m(x,a(y,z))eşittira(m(x,y),m(x,z))
  • Nötr elemanlar: xaralıktaki herhangi biri için a(0,x), eşittir xve m(1,x)eşittirx
  • Olumsuzluk: xaralıktaki herhangi biri için, böyle bir yşey a(x,y)var0
  • Ters: herhangi x≠0aralığında, örneğin vardır yolduğu m(x,y)bir1

İsimler ave msadece örnekler; diğer adları veya adsız işlevleri kullanabilirsiniz. Cevabınız puanı için bayt uzunlukları toplamıdır ave m.

Yerleşik bir işlev kullanıyorsanız, lütfen ürettiği sonucu (örneğin bir çarpım tablosu sağlayın) kelimelerle de açıklayın.


3
@LeakyNun "ekleme" burada yukarıdaki özellikleri karşılayan soyut bir işlemdir. Gerek yok , yukarıdaki aksiyomlar tatmin edildiği sürece a(2,1) = 3sahip olabilirsiniz a(2,1) = 5. aalışılagelmiş rasyonel sayılar alanından alışkın olduğunuz alışkanlıkla bir şey yapmak zorunda değilsiniz.
Martin Ender

2
Değişmeli bir halka önemsizdir. Bir alan ... o kadar kolay değil.
Neil

Yanlış bir şey mi var a=+ m=×?
Haziran'da Adám

4
@ Adám Evet - 2, tersi olmazsam=×
Sp3000

Yanıtlar:


4

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

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

GF2P8MULBIce Lake CPU'larla ilgili yeni talimatları kullanır .

Komut, birinci kaynak işleneninde bir bayt (alan elemanı) ve ikinci bir kaynak işlenmesinde karşılık gelen bayt üzerinde çalışan sonlu GF (2 8 ) alanındaki elemanları çoğaltır . GF (2 8 ) alanı , indirgeme polinomu x 8 + x 4 + x 3 + x + 1 ile polinom gösteriminde temsil edilir .


13

Python 2, 11 + 45 = 56 bayt

Ekleme (11 bayt):

int.__xor__

Çarpma (45 bayt):

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

Aralıktaki giriş numaralarını alır [0 ... 255]. Toplama sadece bitsel XOR, çarpma polinomların GF2'deki katsayılarla Rus köylüsü ile çarpımıdır .

Ve kontrol etmek için:

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))

İçimizden biri değiştirmek zorunda
kalacak

@Mego Hah, şey ... Başka yaklaşımlar bulabileceğimi göreceğim. Gerçi yenmek zor olabilir.
Sp3000

1
Hangi polinom dayanmaktadır?
feersum

1
@LSpice Şimdi m(2,128)27 = 283 - 256 ile sonuçlanan çalıştırarak polinomu kolayca bulabileceğimi anlıyorum, bu yüzden haklısınız ve polinom x^8 + x^4 + x^3 + x + 1.
feersum

1
@LSpice Neil'in cevabında algoritma için bir kaynak olarak bir Wikipedia sayfası verir, belki herkes bunu okur. Ama yine de bu gösterimdeki en küçük indirgenemez polinom olduğu için kod golfü için en belirgin seçimdir.
feersum

6

JavaScript (ES6), 10 + 49 = 59 bayt

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

Etki alanı 0 ... 255'tir. Kaynak .


2
Muhtemelen kullandığınız aralığı belirtmelisiniz.
Martin Ender

4

Hoon , 22 bayt

[dif pro]:(ga 8 283 3)

Hoon ++ga, AES uygulamasında kullanmak için Galois Fields'i oluşturan bir işleve zaten sahiptir . Bu, iki program kullanmak yerine iki işlevden oluşan bir demet döndürür.

Alan adında çalışır [0...255]

Test odası:

=+  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"

Bir çarpım tablosu yayınlamak devasa olurdu, bu yüzden bazı rastgele test senaryoları:

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

1

IA-32 makine kodu, 22 bayt

"Çarpma", 18 bayt:

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

"Toplama", 4 bayt:

92 33 c1 c3

Bu, kuralları biraz uzatır: "çarpma" kodu, işlev çıkış kodundan yoksundur; hemen sonrasında bellekte bulunan "ekleme" koduna dayanır, böylece "düşebilir". Kod boyutunu 1 bayt azaltmak için yaptım.

Kaynak kodu ( mlMS Visual Studio tarafından birleştirilebilir ):

    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

Algoritma, x^8 + x^4 + x^3 + x + 1onaltılı sayı ile temsil edilen olağan polinomu içeren standarttır 1b. "Çarpma" kodu sonucu toplar edx. Tamamlandığında, onu ekleyen koda gider eax(dönüş değerini tutmak için geleneksel kayıt); xorile ecxo noktada çünkü no-op ecxtemizlenir.

Bir tuhaf özellik döngüdür. Sıfırı kontrol etmek yerine

cmp ecx, 0
jne myloop

özel looptalimatı kullanır . Ancak bu komut, 0 ile karşılaştırılmadan önce döngü "sayacını" azaltır. Bunu telafi etmek için kod, loopkomutu kullanmadan önce arttırır .


0

Mathematica 155 bayt

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]

uygulama

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

ilave kontrolü:

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

Daha:

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

NB {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}yerine herhangi birini kullanabilmelidir 283.


İşte 13 bayt daha az: ±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](kaynağın ISO 8859-1'de kodlandığını varsayar)
Martin Ender

@MartinEnder önerinizi nasıl uygulayacağınızdan tam olarak emin değilim
martin

@martin Daha önce olduğu gibi kullanabilirsiniz, ±yerine yerine kullandım fve pyerine o(tabii ki o, pher ikisini de test edebilmek için kullandım) ve sonra standart olarak birkaç bayt kazandım. sözdizimsel şeker hileleri.
Martin Ender

@MartinEnder ile ±aynı şekilde çalışabilir f, ancak p... yanlış gittiğimden emin değilim
martin

Doğrudan yorumdan kopyalarsanız, tarayıcınızın açıklamada satır sonunu görüntülediği her yerde yazdırılamayan bazı karakterler olabilir. Kopyaladıktan sonra bu konumun çevresindeki karakterleri silin ve yeniden yazın. Bunu yapmazsa, sorunun nerede olduğundan emin değilim ..
Martin Ender

-1

Brainfuck, 28 karakter

Neyse ki, standart Brainfuck her şeyi 256 modulo yapar.

Ek:, [->+<]girişlerin kasetin ilk iki konumunda olduğunu varsayar, çıktıyı 0 konumuna yerleştirir

Çarpma:, [->[->+>+<<]>[-<+>]<<]girişlerin kasetin ilk iki konumunda olduğunu varsayar, çıktıyı 3. konuma yerleştirir

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.