-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathdivisor_iterator.c
61 lines (50 loc) · 1.36 KB
/
divisor_iterator.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
// Licensed under the MIT License.
#include <math.h>
#include "divisor_iterator.h"
#include "euler.h"
#include "swap.h"
void divisor_begin(DivisorIterator iterator, long long n)
{
iterator->n = n;
iterator->sqrtN = sqrt(n);
iterator->current = 1;
iterator->next = 0;
iterator->state = DIVISOR_ITERATOR_STATE_INITIAL;
}
bool divisor_end(DivisorIterator iterator)
{
if (iterator->state == DIVISOR_ITERATOR_STATE_SWAP)
{
return iterator->next > iterator->sqrtN;
}
return iterator->current > iterator->sqrtN;
}
void divisor_next(DivisorIterator iterator)
{
long long n = iterator->n;
long long end = iterator->sqrtN;
if (iterator->state == DIVISOR_ITERATOR_STATE_SWAP)
{
swap(&iterator->current, &iterator->next, sizeof(long long));
}
if (iterator->state == DIVISOR_ITERATOR_STATE_YIELD)
{
swap(&iterator->current, &iterator->next, sizeof(long long));
iterator->state = DIVISOR_ITERATOR_STATE_SWAP;
return;
}
do
{
iterator->current++;
}
while (iterator->current <= end && n % iterator->current != 0);
if (iterator->current != n / iterator->current)
{
iterator->next = n / iterator->current;
iterator->state = DIVISOR_ITERATOR_STATE_YIELD;
}
else
{
iterator->state = DIVISOR_ITERATOR_STATE_INITIAL;
}
}