tło
Adler-32 to 32-bitowa suma kontrolna wynaleziona przez Marka Adlera w 1995 r., Która jest częścią szeroko używanej biblioteki zlib (opracowanej również przez Adlera). Adler-32 nie jest tak niezawodny jak 32-bitowa cykliczna kontrola nadmiarowa , ale - przynajmniej w oprogramowaniu - jest znacznie szybsza i łatwiejsza do wdrożenia.
Definicja
Niech B = [b 1 , ⋯, b n ] będzie tablicą bajtów.
Suma kontrolna Adler-32 B jest zdefiniowana jako wynik niski + 65536 × wysoki , gdzie:
niski: = ((1 + b 1 + ⋯ + b n ) mod 65521)
wysoki: = (((1 + b 1 ) + (1 + b 1 + b 2 ) + ⋯ (1 + b 1 + ⋯ + b n )) mod 65521)
Zadanie
Biorąc pod uwagę tablicę bajtów jako dane wejściowe, oblicz i zwróć sumę kontrolną Adler-32, przestrzegając poniższych wskazówek.
Możesz wziąć dane wejściowe jako tablicę bajtów lub liczb całkowitych lub jako ciąg znaków.
W obu przypadkach na wejściu pojawią się tylko bajty odpowiadające drukowanym znakom ASCII.
Możesz założyć, że długość danych wejściowych spełni 0 <długość ≤ 4096 .
Jeśli zdecydujesz się wydrukować wydruk, możesz użyć dowolnej dodatniej podstawy do 256 włącznie.
Jeśli wybierzesz jednoargumentowy, upewnij się, że interpreter może obsłużyć do 2 32 - 983056 bajtów danych wyjściowych na maszynie z 16 GiB pamięci RAM.
Wbudowane obliczenia sumy kontrolnej Adler-32 są zabronione.
Obowiązują standardowe zasady gry w golfa .
Przypadki testowe
String: "Eagles are great!"
Byte array: [69, 97, 103, 108, 101, 115, 32, 97, 114, 101, 32, 103, 114, 101, 97, 116, 33]
Checksum: 918816254
String: "Programming Puzzles & Code Golf"
Byte array: [80, 114, 111, 103, 114, 97, 109, 109, 105, 110, 103, 32, 80, 117, 122, 122, 108, 101, 115, 32, 38, 32, 67, 111, 100, 101, 32, 71, 111, 108, 102]
Checksum: 3133147946
String: "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"
Byte array: [126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126]
Checksum: 68095937
String: <1040 question marks>
Byte array: <1040 copies of 63>
Checksum: 2181038080
źródło
Odpowiedzi:
Galaretka,
1917 bajtówWypróbuj online!
źródło
⁹²¤
Mathematica, 46 bajtów
Anonimowa funkcja, która pobiera tablicę liczb całkowitych i zwraca Adler-32, z pewnymi ulepszeniami od mile i Martina (patrz komentarze).
mile ”to także 46 bajtów , ale szybciej:
źródło
Julia,
7346 bajtówJest to anonimowa funkcja, która przyjmuje tablicę i zwraca liczbę całkowitą. Aby go wywołać, przypisz go do zmiennej.
Łączymy
sum(x) + 1
i tworzymysum(cumsum(x) + 1)
tablicę, w którejx
znajduje się tablica wejściowa, i pobieramy każdy moduł 65521. Następnie obliczamy iloczyn skalarny z 1 i 4 8 , co daje nam(sum(x) + 1) + 4^8 * sum(cumsum(x) + 1)
, czyli dokładnie wzór Adlera-32.Wypróbuj online! (Obejmuje wszystkie przypadki testowe)
Zaoszczędź 27 bajtów dzięki Sp3000 i Dennis!
źródło
x86-64 funkcja kodu maszynowego:
3332 bajty (lub3130 bajtów zint[]
wejściem zamiastchar[]
)Funkcja kodu maszynowego x86-32: 31 bajtów
Jako fragment kodu inline-asm GNU C: zapisuje
2B1B (tylkoret
insn).Skomentowano źródło i sterownik testowy na github
Wersja 64-bitowa jest możliwa do wywołania bezpośrednio z C przy użyciu standardowego Systemu V x86-64 ABI (przy użyciu 2 fałszywych argumentów, aby uzyskać argumenty w żądanych regach). Niestandardowe konwencje wywoływania nie są rzadkie w przypadku kodu asm, więc jest to funkcja dodatkowa.
32-bitowy kod maszynowy oszczędza 1B, ponieważ łączenie górnej i dolnej połowy
push16/push16 => pop32
działa tylko w trybie 32-bitowym. Funkcja 32-bitowa wymagałaby niestandardowej konwencji wywoływania. Nie powinniśmy się temu przejmować, ale wywołanie z C wymaga funkcji otoki.Po przetworzeniu 4096
~
(ASCII 126) bajtachhigh = 0x3f040000, low = 0x7e001
. Więchigh
jest najbardziej znaczący bit nie jest jeszcze ustalone. Mój kod korzysta z tego, zaloguj rozciągająceeax
sięedx:eax
zcdq
jako sposób zerowaniaedx
.0x40 - 0x20
= 32 bajty.Skomentowane źródło NASM:
wydziwianie:
xchg eax, r32
jest jednym bajtem; tańsze niż mov. 8086 potrzebowało danych w toporze, aby uzyskać o wiele więcej rzeczy niż> = 386, więc postanowili wydać dużo przestrzeni operacyjnej na rzadko używane obecniexchg ax, r16
.Mieszanie push64 i push16 w celu połączenia wysokiego i niskiego rejestru w jeden rejestr pozwala zaoszczędzić instrukcje przenoszenia danych reg-reg około dwóch sekund
div
. 32-bitowa wersja tej sztuczki działa jeszcze lepiej:push16 / push16 / pop32
jest tylko 5B, a nie 6.Ponieważ pchamy / popujemy, nie jest to bezpieczne dla wbudowanego asm w SysV amd64 ABI (z czerwoną strefą) .
rcx
Rozważyłem również użycie jako indeksu tablicowego zamiast posiadania dwóch liczników pętli, ale adler32 (s)! = Adler32 (reverse (s)). Więc nie mogliśmy użyćloop
. Liczenie od -len w górę do zera i używaniemovzx r32, [rsi+rcx]
po prostu powoduje użycie zbyt wielu bajtów.Jeśli chcemy rozważyć samodzielne zwiększenie wskaźnika, prawdopodobnie najlepszym rozwiązaniem jest kod 32-bitowy. Nawet x32 ABI (wskaźniki 32-bitowe) nie jest wystarczające, ponieważ
inc esi
ma 2B na amd64, ale 1B na i386. Wydaje się, że trudno jest pokonać sumęxor eax,eax
/lodsb
/loop
: 4B, aby z kolei każdy element rozszerzył zero do eax.inc esi
/movzx r32, byte [esi]
/loop
wynosi 5B.scas
to kolejna opcja zwiększania wskaźnika za pomocą instrukcji 1B w trybie 64-bitowym. (rdi
/edi
zamiastrsi
, więc weźmiemy argument argrdi
). Nie możemy jednak użyć wyniku flagiscas
jako warunku pętli, ponieważ nie chcemy utrzymywać wartości zerowej eax. Inny przydział rejestrów może zaoszczędzić bajt po pętli.int[]
wkładPełne przejmowanie funkcji
uint8_t[]
jest „główną” odpowiedzią, ponieważ jest to bardziej interesujące wyzwanie. Rozpakowanie doint[]
jest nierozsądną rzeczą, o którą prosi nasz rozmówca w tym języku, ale oszczędza 2B.Jeśli weźmiemy nasz wkład jako rozpakowaną tablicę 32-bitowych liczb całkowitych, możemy łatwo zapisać jeden bajt (używać
lodsd
i zamieniać naxor eax,eax / cdq
justxor edx,edx
).Możemy zapisać kolejny bajt, zerując edx za pomocą
lodsd
/cdq
, i ponownie układając pętlę, aby ładowała końcowy element 0 przed wyjściem. (Nadal zakładamy, że istnieje, mimo że jest to tablicaint
, a nie ciąg znaków).Zrobiłem również wersję niesprawdzoną, która używa
scasd
(wersja 1Badd edi,4
) iadd eax, [rdi]
zamiastlodsd
, ale to także 30 bajtów. Oszczędności wynikające z posiadaniahigh
eax na końcu pętli są równoważone większym kodem w innym miejscu. Ma tę zaletę, że nie zależy od0
elementu końcowego na wejściu, co może być nieuzasadnione w przypadku rozpakowanej tablicy, w której również podano długość.Sterownik testowy C ++ 11
Zobacz link do github. Ta odpowiedź stawała się zbyt duża, a sterownik testowy miał więcej funkcji z większym kodem.
źródło
int[]
wtedy, gdy było to konieczne, lub zapisanie więcej niż 4 bajtów kodu lub czegoś takiego. Nie mam problemu z przedstawieniem rozwiązaniaadler32(int[])
problemu, ale wydaje mi się, żeadler32(char[])
problem jest bardziej interesujący, ponieważ jest to prawdziwa funkcja adler32. Właśnie tak naprawdę chcę grać w golfa w asm. (I bardzo chciałbym w jakiś sposób zaoszczędzić jeszcze jeden bajt, ponieważ w rzeczywistości asm 33 bajty = 48 bajtów, jeśli używana jest następna funkcjaALIGN 16
). Chyba będę grał w golfa.do{}while(--len)
stylu pętli zamiastwhile(len--){}
.MATL , 22 bajty
Dane wejściowe mogą być tablicą liczb lub odpowiednim ciągiem ASCII.
Wypróbuj online!
Wyjaśnienie
źródło
Właściwie 36 bajtów
Wypróbuj online!
Wyjaśnienie:
źródło
Java, 84 bajty
Jeśli rozwiązania Java zawsze mają być kompletnym kodem, który można skompilować, daj mi znać.
Bez golfa
Uwaga
Będziesz musiał przekonwertować dane wejściowe
String
naint[]
(int[]
jest o jeden bajt krótszy niżbyte[]
lubchar[]
).Wydajność
źródło
Piet, 120 kodów
Z kodem wielkości 20:
Notatki / Jak to działa?
Ponieważ nie jest możliwe użycie tablicy lub łańcucha jako danych wejściowych, program ten działa na podstawie szeregu liczb całkowitych (reprezentujących znaki ascii) jako danych wejściowych. Na początku myślałem o wprowadzaniu znaków, ale starałem się znaleźć dobre rozwiązanie dla zakończenia, więc teraz kończy się, gdy zostanie wprowadzona dowolna liczba mniejsza niż 1. Początkowo były to tylko ujemne wartości dla zakończenia, ale musiałem zmienić inicjalizację po napisaniu programu, więc teraz nie mogę dopasować wymaganego
2
, tylko1
(26/45 na obrazie śledzenia). Nie ma to jednak znaczenia, ponieważ zgodnie z regułami wyzwania dozwolone są tylko drukowane znaki ascii.Długo walczyłem z ponownym wprowadzeniem pętli, choć w końcu znalazłem dość eleganckie rozwiązanie. Nie
pointer
lubswitch
operacje, tylko interpreter wbiega w ściany, dopóki nie przejdzie z powrotem do zielonego kodu w celu odczytania danych wejściowych (43-> 44 na obrazach śladu).Zakończenie pętli uzyskuje się najpierw poprzez powielenie wejścia, dodanie 1, a następnie sprawdzenie, czy jest ono większe niż 1. Jeśli tak, to uruchamiany jest selektor koderów i wykonywanie jest kontynuowane na dolnej ścieżce. Jeśli tak nie jest, program pozostaje w lewo (jasnożółte kody, 31/50 na obrazach śladu).
Obsługiwany rozmiar wejściowy jest zależny od implementacji interpretera, chociaż możliwe byłoby obsługiwanie dowolnie dużego wejścia za pomocą odpowiedniego interpretera (powiedzmy na przykład, interpreter Java, który używa
BigInteger
jako wartości wewnętrznych)Właśnie zobaczyłem, że konfiguracja zawiera jeden niepotrzebny
DUP
iCC
(7-> 8-> 9 w obrazach śledzenia). Nie mam pojęcia, jak to się stało. Jest to faktycznie noop, przełącza selektor kodów 16 razy, co nie powoduje żadnych zmian.Obrazy śledzenia Npiet
Konfiguracja i pierwsza pętla:
Zakończenie pętli, wyjście i wyjście:
Wyjścia
Wybacz, jeśli dołączę tylko jedno wyjście, to zajmuje dużo czasu: ^)
Npiet trace dla [65, -1]
źródło
C89, 70 bajtów
Aby przetestować (skompilować z
gcc -std=c89 -lm golf.c
):źródło
zlib
wygląda źródło? Hm ...for
zamiastwhile
:for(h=0,l=1;*B;)h+=l+=*B++;
Labirynt ,
37363231 bajtówWypróbuj online!
Wprowadź jako listę liczb całkowitych. Program kończy się z błędem (którego komunikat o błędzie trafia do STDERR).
Wyjaśnienie
Podkład labiryntowy:
_
.Chociaż kod zaczyna się od „pokoju” 4x2, to tak naprawdę dwie oddzielne pętle dwa na dwa ściśnięte razem. IP po prostu przylega do jednej pętli na raz ze względu na wartości stosu.
Tak więc kod zaczyna się od pętli 2x2 (zgodnie z ruchem wskazówek zegara), która odczytuje dane wejściowe podczas obliczania sum prefiksu:
Teraz mamy wszystkie sumy prefiksów na stosie Aux , a także kopię sumy nad wszystkimi wartościami i
0
z EOF na main . W ten sposób wprowadzamy kolejną pętlę 2x2 (zgodnie z ruchem wskazówek zegara), która sumuje wszystkie sumy prefiksów do obliczeniaHIGH
.Głównym stos ma teraz
LOW - 1
iHIGH
zero, z wyjątkiem, że nie podjęły jeszcze modulo. Pozostała część kodu jest całkowicie liniowa:IP uderza teraz w ślepy zaułek i się odwraca.
+
I*
są w zasadzie nic nie rób, ze względu na zerowe na dole stosu.36
Teraz okazuje szczyt głównego INTO63
, ale dwa{{
ciągnąć dwa zera z AUX na wierzchu. Następnie%
próbuje podzielić przez zero, co kończy program.Zauważ, że Labirynt używa liczb całkowitych o dowolnej precyzji, więc odłożenie modulo do końca sumy nie spowoduje problemów z przepełnieniem liczb całkowitych.
źródło
Python 2,
6058 bajtówCałkiem proste podejście. Jest to pełny program, który pobiera listę liczb całkowitych przez STDIN, np
[72, 105, 33]
.(Dzięki @xnor za niesamowitą wskazówkę dotyczącą aliasingu / inicjalizacji)
źródło
H=h=65521
inicjalizacjęh
podczas aliasingu 65521.J, 30 bajtów
Prawdopodobnie można by to bardziej skondensować z innym pociągiem.
Stosowanie
Tutaj
x $ y
tworzy listę zx
kopiamiy
.Wyjaśnienie
źródło
Oktawa,
5250 bajtówZaoszczędź 2 bajty dzięki @LuisMendo
Pobiera tablicę liczb całkowitych jako danych wejściowych.
niski jest pobierany z ostatniego elementu wysokiego (przed zsumowaniem) zamiast jawnego obliczania sumy, co pozwala zaoszczędzić ... 1 bajt !
Próbka uruchomiona na ideone .
źródło
+B
. Myślę, że specyfikacja wejściowa mówi, że możesz wziąć liczby całkowite, więc może po prostu to zrobię.CJam,
3029 bajtówWprowadź jako listę liczb całkowitych.
Sprawdź to tutaj.
Wyjaśnienie
źródło
Perl 6 , 60 bajtów
Wyjaśnienie:
Test:
źródło
Python 3 (79 bajtów)
Na podstawie rozwiązania R. Kapa.
Zastąpiłem mnożenie przesunięciem i usunąłem parę wsporników.
Ponieważ nie mogę dodawać komentarzy, udzieliłem nowej odpowiedzi.
źródło
Schemat, 195 bajtów
Gdyby nie te wszystkie nawiasy ...
źródło
Haskell,
5450 bajtówPrzykład użycia:
g [69,97,103,108,101,115,32,97,114,101,32,103,114,101,97,116,33]
->918816254
.scanl
zawiera wartość początkową (->1
) na liście (->[1,1+b1,1+b1+b2,..]
), więcsum
jest wyłączony przez1
, co jest ustalane przez dodawanie-1
do listy przed zsumowaniem.Edycja: Dzięki @xnor za 4 bajty.
źródło
m
:m=(`mod`65521).sum g x=m(-1:scanl(+)1x)*4^8+m(1:x)
. Prawdopodobnie istnieje lepszy sposób na ustalenie sum niż zaliczka.JavaScript (ES7),
5250 bajtówES6 zajmuje 51 bajtów (zamień 4 ** 8 na 65536). Jeśli chcesz wersję ciąg, to dla 69 bajtów:
Edycja: Zapisano 2 bajty dzięki @ user81655.
źródło
Akceptacja funkcji ARM Thumb-2
uint8_t[]
: 40 bajtów (36B dla niestandardowych ABI iint[]
)Cechy: nieodroczony moduł, więc dane wejściowe o dowolnej wielkości są w porządku. W rzeczywistości nie używa instrukcji podziału, więc nie jest wolny. (err, przynajmniej nie z tego powodu: P)
Oszczędności wynikające z mniej rygorystycznych zasad:
uint32_t[]
tablicy.Zatem najlepszym przypadkiem jest 36B.
0x28 = 40 bajtów
Uwagi:
Zamiast
log%m
na końcu robimyif(low>=m) low-=m
wewnątrz pętli. Jeśli zrobimy niski przed wysokim, wiemy, że żaden nie może przekroczyć2*m
, więc modulo jest po prostu kwestią odejmowania lub nie. Acmp
i przewidywanesub
jest tylko 6B w trybie Thumb2. Standardowy idiom dla%
to 8B w trybie Thumb2:Wersja o długości niejawnej
adler(char *)
ma ten sam rozmiar kodu co długość jawnaadler(uint8_t[], uint32_t len)
. Możemy ustawić flagi dla warunku wyjścia z pętli za pomocą jednej instrukcji 2B w obu kierunkach.Wersja o niejawnej długości ma tę zaletę, że działa poprawnie z pustym łańcuchem, zamiast próbować zapętlić 2 ^ 32 razy.
złożyć / skompilować za pomocą:
lub
Bez
-static
tego proces działający podqemu-arm
nie znalazł dynamicznego linkera. (I tak, zainstalować ARM cross-devel konfigurację tylko dla tej odpowiedzi, bo myślałem, że mój pomysł opiera-odejmowania był schludny.) Na amd64 Ubuntu, zainstalowaćgcc-arm-linux-gnueabi
,g++-arm-linux-gnueabi
. Znalazłemgdb-arm-none-eabi
rodzaj ledwie działającego połączeniaqemu-arm -g port
.Skomentowane źródło:
test-adler32.cpp
ma te same przypadki testowe imain()
co w przypadku mojej odpowiedzi x86-64, ale zaczyna się w ten sposób:źródło
x86 16-bitowa funkcja kodu maszynowego: 32 bajty przy użyciu niestandardowej konwencji wywoływania
Argumenty w rejestrach i nie zachowujące rejestrów innych niż bp (i sp).
W kodzie 16-bitowym zwracamy wartość 32-bitową w
dx:ax
parze rejestrów. Oznacza to, że nie trzeba wydawać żadnych poleceń scalaniahigh
ilow
podeax
. (Pozwoliłoby to również zaoszczędzić bajty w kodzie 32-bitowym i 64-bitowym, ale możemy jedynie uzasadnić przeniesienie tej pracy do osoby dzwoniącej w kodzie 16-bitowym).Skomentowano źródło i sterownik testowy na github (dla x86 16, 32 i 64bit oraz ARM).
0x120 - 0x100 = 32 bajty
Przetestowany przez montażem tego samego kodu trybie 32-bitowym, tak że może to wywołać (z funkcji owijki) z C skompilowany
-m32
. Dla mnie tryb 16-bitowy jest dość interesujący, wywołania systemowe DOS nie są. Wszystkie instrukcje mają jawne argumenty, z wyjątkiem,loop
alodsb
więc, w trybie 32-bitowym używa się prefiksów wielkości argumentu. Ta sama instrukcja, inne kodowanie. Alelodsb
w trybie 32bit będzie korzystać[esi]
, więc ta wersja do testowania działa z 32-bitowymi wskaźnikami (ponieważ nie wykonujemy żadnych obliczeń adresu ani przyrostu / porównania wskaźnika).Brak niezgodności. Moja uprząż testowa drukuje komunikat, jeśli występuje niezgodność.
W przypadku rejestrów 16-bitowych nie możemy odraczać redukcji modulo aż do zakończenia pętli. Istnieje interesująca różnica między 16-bitowym a innym rozmiarem operandu:
m = 65521
(0xFFF1
) to ponad połowa 65536. Odejmowaniem
przeniesienia utrzymuje wartość poniżej 2 * m, nawet jeślihigh=0xFFF0 + 0xFFF0
. Po pętli podpowiedź i odejmij wykona lewę, zamiast adiv
.Wymyśliłem nowatorską technikę zmniejszania modulo rejestru po dodaniu, które może powodować przeniesienie . Zamiast zerować górną połowę wejścia dla
div
, użyj,setc dl
aby stworzyć 32-bitową dywidendę z nieskróconym wynikiem dodania (dh
jest już wyzerowany). (div
robi podział 32b / 16b => 16bit.)setcc
(3 bajty) wprowadzono z 386. Aby uruchomić to na 286 lub wcześniejszym, najlepiej, co wymyśliłem, używa nieudokumentowanejsalc
instrukcji (ustaw AL z carry) . Jest to jednobajtowy kod operacyjny dlasbb al,al
, więc moglibyśmy użyćsalc
/neg al
przed zrobieniemxchg ax, dx
(czego i tak potrzebujemy). Bezsalc
jest sekwencja 4B:sbb dx,dx
/neg dx
. Nie możemy użyć 3Bsbb dx,dx
/inc dx
, ponieważ to by emulowało,setnc
a niesetc
.Próbowałem użyć 32-bitowego rozmiaru operandu zamiast obsługi przenoszenia, ale nie tylko
add
instrukcje wymagają prefiksu wielkości operandu. Instrukcje konfigurujące stałe i tak dalej również wymagają prefiksów wielkości operandu, więc nie było to najmniejsze.źródło
Pyth,
252423 bytes1 byte thanks to @Jakube.
1 more byte thanks to @Jakube.
Try it online!
Translation of my answer in Jelly.
źródło
Perl 5, 43 bytes
42 bytes, plus 1 for
-aE
instead of-e
Input is as decimal integers, space-separated.
A tip of my hat to Sp3000, from whom I took ideas for this answer.
How it works:
-a
,$.
starts at 1 and@F
is the input array.$h
starts at 0.$_
is used bymap
as a placeholder for each element of an array.map$h+=$.+=$_,@F
means that for each element in@F
we add that element to$.
and then add$.
to$h
.$.%65521+$h%65521*4**8
(that is,($. % 65521) + ( ($h % 65521) * (4**8) )
andsay
(print) the result.źródło
Factor,
112109103 bytesNow, this is a literal translation of the algorithm in the question... now that I actually made it, y'know, correct.
Ungolfed:
Expects any sequence of numbers or a string (not much difference, though they aren't technically the same).
I don't know how this will perform for the given limit on a version of Factor compiled with 32-bit word-size, but on my 6GB 64-bit 2.2GHz machine:
źródło
Ruby, 91 bytes
źródło
Clojure, 109 bytes
Based on @Mark Adler's solution.
Ungolfed
Usage
źródło
Javascript (130 Characters Golfed)
Ungolfed
Golfed
Paste into Developers Console and then give it an Array of Bytes EG:
And it will return the checksum to the console
źródło
TMP, 55 bytes
3a1.3b0.1;4+a>T8%a>xFFF14+b>a8%b>xFFF11~5<b>164|b>a2$b$
Implementation in Lua can be found here: http://preview.ccode.gq/projects/TMP.lua
źródło
Python 3.5, 82 bytes:
(-1 byte thanks to Neil!)
(-1 byte thanks to mathmandan!)
(-4 bytes thanks to Dennis!)
An anonymous
lambda
function. Accepts a byte array, applies the entire algorithm to the array, and outputs the result. Has successfully worked for all the test cases. You call this by assigning a variable to it, and then calling that variable just like you would call a normal function. If you are using the shell, then this should output without a print function. However, if you are not, then you must wrap the function call in theprint()
function to actually see the output.Try it online! (Ideone)
źródło
(E+15)
is actually a byte longer than65536
.4**8
is a byte shorter than65536
.Fission, 324 bytes
Fair warning, the only implementation I've tested this on is my own port of the language to F#. It's not golfed, mainly because I found it easier to have a couple of long runs while my prime constant cooled along the bottom, so I may come back and tweak it.
How does it work?
R'~++Y++~'L
block fuses a 256 constant and launches it downwards, setting the mass multiplier of the reactor directly below it.R'~++A++~'A
block fuses another 256 and launches it up towards the reactor above, which fissions the particle into two mass multiples of65536
mass each, launching them left and right (where the right particle is immediately destroyed by the terminator).65521
(our large prime).Z
) at the end of the run causes the particle to duplicate the prime, sending one back to the right where it ultimately sets the stored mass of the fission reactor (^
). This is how we'll be applying the modulus operator to the H block.<
) we'll be using for the L block.|S
"cooling tower".\Y/
fuses the L block (which comes in through the left channel) and the H block (which comes in through the right channel), then slams them into a terminator which sets the exit code to the fused mass.źródło
*
, which is how I'm returning the output. I'll see if I can find another interpreter to verify the output tomorrow.