C++ Library Extensions 2022.12.09
To help learn modern C++ programming
generate_table.cpp
Go to the documentation of this file.
1/*
2 Author: Thomas Kim
3 First Edit: July 24, 2021
4
5 Factorial - https://en.wikipedia.org/wiki/Factorial
6
7 k-permutations of n - (nPr)
8 Permutation - https://en.wikipedia.org/wiki/Permutation
9
10 k-combinations of n - (nCr)
11 Combination - https://en.wikipedia.org/wiki/Combination
12
13 Factorial Calculator (x!)
14 https://keisan.casio.com/exec/system/1273504815
15
16 Permutation Calculator (nPr)
17 https://keisan.casio.com/exec/system/1223622949
18
19 Combinations Calculator (nCr)
20 https://www.calculatorsoup.com/calculators/discretemathematics/combinations.php
21
22 generate_table.exe max_permu max_combi > permu_combi_table.cxx
23
24 Example> generate_table.exe 100 100 > permu_combi_table.cxx
25*/
26
28
29// #define INCLUDE_PERMU_COMBI_TABLE
30#include "cpg_rational.hpp"
31
32namespace crn = cpg::rational_number;
33
34auto factorial(unsigned long long n)
35{
36 std::optional<unsigned long long> result;
37
38 unsigned long long old;
39 unsigned long long f = 1;
40 bool success = true;
41
42 for(unsigned long long k = 1; k <= n; ++k)
43 {
44 old = f; f *= k;
45
46 if(old != f / k)
47 {
48 success = false; break;
49 }
50 }
51
52 if(success) result = f;
53
54 return result;
55}
56// end of function factorial()
57
58auto nPr(unsigned long long n, unsigned long long r = 1)
59{
60 std::optional<unsigned long long> result;
61
62 unsigned long long old_value;
63 unsigned long long new_value = 1;
64 bool success = true;
65
66 for(unsigned long long k = 0; k < r; ++k)
67 {
68 old_value = new_value;
69 new_value *= (n-k);
70
71 if(old_value != (new_value / (n-k)))
72 {
73 success = false; break;
74 }
75 }
76
77 if(success) result = new_value;
78
79 return result;
80}
81// end of function nPr()
82
83auto nCr(unsigned long long n, unsigned long long r)
84{
85 /* nPr (n - 0) x (n - 1) x .... x (n - (r-1) )
86 nCr * r! = nPr => nCr = ---------- = -----------------------------------------
87 r! (r-0) x (r - 1) x .....x (r - (r-1) )
88
89
90 nCr, r = 0 => 1, r = n => 1
91 nCr = nCn-r, r = min{ r, n-r }
92 */
93
94 std::optional<unsigned long long> result;
95
96 if(r == 0 || r == n)
97 {
98 result = 1; return result;
99 }
100
101 if ( r > (n-r) ) r = n-r;
102
105
106 bool success = true;
107
108 for(unsigned long long k = 0; k < r; ++k)
109 {
110 auto value = crn::rational<unsigned long long>{n - k, r - k};
111
112 old_value = new_value;
113 new_value *= value;
114
115 if(old_value != (new_value / value))
116 {
117 success = false; break;
118 }
119 }
120
121 if(success)
122 result = (unsigned long long)new_value;
123
124 return result;
125}
126// end of function nCr()
127
128auto nCr_naive(unsigned long long n, unsigned long long r)
129{
130 /* nPr (n - 0) x (n - 1) x .... x (n - (r-1) )
131 nCr * r! = nPr => nCr = ---------- = -----------------------------------------
132 r! (r-0) x (r - 1) x .....x (r - (r-1) )
133
134
135 nCr, r = 0 => 1, r = n => 1
136 nCr = nCn-r, r = min{ r, n-r }
137 */
138
139 std::optional<unsigned long long> result;
140
141 if(r == 0 || r == n)
142 {
143 result = 1; return result;
144 }
145
146 if ( r > (n-r) ) r = n-r;
147
148 auto npr = nPr(n, r);
149 auto r_fact = factorial(r);
150
151 if(!npr.has_value())
152 {
153 // std::cout <<"Failed to compute " << n << "_C_" << r << std::endl;
154 return result;
155 }
156
157 if(!r_fact.has_value())
158 {
159 // std::cout <<"Failed to compute " << r << "!" <<std::endl;
160 return result;
161 }
162
163 result = (unsigned long long) npr.value() / r_fact.value();
164
165 return result;
166
167}
168// end of function nCr_naive()
169
171{
172 std::cout <<"\tconst std::vector<unsigned long long> factorial_table\n";
173 std::cout <<"\t{"<<std::endl;
174
175 for(unsigned long long n = 0; n < 21; ++n)
176 {
177 auto f = factorial(n);
178
179 if(f)
180 {
181 if(n == 0)
182 std::cout <<"\t\t/* " <<n<<"! */ ";
183 else
184 std::cout <<"\t\t/* " <<n<<"! */ ,";
185
186 std::cout << f.value() <<"ull"<<std::endl;
187 }
188 }
189
190 std::cout <<"\t};\n\t// end of factorial_table" << std::endl << std::endl;
191}
192// end of generate_factorial()
193
194void generate_permutation_table(unsigned long long limit = 100)
195{
196 std::cout <<"\tconst std::vector<std::vector<unsigned long long>> permutation_table" << std::endl;
197 std::cout <<"\t{" << std::endl;
198
199 for(unsigned long long n = 0; n <= limit; ++n)
200 {
201 if(n == 0)
202 std::cout <<"\t\t{ ";
203 else
204 std::cout <<",\n\t\t{ ";
205
207
208 for(unsigned long long r = 0; r <= n; ++r)
209 {
210 auto npr = nPr(n, r);
211
212 if(npr.has_value())
213 {
214 std::cout <<"\t\t\t/* " <<n << "_P_" << r << " */ ";
215
216 if(r != 0) std::cout << ", ";
217
218 std::cout << npr.value() <<"ull"<<std::endl;
219 }
220 else break;
221 }
222
223 std::cout <<"\t\t}";
224 }
225
226 std::cout <<"\n\t};" << std::endl;
227 std::cout <<"\t// end of permutation_table" << std::endl << std::endl;
228}
229// end of generate_permutation_table()
230
231void generate_combination_table(unsigned long long limit = 100)
232{
233 std::cout <<"\tconst std::vector<std::vector<unsigned long long>> combination_table" << std::endl;
234 std::cout <<"\t{" << std::endl;
235
236 for(unsigned long long n = 0; n <= limit; ++n)
237 {
238 if(n == 0)
239 std::cout <<"\t\t{ ";
240 else
241 std::cout <<",\n\t\t{ ";
242
244
245 for(unsigned long long r = 0; r <= (n/2) ; ++r)
246 {
247 auto ncr = nCr(n, r);
248
249 if(ncr.has_value())
250 {
251 std::cout <<"\t\t\t/* " <<n << "_C_" << r << " */ ";
252
253 if(r != 0) std::cout << ", ";
254
255 std::cout << ncr.value() <<"ull"<<std::endl;
256 }
257 else break;
258 }
259
260 std::cout <<"\t\t}";
261 }
262
263 std::cout <<"\n\t};" << std::endl;
264 std::cout <<"\t// end of combination_table" << std::endl;
265}
266// end of generate_combination_table()
267
268void generate_combination_table_naive(unsigned long long limit = 100)
269{
270 std::cout <<"\tconst std::vector<std::vector<unsigned long long>> combination_table" << std::endl;
271 std::cout <<"\t{" << std::endl;
272
273 for(unsigned long long n = 0; n <= limit; ++n)
274 {
275 if(n == 0)
276 std::cout <<"\t\t{ ";
277 else
278 std::cout <<",\n\t\t{ ";
279
281
282 for(unsigned long long r = 0; r <= (n/2) ; ++r)
283 {
284 auto ncr = nCr_naive(n, r);
285
286 if(ncr.has_value())
287 {
288 std::cout <<"\t\t\t/* " <<n << "_C_" << r << " */ ";
289
290 if(r != 0) std::cout << ", ";
291
292 std::cout << ncr.value() <<"ull"<<std::endl;
293 }
294 }
295
296 std::cout <<"\t\t}";
297 }
298
299 std::cout <<"\n\t};" << std::endl;
300 std::cout <<"\t// end of combination_table" << std::endl;
301}
302// end of generate_combination_table_naive()
303
304void generate_table(unsigned long long permu = 50, unsigned long long combi = 100)
305{
306 std::cout << "#include<vector>\n" << std::endl;
307
308 std::cout <<"namespace cpg::rational_number\n{"<< std::endl;
309
311
313
315
316 std::cout <<"}\n// end of namespace cpg::rational_number"<< std::endl;
317}
318
319int main(int argc, char** argv)
320{
321 if(argc==3)
322 {
323 size_t permu = std::atoi(argv[1]);
324 size_t combi = std::atoi(argv[2]);
325
326 generate_table(permu, combi);
327 }
328 else
329 {
330 std::cout <<" generate_table max_permu max_combi > filename.cxx"<<std::endl;
331 std::cout <<"\tmax_permu - upper limit of permutation"<<std::endl;
332 std::cout <<"\tmax_combi - upper limit of combination"<<std::endl<<std::endl;
333 std::cout <<"\tExample> generate_table.exe 50 100 > permu_combi_table.cxx"<<std::endl;
334 }
335}
auto & cout
auto & endl
void generate_combination_table_naive(unsigned long long limit=100)
int main(int argc, char **argv)
void generate_permutation_table(unsigned long long limit=100)
auto nCr(unsigned long long n, unsigned long long r)
auto factorial(unsigned long long n)
void generate_combination_table(unsigned long long limit=100)
void generate_table(unsigned long long permu=50, unsigned long long combi=100)
auto nCr_naive(unsigned long long n, unsigned long long r)
void generate_factorial_table()
auto nPr(unsigned long long n, unsigned long long r=1)
enable_if_all_in_list_t< types::type_list_t< Type1, Type2 >, integral_list_t, ReturnType > npr(Type1 nn, Type2 rr)
Definition: tpf_ncrnpr.hpp:428
enable_if_all_in_list_t< types::type_list_t< Type1, Type2 >, integral_list_t, ReturnType > ncr(Type1 nn, Type2 rr)
Definition: tpf_ncrnpr.hpp:390