Advertisement
Guest User

Untitled

a guest
Aug 23rd, 2017
63
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 10.05 KB | None | 0 0
  1. struct program_args {
  2. long long number;
  3. long double lbound, ubound;
  4. bool ceil, floor, round, trunc; // mutually exclusive
  5. int precision;
  6. std::vector<long double> excluded;
  7. bool norepeat, stat_min, stat_max, stat_median, stat_avg, bad_random, list, quiet;
  8. std::vector<std::string> prefix, suffix, contains;
  9. std::string delim = "n";
  10. };
  11.  
  12. program_args args;
  13.  
  14. returnID parse_args(program_args &args, int argc, char const *const *argv);
  15.  
  16. program_args args;
  17.  
  18. switch (auto result = parse_args(args, ac, av)) {
  19. case returnID::success: break;
  20. case returnID::success_help: return 0;
  21. default: return result;
  22. }
  23.  
  24. if (!args.excluded.empty() && std::find(args.excluded.begin(), args.excluded.end(), rand) != args.excluded.end())
  25. continue;
  26. else if (args.norepeat && std::find(repeated.begin(), repeated.end(), rand) != repeated.end())
  27. continue;
  28. else if (!args.prefix.empty() && fx_vect(rand, args.prefix, fx_enum::prefix))
  29. continue;
  30. else if (!args.suffix.empty() && fx_vect(rand, args.suffix, fx_enum::suffix))
  31. continue;
  32. else if (!args.contains.empty() && fx_vect(rand, args.contains, fx_enum::contains))
  33. continue;
  34.  
  35. while (generated.size() < args.number)
  36.  
  37. if (args.stat_avg) {
  38. long double sum = std::accumulate(generated.begin(), generated.end(), 0.0);
  39. std::cout << "avg: " << sum / generated.size() << 'n';
  40. }
  41.  
  42. #include <algorithm>
  43. #include <boost/program_options.hpp>
  44. #include <boost/algorithm/string/predicate.hpp>
  45. #include <cmath>
  46. #include <iomanip>
  47. #include <iostream>
  48. #include <limits>
  49. #include <random>
  50. #include <vector>
  51.  
  52. enum returnID {
  53. success = 0,
  54. known_err = 1,
  55. other_err = 2,
  56. zero_err = 3,
  57. conflict_err = 4,
  58. overd_err = 5,
  59. underd_err = 6,
  60. exclude_err = 7,
  61.  
  62. success_help = -1,
  63. };
  64.  
  65. bool filter(const long double rand,
  66. int precision,
  67. const std::vector<std::string>& fx,
  68. bool(*predicate)(const std::string&, const std::string&)) {
  69. std::ostringstream oss;
  70. oss << std::fixed << std::setprecision(precision) << rand;
  71. auto const str_rand = oss.str();
  72.  
  73. return std::none_of(fx.begin(), fx.end(), [&](auto const& s) { return predicate(str_rand, s); });
  74. }
  75.  
  76.  
  77. struct program_args {
  78. unsigned long long number;
  79. long double lbound, ubound;
  80. bool ceil, floor, round, trunc; // mutually exclusive
  81. int precision;
  82. std::vector<long double> excluded;
  83. bool norepeat, stat_min, stat_max, stat_median, stat_avg, bad_random, list, quiet;
  84. std::vector<std::string> prefix, suffix, contains;
  85. std::string delim = "n";
  86. };
  87.  
  88. returnID parse_args(program_args &args, int argc, char const *const *argv)
  89. {
  90. static auto const ld_prec = std::numeric_limits<long double>::max_digits10;
  91.  
  92. namespace po = boost::program_options;
  93. po::options_description desc("Options");
  94. desc.add_options()
  95. ("help,h", "produce this help message")
  96. ("number,n", po::value(&args.number)->default_value(1),
  97. "count of numbers to be generated")
  98. ("lbound,l", po::value(&args.lbound)->default_value(0.0),
  99. "minimum number(ldouble) to be generated")
  100. ("ubound,u", po::value(&args.ubound)->default_value(1.0),
  101. "maximum number(ldouble) to be generated")
  102. ("ceil,c", po::bool_switch(&args.ceil)->default_value(false),
  103. "apply ceiling function to numbers")
  104. ("floor,f", po::bool_switch(&args.floor)->default_value(false),
  105. "apply floor function to numbers")
  106. ("round,r", po::bool_switch(&args.round)->default_value(false),
  107. "apply round function to numbers")
  108. ("trunc,t", po::bool_switch(&args.trunc)->default_value(false),
  109. "apply truncation to numbers")
  110. ("precision,p", po::value(&args.precision)->default_value(ld_prec),
  111. "output precision(not internal precision, cannot be > ldouble precision)")
  112. ("exclude,e", po::value<std::vector<long double> >(&args.excluded)->multitoken(),
  113. "exclude numbers from being printed, best with --ceil, --floor, --round, or --trunc")
  114. ("norepeat,x", po::bool_switch(&args.norepeat)->default_value(false),
  115. "exclude repeated numbers from being printed, best with --ceil, --floor, --round, or --trunc")
  116. ("stat-min", po::bool_switch(&args.stat_min)->default_value(false),
  117. "print the lowest value generated")
  118. ("stat-max", po::bool_switch(&args.stat_max)->default_value(false),
  119. "print the highest value generated")
  120. ("stat-median", po::bool_switch(&args.stat_median)->default_value(false),
  121. "print the median of the values generated")
  122. ("stat-avg", po::bool_switch(&args.stat_avg)->default_value(false),
  123. "print the average of the values generated")
  124. ("bad-random", po::bool_switch(&args.bad_random)->default_value(false),
  125. "use srand(time(NULL)) and rand() for generating random numbers(limited by RAND_MAX)")
  126. ("prefix", po::value(&args.prefix)->multitoken(),
  127. "only print when the number begins with string(s)")
  128. ("suffix", po::value(&args.suffix)->multitoken(),
  129. "only print when the number ends with string(s)")
  130. ("contains", po::value(&args.contains)->multitoken(),
  131. "only print when the number contains string(s)")
  132. ("list", po::bool_switch(&args.list)->default_value(false),
  133. "print numbers in a list with positional numbers prefixed")
  134. ("delim", po::value(&args.delim),
  135. "change the delimiter")
  136. ("quiet", po::bool_switch(&args.quiet)->default_value(false),
  137. "disable number output, useful when paired with stats");
  138.  
  139. po::variables_map vm;
  140. po::store(po::parse_command_line(argc, argv, desc), vm);
  141. po::notify(vm);
  142.  
  143. if (vm.count("help")) {
  144. std::cout << desc << 'n';
  145. return returnID::success_help;
  146.  
  147. }
  148. if (args.number <= 0) {
  149. std::cerr << "error: the argument for option '--number' is invalid(n must be >= 1)n";
  150. return returnID::zero_err;
  151.  
  152. }
  153. if (args.ceil + args.floor + args.round + args.trunc > 1) {
  154. std::cerr << "error: --ceil, --floor, --round, and --trunc are mutually exclusive and may only be called oncen";
  155. return returnID::conflict_err;
  156.  
  157. }
  158. if (args.precision > ld_prec) {
  159. std::cerr << "error: --precision cannot be greater than the precision for <long double> ("
  160. << ld_prec << ")n";
  161. return returnID::overd_err;
  162.  
  163. }
  164. if (args.precision <= -1) {
  165. std::cerr << "error: --precision cannot be less than zeron";
  166. return returnID::underd_err;
  167.  
  168. }
  169. if (vm.count("exclude") && vm["exclude"].empty()) {
  170. std::cerr << "error: --exclude was specified without arguments(arguments are separated by spaces)n";
  171. return returnID::exclude_err;
  172. }
  173. return returnID::success;
  174. }
  175.  
  176.  
  177.  
  178. int main(int ac, char* av[]) {
  179. try {
  180. program_args args;
  181.  
  182. switch (auto result = parse_args(args, ac, av)) {
  183. case returnID::success: break;
  184. case returnID::success_help: return 0;
  185. default: return result;
  186. }
  187.  
  188. std::vector<long double> generated;
  189.  
  190. std::random_device rd;
  191. std::mt19937 generator(rd());
  192. std::uniform_real_distribution<long double> dis(args.lbound, args.ubound);
  193.  
  194. if (args.bad_random) std::srand(std::time(NULL));
  195.  
  196. std::cout.precision(args.precision);
  197.  
  198. long long list_cnt = 0;
  199.  
  200. while (generated.size() < args.number) {
  201. long double rand = (args.bad_random) ? args.lbound + (std::rand() / (RAND_MAX / (args.ubound - args.lbound))) : dis(generator);
  202.  
  203. if (args.ceil) rand = std::ceil(rand);
  204. else if (args.floor) rand = std::floor(rand);
  205. else if (args.round) rand = std::round(rand);
  206. else if (args.trunc) rand = std::trunc(rand);
  207.  
  208. if (!args.excluded.empty() && std::find(args.excluded.begin(), args.excluded.end(), rand) != args.excluded.end())
  209. continue;
  210. else if (args.norepeat && std::find(generated.begin(), generated.end(), rand) != generated.end())
  211. continue;
  212. else if (!args.prefix.empty() && filter(rand, args.precision, args.prefix, boost::starts_with))
  213. continue;
  214. else if (!args.suffix.empty() && filter(rand, args.precision, args.suffix, boost::ends_with))
  215. continue;
  216. else if (!args.contains.empty() && filter(rand, args.precision, args.contains, boost::contains))
  217. continue;
  218.  
  219. generated.push_back(rand);
  220.  
  221. if (!args.quiet) {
  222. if (args.list)
  223. std::cout << ++list_cnt << ".t";
  224. std::cout << std::fixed << rand << args.delim;
  225. }
  226. }
  227.  
  228. if (args.delim != "n" && !args.quiet) std::cout << 'n';
  229.  
  230. if ((args.stat_min || args.stat_max || args.stat_median || args.stat_avg) && !args.quiet)
  231. std::cout << 'n';
  232.  
  233. if (args.stat_min || args.stat_max) {
  234. auto minmax = std::minmax_element(generated.begin(), generated.end());
  235. if (args.stat_min)
  236. std::cout << "min: " << *minmax.first << 'n';
  237. if (args.stat_max)
  238. std::cout << "max: " << *minmax.second << 'n';
  239. }
  240. if (args.stat_median) {
  241. auto midpoint = generated.begin() + generated.size() / 2;
  242. std::nth_element(generated.begin(), midpoint, generated.end());
  243. auto median = *midpoint;
  244. if (generated.size() % 2 == 0)
  245. median = (median + *std::min_element(midpoint+1, generated.end())) / 2;
  246. std::cout << "median: " << median << 'n';
  247. }
  248. if (args.stat_avg) {
  249. long double sum = std::accumulate(generated.begin(), generated.end(), 0.0);
  250. std::cout << "avg: " << sum / generated.size() << 'n';
  251. }
  252.  
  253. return returnID::success;
  254.  
  255. } catch(std::exception & e) {
  256. std::cerr << "error: " << e.what() << 'n';
  257. return returnID::known_err;
  258.  
  259. } catch(...) {
  260. std::cerr << "error: exception of unknown type!n";
  261. return returnID::other_err;
  262. }
  263. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement