IA-32 मशीन कोड, 27 बाइट्स
Hexdump:
60 33 db 8b f9 33 c0 92 43 50 f7 f3 85 d2 75 04
ab 93 ab 93 3b c3 5a 77 ec 61 c3
स्रोत कोड (MS Visual Studio सिंटैक्स):
pushad;
xor ebx, ebx;
mov edi, ecx;
myloop:
xor eax, eax;
xchg eax, edx;
inc ebx;
push eax;
div ebx;
test edx, edx;
jnz skip_output;
stosd;
xchg eax, ebx;
stosd;
xchg eax, ebx;
skip_output:
cmp eax, ebx;
pop edx;
ja myloop;
popad;
ret;
पहला पैरामीटर ( ecx
) आउटपुट के लिए एक सूचक है, दूसरा पैरामीटर (edx
) संख्या है। यह किसी भी तरह से उत्पादन के अंत को चिह्नित नहीं करता है; सूची के अंत का पता लगाने के लिए व्यक्ति को शून्य के साथ आउटपुट एरे को प्रीफ़िल करना चाहिए।
एक पूर्ण C ++ प्रोग्राम जो इस कोड का उपयोग करता है:
#include <cstdint>
#include <vector>
#include <iostream>
#include <sstream>
__declspec(naked) void _fastcall doit(uint32_t* d, uint32_t n) {
_asm {
pushad;
xor ebx, ebx;
mov edi, ecx;
myloop:
xor eax, eax;
xchg eax, edx;
inc ebx;
push eax;
div ebx;
test edx, edx;
jnz skip_output;
stosd;
xchg eax, ebx;
stosd;
xchg eax, ebx;
skip_output:
cmp eax, ebx;
pop edx;
ja myloop;
popad;
ret;
}
}
int main(int argc, char* argv[]) {
uint32_t n;
std::stringstream(argv[1]) >> n;
std::vector<uint32_t> list(2 * sqrt(n) + 3); // c++ initializes with zeros
doit(list.data(), n);
for (auto i = list.begin(); *i; ++i)
std::cout << *i << '\n';
}
आउटपुट में कुछ गड़बड़ियाँ हैं, भले ही यह कल्पना का अनुसरण करता हो (छँटाई की कोई आवश्यकता नहीं; विशिष्टता की आवश्यकता नहीं)।
इनपुट: 69
आउटपुट:
69
1
23
3
भाजक जोड़े में हैं।
इनपुट: 100
आउटपुट:
100
1
50
2
25
4
20
5
10
10
सही वर्गों के लिए, अंतिम भाजक दो बार आउटपुट है (यह अपने आप में एक जोड़ी है)।
इनपुट: ३०
आउटपुट:
30
1
15
2
10
3
6
5
5
6
यदि इनपुट एक पूर्ण वर्ग के करीब है, तो अंतिम जोड़ी दो बार आउटपुट है। यह लूप में चेक के आदेश के कारण है: पहले, यह "शेष = 0" और आउटपुट के लिए जांच करता है, और उसके बाद ही लूप से बाहर निकलने के लिए "भागफल <विभाजक" की जांच करता है।
O(sqrt(n))
।