x86-64 Машинний код, 7 байт
31 C0
01 C8
E2 FC
C3
Вищеописані байти визначають функцію, яка приймає один параметр, n
і повертає значення, що містить суму всіх цілих чисел від 1 до n
.
Він записується до конвенції про виклики Microsoft x64 , яка передає параметр у ECX
регістр. Повертається значення залишається EAX
, як і всі умови викликів x86 / x86-64.
Невикольована збірна мнемоніка:
xor eax, eax ; zero out EAX
Next: add eax, ecx ; add ECX to EAX
loop Next ; decrement ECX by 1, and loop as long as ECX != 0
ret ; return, with result in EAX
Спробуйте в Інтернеті!
(Виклик функції C там позначається атрибутом, який змушує GCC викликати його за допомогою угоди про виклик Microsoft, яку використовує мій код складання. Якби TIO надав MSVC, це не було б необхідним.)
За незвичайними стандартами кодового гольфу ви бачите, що цей ітеративний циклічний підхід є кращим перед підходами, які використовують більш розумну математичну формулу ( n(n+1) / 2
), хоча він, очевидно, є менш ефективним з точки зору швидкості руху.
Використовуючи теорію чисел, реалізацію стельової кішки все одно можна обіграти на один байт. Кожна з цих інструкцій є важливою, але існує трохи коротше кодування, IMUL
яке використовується EAX
неявно як операнд призначення (насправді він використовує EDX:EAX
, але ми можемо просто ігнорувати верхні 32 біти результату). Це лише 2 байти для кодування, вниз від 3.
LEA
також займає три байти, але насправді цього немає, тому що нам потрібно наростити , зберігаючи початкове значення. Якби ми зробили MOV
копію, тоді INC
ми знаходимося в 4 байти. (У x86-32, де INC
є лише 1 байт, ми знаходимося на тих же 3 байтах, що і LEA
.)
Кінцевий зсув правої частини потрібен для ділення результату навпіл і, безумовно, більш компактний (і більш ефективний), ніж множення. Тим НЕ менше, код повинен бути дійсно використовуючи shr
замість sar
, так як це передбачає , що значення вхідного сигналу, n
, це беззнаковое ціле число. (Це припущення, звичайно, справедливо згідно з правилами, але якщо ви знаєте, що вхід не підписаний, то вам не слід робити підписаний арифметичний зсув, оскільки верхній біт, встановлений у великому неподписаному значенні, спричинить результат бути невірним.)
8D 41 01 lea eax, [rcx+1]
F7 E9 imul ecx
D1 E8 shr eax, 1
C3 ret
Зараз лише 8 байт (завдяки Пітеру Кордесу). Все-таки 8> 7.