-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathcount_sparse_numbers.c
113 lines (84 loc) · 1.33 KB
/
count_sparse_numbers.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
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
/*
42dec = 101010bin
nearest power of two (less than n):
32dec = 100000bin
8:
100000
100001
100010
100100
100101
101000
101001
101010
5:
10000
10001
10010
10100
10101
3:
1000
1001
1010
2:
100
101
1:
10
1:
1
Fibonacci!
number of sparse numbers is equal to the sum
of Fibonacci sequence elements
fib(n+2) - 1 = fib(n) + fib(n-1) ... + fib(0)
*/
#include <stdbool.h>
#include <stdio.h>
bool is_sparse(int n) {
while (n) {
if ((n & 3) == 3) return false;
n >>= 1;
}
return true;
}
int nearest_lower_pow_of_two(int n) {
if (n < 1) return -1000;
int pow = 0;
while (n != 1) {
n >>= 1;
pow += 1;
}
return pow;
}
int fib(int n) {
if (n < 0) return -1000;
if (n == 0) return 0;
int prev1;
int prev2 = 0;
int fib = 1;
for (int i = 0; i < n - 1; i++) {
prev1 = prev2;
prev2 = fib;
fib = prev1 + prev2;
}
return fib;
}
int count_sparse_numbers(int n) {
if (n == 0) return 0;
int pow = nearest_lower_pow_of_two(n);
int count = fib(pow + 2);
int two = 1 << pow;
while (two < n) {
two++;
if (is_sparse(two))
count++;
}
return count;
}
int main() {
int n;
if (!scanf("%d", &n)) printf("invalid value");
printf("%d", count_sparse_numbers(n));
return 0;
}