-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathCountNumberDigit.cpp
130 lines (110 loc) · 3.63 KB
/
CountNumberDigit.cpp
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
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
/*
* Puzzle, write function that takes 2 parameters. int and int(char)
* First parameter call Number, can be any digit number
* Second parameter is single digit (0-9)
* write function that will count times of digit is written
* when you traverse from 1..Number in incremental order.
* e.g Number = 51 , Digit 'd' = 4
* Function should print 6 , since traversing 1 to 51 , 4 comes in 4, 14, 24, 34, 44.
* Another eg. N = 103 , d = '7' , result = 20 . Values are 7, 17, 27, 37, 47, 57, 67, 70..77...79, 87, ,97
*/
#include<iostream>
#include<string>
#include<cmath>
#include<algorithm>
#include <bits/stdc++.h>
#include <chrono>
using namespace std;
int countNo(int &, char &); // Simple traversing 1 to N and count d . Order(N)
int calcNo(int &, char &);
int countDig(int cnt, char &ch) ; // Formula use, order O(log(10))
int main(){
int cnt = 0;
cin >> cnt;
char ch = '0';
cin >> ch;
int res = 0;
auto start = chrono::high_resolution_clock::now();
ios_base::sync_with_stdio(false);
res = countNo(cnt, ch);
auto end = chrono::high_resolution_clock::now();
double time_taken =
chrono::duration_cast<chrono::nanoseconds>(end - start).count();
time_taken *= 1e-9;
cout << " Res : " << res << ", time taken : " << fixed << time_taken << setprecision(9) << endl;
start = chrono::high_resolution_clock::now();
ios_base::sync_with_stdio(false);
res = countDig(cnt, ch);
end = chrono::high_resolution_clock::now();
time_taken =
chrono::duration_cast<chrono::nanoseconds>(end - start).count();
time_taken *= 1e-9;
cout << " Res : " << res << ", time taken : " << fixed << time_taken << setprecision(9) << endl;
return 0;
}
int countNo(int & cnt, char &ch){
int res = 0;
string str;
for ( int i = 1; i <= cnt; i++){
str = to_string(i);
if (count(str.begin(), str.end(), ch)){
//cout << str << ", ";
res += count(str.begin(), str.end(), ch);
}
}
cout << endl;
return res;
}
// Experimental function, but doesnt do correction if d = 0
int calcNo(int &cnt, char &ch){
int res=0;
int exp = (int)log10(cnt);
string str = to_string(cnt);
int numberToCount = atoi(string(1,ch).c_str());
int n = 0, prevn=0;
for (int i=0; i<=exp; i++){
n = atoi(string(1,str[exp-i]).c_str());
if ( i == 0) {
if ( n >= numberToCount) res++;
prevn = n;
continue;
}
res += (n*i*((int)pow(10,i-1)));
if ( n == numberToCount)
res += atoi(string(str, exp-i+1).c_str()) + 1;
else if (n > numberToCount)
res += (int)pow(10,i);
}
return res;
}
/*
* Here formula is used, p = log(N) to base 10..
* Result = Sum{ (n_i * 10^(i-1) *i)
* +
* Mod(N,10^i) + 1 ... if n == d
* +
* 10^i .......... if n > d
* } .... for i from 1 .. p
* -
* Sum(10^i) for i from 1..p only if d == 0 // this is for correction..
*
*/
int countDig(int cnt, char &ch) {
int numberToCount = atoi(string(1,ch).c_str());
int exp = (int)log10(cnt);
string str = to_string(cnt);
int n=0;
int res=0; /// final result.
for (int i=0; i<=exp; i++){
n = atoi(string(1,str[exp-i]).c_str());
res += (n *i *((int)pow(10,i-1)));
if (n > numberToCount) res += (int)(pow(10,i));
else if ( n == numberToCount) res += (1 + (cnt%((int)pow(10,i))));
}
if (numberToCount == 0){
int s = 0;
for ( int i = 0 ; i <=exp; i++) s += (int)pow(10,i);
res -= s;
}
return res;
}