Twoim celem jest zaimplementowanie operacji mnożenia XOR (bez nośnika ), zdefiniowanej poniżej, w jak najmniejszej liczbie bajtów.
Jeśli myślimy o bitowej XOR ( ^
) jako dodatku binarnym bez przenoszenia
101 5
^ 1001 9
----
1100 12
5^9=12
możemy wykonać mnożenie XOR @
, wykonując binarne długie mnożenie, ale wykonując krok dodawania bez przenoszenia bitowego XOR ^
.
1110 14
@ 1101 13
-----
1110
0
1110
^ 1110
------
1000110 70
14@13=70
(Dla matematyków jest to mnożenie w pierścieniu wielomianowym F_2[x]
, identyfikującym wielomiany liczbami naturalnymi, oceniając x=2
jako wielomian nad Z.)
Mnożenie XOR dojeżdża a@b=b@a
, kojarzy (a@b)@c=a@(b@c)
i dystrybuuje w bitowym XOR a@(b^c)=(a@b)^(a@c)
. W rzeczywistości, jest to wyjątkowa taka operacja, która odpowiada mnożenie a@b=a*b
ilekroć a
i b
są uprawnienia 2
jak 1,2,4,8...
.
Wymagania
Weź dwie nieujemne liczby całkowite jako dane wejściowe i wyjściowe lub wydrukuj ich produkt XOR. Powinny to być liczby lub ich dziesiętne ciągi znaków, a nie ich rozwinięcia binarne. Wygrywa najmniej bajtów.
Nie przejmuj się przepełnieniami liczb całkowitych.
Oto kilka przypadków testowych sformatowanych jako a b a@b
.
0 1 0
1 2 2
9 0 0
6 1 6
3 3 5
2 5 10
7 9 63
13 11 127
5 17 85
14 13 70
19 1 19
63 63 1365
PCLMULQDQ
z rozszerzenia CLMUL. Niestety zostałem wcześniej oceniony za moją wiedzę na temat zestawu instrukcji x86 (Powiązane zPEXT/PDEP
), więc zostawię to jako komentarz tutaj.Odpowiedzi:
Kod maszynowy x86: 7 bajtów
Tylko dwie instrukcje.
pclmulqdq
wykonuje ciężkie podnoszenie, dosłownie wdraża ten rodzaj mnożenia xor.ret
aby uczynić ją funkcją wywoływalną, miejmy nadzieję spełniającą wymóg „generowania” wyniku (w wartości zwracanejxmm0
). Umieszczanie argumentów wxmm
liczbach całkowitych w args jest trochę niezwykłe, ale mam nadzieję, że mi wybaczysz.źródło
Z80, 11 bajtów
Kod jest wywoływany jako funkcja.
a
ib
są wD
iE
(kolejność nie ma znaczenia), a odpowiedź jest przechowywany wA
chwili powrotu kod (istnieją żadne funkcje I / O).Daje prawidłowe wyniki dla wszystkich danych wejściowych testu, z wyjątkiem
63@63
tych zwracanych,85
ponieważ wszystkie rejestry są 8-bitowe i 1365 mod 256 = 85 (przepełnienie liczb całkowitych).źródło
C,
4438 bajtówDzięki nim używamy teraz rekurencji dla 6 mniej bajtów!
Możemy zdefiniować funkcję
f
, która trwaa
,b
.Można to nazwać tak:
Które wyjścia:
13 @ 14 = 70
Wypróbuj przypadki testowe online !
źródło
f(a,b)={return(b)?(b&1)*a^f(2*a,b/2):0;}
?(b&1)
sięb%2
zapisać kolejne dwa bajty, ponieważ%
ma taką samą lewej do prawej poziom pierwszeństwa*
.Pyth,
1312 bajtówDemonstracja.
Stara wersja, 13 bajtów:
Demonstracja.
źródło
vz
dwóch wejściowych liczb całkowitych.CJam,
1413 bajtówJak to działa :
Najpierw otrzymujemy długie wyniki mnożenia, a następnie pracujemy w górę, zaczynając od dwóch najniższych par.
Wypróbuj online tutaj
źródło
J, 14 bajtów
Stosowanie:
Objaśnienie (czytanie głównie od prawej do lewej;
u
iv
oznaczają dowolne funkcje):u&.#:
stosujeu
się do wektorów reprezentacji binarnych liczb wejściowych, a następnie zamień wynik z powrotem na liczbę całkowitą (u&.v == v_inverse(u(v(input_1), v(input_2)))
)*/
produkty (*
) danych wejściowych w produkcie Descartesa (/
) dwóch wektorów binarnychv(u@)
stosuje sięu
dov
(do produktu Descartes)u/.
stosuje sięu
do każdej anty-przekątnej produktu Descartes (anty-przekątne oznaczają pierwszą, drugą, ... cyfrę w reprezentacji binarnej)~:/
zmniejsz (/
) anty-przekątną z operacją XOR (~:
)Wypróbuj online tutaj.
źródło
Python 2, 35 bajtów
Zadzwoń jak
f(13, 14)
. Myślę, że większość języków o podobnej konstrukcji zbiega się z czymś takim.źródło
Java, 62
Rozszerzony
źródło
for(;i<32;)
sięwhile(i<32)
? Są tej samej długości, ale drugi wydaje się bardziej naturalnym sposobem na napisanie tego.i++
pierwotnie był wfor
pętli i grał w golfa do obecnej pozycji. Ponieważwhile
nie jest mniejszy, nie ma powodu, aby go zmieniać.Haskell, 50 bajtów
Tłumaczenie odpowiedzi C @ BrainSteel. Przykład użycia:
źródło
Perl - 35 bajtów
Liczenie opcji wiersza poleceń jako jednej. Dane wejściowe są pobierane
STDIN
, oddzielone spacją.Przykładowe użycie:
źródło
Julia,
353330 bajtówTworzy to funkcję rekurencyjną,
f
która przyjmuje dwie liczby całkowite i zwraca iloczyn XOR wejść.Nie golfowany:
Zapisano kilka bajtów dzięki zachęcie ze Sp3000!
źródło
Python 2,
104917866 bajtówWeź bity
b
w odwrotnej kolejności, kończąc przed trafieniem'0b'
na początku łańcucha. Pomnóż każdy przeza
ixor
przez sumę, a następnie przesuń w lewoa
. Następnie wydrukuj sumę.źródło
Idź, 63 bajty
Kompletny przykład:
http://play.golang.org/p/-ngNOnJGyM
źródło
GAP , 368 bajtów
Jasne, zróbmy to! (jest to tylko luźna gra w golfa, chodziło raczej o przejście do F 2 [x] i wykonanie obliczeń bardziej niż jakakolwiek próba bycia zwycięzcą)
Oto kod
Oto niepoznany kod z wyjaśnieniem:
Dobra, więc po pierwsze, tworzymy pierścień wielomianowy jednowymiarowy nad polem F 2 i nazywamy go
R
. Należy pamiętać, żeGF(2)
jest F 2 w Gap.Następnie przypiszemy zmienną GAP
x
do nieokreślonego pierścieniaR
. Teraz, ilekroć mówięx
w GAP, system będzie wiedział, że mówię o nieokreślonym pierścieniuR
.Następnie mamy dwie funkcje, które są odwrotnymi mapami. Obie mapy są włączone, ale nie zachowują struktury, więc nie mogłem znaleźć lepszego sposobu na ich wdrożenie w GAP. Jest prawie na pewno lepszy sposób, jeśli go znasz, proszę o komentarz!
Pierwsza mapa
to_ring
pobiera liczbę całkowitą i odwzorowuje ją na odpowiadający jej element pierścieniowy. Robi to poprzez użycie algorytmu konwersji do binarnego, w którym każdy,1
który pojawiłby się w binarnym, jest zastępowany przezx^n
gdzien
jest odpowiednia moc, którą 2 by wziął, gdyby liczba rzeczywiście była binarna.Następna funkcja odwraca to.
to_ints
bierze element pierścienia i mapuje go na odpowiednią liczbę całkowitą. Robię to, uzyskując listę współczynników wielomianu i dla każdego niezerowego współczynnika wynik jest zwiększany o 2 ^ n, w taki sam sposób, w jaki konwertujemy wartość binarną na dziesiętną.W ostatnim kroku nazywamy te funkcje. Bierzemy dwa wejścia całkowite, przekształcamy je w elementy w pierścieniu
R
, a następnie mnożymy te elementy razem i wysyłamy produkt z powrotem do liczb całkowitych.źródło
Rubinowy,
767573 bajtówRuby, 60 bajtów (tylko funkcja, brak we / wy)
źródło
Mathematica, 40 bajtów
źródło
f@@{a,b,c,d}
=f[a,b,c,d]
. reference.wolfram.com/language/ref/Apply.htmlDart,
3432 bajtyProsta implementacja rekurencyjna.
źródło
gnuplot, 29 bajtów
tak jak w Dart (patrz wyżej)
źródło
GNU Assembler (x86_64 Mac OS X), 97 bajtów
Jest to właściwa funkcja, którą można wywołać z C:
i można przetestować za pomocą tego programu C:
Zauważ, że w Mac OS X musisz użyć,
clang -x c
aby skompilować go jako C, a nie C ++.W przypadku linuxa (o ile dobrze pamiętam) kod będzie miał 95 bajtów:
O dziwo, ta wersja jest w rzeczywistości dłuższa niż definiowanie funkcji w asemblerze wbudowanym, ale ta była dłuższa niż rozwiązanie czystego C, które już mamy, więc postanowiłem spróbować asemblera.
edytować
Jeśli jest liczony według złożonego rozmiaru (bez etykiet i innych), to jest
Asembler x86_64, 22 bajty:
źródło
golflua 68
Zasadniczo robi to samo przesunięcie bitów, co odpowiedź Java Ypnypna , ale wydaje się, że wymaga dzielenia przez 2 na końcu, aby działać poprawnie. Przyjmuje wartości jako standardowe, przykłady poniżej
źródło
Cejlon, 90 bajtów
To jest po prostu algorytm opisany: pomnożyć
a
przez2^i
gdziekolwieki
ty bit jest ustawiony wb
, i dodać je razem za pomocą xor. Iteruje się,0:64
ponieważ liczby całkowite są 64-bitowe na Cejlonie, gdy są uruchomione na JVM (niższe, gdy działają jako JavaScript, ale pob.get(i)
prostu zwracają fałsz).Sformatowany:
Alias skrywa tutaj tylko jeden bajt.
źródło
(niekonkurujące) galaretka, 16 bajtów
Wypróbuj online!
źródło