x 86, 41 39 bajtów
Najczęściej prosta implementacja formuły z wejściem ecx
i wyjściem na stosie.
Interesujące jest to, że użyłem funkcji dzielenia, ale ponieważ call label
jest to 5 bajtów , przechowuję adres etykiety i używam 2 bajtów call reg
. Ponadto, ponieważ wypycham wartości w mojej funkcji, używam jmp
zamiastret
. Jest bardzo możliwe, że bycie sprytnym z pętlą i stosem może całkowicie uniknąć sprawdzania.
Nie robiłem żadnych fantazyjnych sztuczek z kostką, jak używanie (k+1)^3 = k^3 + 3k^2 + 3k + 1
.
Dziennik zmian:
Napraw liczbę bajtów za pomocą not
zamiast neg
/ dec
.
-2 bajty, nie xor
ing, edx
ponieważ prawdopodobnie jest to 0 z imul
.
.section .text
.globl main
main:
mov $10, %ecx # n = 10
start:
lea (cube),%edi # save function pointer
call *%edi # output n^3
sub %ecx, %eax # n^3 - n
# edx = 0 from cube
push $6
pop %ebx # const 6
idiv %ebx # k = (n^3 - n)/6
mov %eax, %ecx # save k
call *%edi # output k^3
push %eax # output k^3
not %ecx # -k-1
call *%edi # output (-k-1)^3
inc %ecx
inc %ecx # -k+1
call *%edi # output (-k+1)^3
ret
cube: # eax = ecx^3
pop %esi
mov %ecx, %eax
imul %ecx
imul %ecx
push %eax # output cube
jmp *%esi # ret
Objdump:
00000005 <start>:
5: 8d 3d 22 00 00 00 lea 0x22,%edi
b: ff d7 call *%edi
d: 29 c8 sub %ecx,%eax
f: 6a 06 push $0x6
11: 5b pop %ebx
12: f7 fb idiv %ebx
14: 89 c1 mov %eax,%ecx
16: ff d7 call *%edi
18: 50 push %eax
19: f7 d1 not %ecx
1b: ff d7 call *%edi
1d: 41 inc %ecx
1e: 41 inc %ecx
1f: ff d7 call *%edi
21: c3 ret
00000022 <cube>:
22: 5e pop %esi
23: 89 c8 mov %ecx,%eax
25: f7 e9 imul %ecx
27: f7 e9 imul %ecx
29: 50 push %eax
2a: ff e6 jmp *%esi
Oto moja wersja testowa, która wykonuje całą kostkę na końcu. Po wypchnięciu wartości na stos pętla kostki zastępuje wartości stosu. Obecnie ma 42 40 bajtów, ale gdzieś powinny być jakieś ulepszenia.
.section .text
.globl main
main:
mov $10, %ecx # n = 10
start:
push %ecx # output n
mov %ecx, %eax
imul %ecx
imul %ecx
sub %ecx, %eax # n^3 - n
# edx = 0 from imul
push $6
pop %ecx # const 6
idiv %ecx # k = (n^3 - n)/6
push %eax # output k
push %eax # output k
not %eax # -k-1
push %eax # output -k-1
inc %eax
inc %eax # -k+1
push %eax # output -k+1
dec %ecx # count = 5
add $20, %esp
cube:
mov -4(%esp),%ebx # load num from stack
mov %ebx, %eax
imul %ebx
imul %ebx # cube
push %eax # output cube
loop cube # --count; while (count)
ret
-10
innego możliwego rozwiązania może być-1000+4574296+4410944-4492125-4492125
na przykład. I czy wolno generować dane wyjściowe,--
czy+-
zamiast+
/-
odpowiednio (tj.3 = 27+-27+-125--64--64
Zamiast3 = 27-27-135+64+64
)?