x86-Assembly (78 Bytes)
This example uses Intel syntax. Besides, here the fastcall
or register
calling convention is used (the latter from 32-bit Delphi), so the parameter is in ecx
. I also introduce a second parameter that points to a free space for the result and is saved in edx
. A function for allocating memory space would be specific to the operating system and a transfer via the stack would be problematic, so I chose this option.
listSexy:
mov ebp, esp ; 89E5 Save initial esp
mov edi, edx ; 89D7 Save second parameter in edx
; Part One: Save all prime numbers from 3 to the limit on the stack
; (This takes 32 Bytes)
xor eax, eax ; 31C0 set eax = 1 (shorter than mov eax, 1)
inc eax ; 40
checkComplete:
add eax, 2 ; 83C002 Go to next possible number (first is 3)
cmp eax, ecx ; 39C8 Has the limit, i.e. the parameter, been skipped?
jae partTwo ; 7316
mov ebx, esp ; 89E3 Check it against all previous prime numbers
checkNext: ; which are stored between ebp and esp
cdq ; 99 Clear edx for the later division
push eax ; 50 Put the number on the stack
cmp ebx, ebp ; 39E5 Has the check already completed?
je partTwo ; 74F1 The comfirmed prime number remains on stack
mov esi, [ebx] ; 8B33 Load a previous prime
div esi ; F7F6
pop eax ; 58
test edx, edx ; 85D2 Is esi a divider?
je checkComplete ; 74E8
add ebx, 4 ; 83C304 Let ebx point to the next possible divisor
jmp checkNext ; EBEC
; Part Zwo: Check all prime numbers if they are sexy primes
; (This takes 39 Bytes)
partTwo:
mov ebx, ebp ; 89E5 Start with the first prime number, i.e. 3
NextPrime:
sub ebx, 4 ; 83EB04 Let ebx point to the next prime number
cmp ebx, esp ; 39E3 Has the last number been reached? It cant be sexy,
; since it has no successors here
jmp Finished ; 761E
mov edx, ebx ; 89DA Check all successors up to a distance of 6
mov eax, [ebx] ; 8B03 eax is the prime number whose successors are checked
add eax, 6 ; 83C006
GoFurther:
sub edx, 4 ; 83EA04
cmp eax, [edx] ; 8B02
jb NextPrime ; 72EB If the successor is too large, x can no longer be sexy
ja GoFurther ; 77F7 If the successor is too small, take the next one
mov eax, [ebx] ; 8B03 Load eax again (shorter than sub eax, 6)
mov ecx, [edx] ; 8B0A Load the successor which makes eax a sexy prime
mov [edi], eax ; 8907 Store both in their intended place
mov [edi+4], ecx ; 894F04
add edi, 8 ; 83C708
jmp NextPrime ; EBDB
Finished:
mov esp, ebp ; 89EC Restore stack
ret ; C3
The opcodes (and thus the size of the instruction) are given in the comment. The function can be called from C with, for example
int n = 100;
int resultList[50] = { };
listSexy(n, resultList);
The result list should be initialized with zero, since no final null byte sequence or similar is written into.
Online working example: http://tpcg.io/mEPb1Wy9