well, maybe you're right, so i'll post another task. btw i think he meant odd numbers.
here's my approach, implementing the "sieve of erathostenes" (i think it's spelled like that) in assembler:
Code:
// ASMTest.cpp : Definiert den Einstiegspunkt für die Konsolenanwendung.
//
#include "stdafx.h"
#include <iostream>
#include <iomanip>
typedef unsigned __int32 DWORD;
int _tmain(int argc, _TCHAR* argv[])
{
DWORD a[32768];// = (*)(new DWORD[300]);
DWORD arr_length = sizeof(a) / sizeof(DWORD), upper_bound = (arr_length / 2);
DWORD m_ex;
for (int b = 0; b < arr_length; b ++)
a[b] = 0xFFFFFFFF;
__asm {
; go through all dwords up to AT LEAST the half count
; note on div
; edx:eax / [ecx|ebx] goes to eax (quotient)
; edx:eax % [ecx|ebx] goes to edx (rest)
; here comes the loop
mov ecx, 00h
loop_dword00:
; current value
;mov eax, a[ecx*4]
; push counter for the inner loop
push ecx
; loop through all bits of current dword
mov ecx, 00h
mov ebx, 01h
loop_bits00:
; get dword counter
pop edx
push edx
mov eax, a[edx*4]
mov edx, eax
and edx, ebx
; if bit is 0 move on to next bit
jz ignore00
; calculate bit position to pass as argument
; get dword counter
pop edx
push edx
; push current value & inner counter, bit pattern
;push eax
push ebx
push ecx
; dword counter * 32 + bit counter
mov eax, edx
mov edx, 20h
mul edx
add eax, ecx
add eax, 01h
; call function clearbits only
; if bit position is greater 1
cmp eax, 01h
jbe ignore02
; debug
;cmp eax, 02h
;ja finish
; argument 1
mov m_ex[00h], eax
call clearbits
ignore02:
; restore current value & inner counter, bit pattern
pop ecx
pop ebx
;pop eax
ignore00:
shl ebx, 01h
inc ecx
cmp ecx, 20h
jb loop_bits00
; pop counter
pop ecx
inc ecx
cmp ecx, upper_bound
jbe loop_dword00
; don't execute functions
jmp finish
; clears all bits that are multiples of eax
clearbits:
; argument 1
mov eax, m_ex[00h]
; calculate dword and bit offset
mov edx, 00h
mov ebx, 20h
div ebx
; here comes the loop
mov ecx, eax
mov ebx, edx
loop_dword01:
; calculate new dword and bit offset
push ebx
mov eax, m_ex[00h]
mov edx, 00h
mov ebx, 20h
div ebx
pop ebx
; dword position
add ecx, eax
; bit offset
add ebx, edx
cmp ebx, 20h
jbe ignore01
add ecx, 01h
sub ebx, 20h
ignore01:
cmp ecx, arr_length
jae return01
; current value
mov eax, a[ecx*4]
; ecx is now dword offset
; ebx bit offset, so clear this bit
push ecx
mov cl, bl
sub cl, 01h
mov edx, 01h ; 00000001
shl edx, cl ; 00001000
or eax, edx
xor eax, edx
pop ecx
; store current value
mov a[ecx*4], eax
jmp loop_dword01
return01:
ret
finish:
}
DWORD mask, count = -1;
for (int b = 0; b < arr_length; b ++) {
mask = 0x00000001;
std::cout << "a[" << std::setw(4) << std::setfill('0') << b << "] = [;
for (int i = 0; i < 32; i ++) {
std::cout << (( a[b] & mask) ? (++count, "1") : "0");
mask <<= 1;
}
std::cout << "]" << std::endl;
}
std::cout << "E = " << count << std::endl;
return 0;
}
output is a bit weird, and i haven't measured time, though i think that simply by the use of this algrithm it's faster than the brute-force approach.
ok, here's your next taskyou've got an ip, consisting of four bytes (integer values from 0 to 255). example: 225.152.3.34.
what you should do is paste an algorithm, that transforms this number in a string consisting of letters (only minuscles such as 'a', 'b', not 'A') and numbers from '0' to '9'. the one with the shortest string for all ip's that exist wins the contest.
note that the algorithm has to be reversible!example for 225.152.3.34: your string that your algorithm gives out is 'gb2sl35b1', that makes 9 characters. your algorithm must be able to transform this back to 225.152.3.34.
i'll post my approach later on.
greetings, joey.