comprehensions.cpp 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  1. // Range v3 library
  2. //
  3. // Copyright Eric Niebler 2013-present
  4. //
  5. // Use, modification and distribution is subject to the
  6. // Boost Software License, Version 1.0. (See accompanying
  7. // file LICENSE_1_0.txt or copy at
  8. // http://www.boost.org/LICENSE_1_0.txt)
  9. //
  10. // Project home: https://github.com/ericniebler/range-v3
  11. //
  12. #include <chrono>
  13. #include <iostream>
  14. #include <range/v3/all.hpp>
  15. using namespace ranges;
  16. int
  17. main()
  18. {
  19. // Define an infinite range containing all the Pythagorean triples:
  20. auto triples = views::for_each(views::iota(1), [](int z) {
  21. return views::for_each(views::iota(1, z + 1), [=](int x) {
  22. return views::for_each(views::iota(x, z + 1), [=](int y) {
  23. return yield_if(x * x + y * y == z * z,
  24. std::make_tuple(x, y, z));
  25. });
  26. });
  27. });
  28. //// This alternate syntax also works:
  29. // auto triples = iota(1) >>= [] (int z) { return
  30. // iota(1, z+1) >>= [=](int x) { return
  31. // iota(x, z+1) >>= [=](int y) { return
  32. // yield_if(x*x + y*y == z*z,
  33. // std::make_tuple(x, y, z)); };}; };
  34. // Display the first 100 triples
  35. RANGES_FOR(auto triple, triples | views::take(100))
  36. {
  37. std::cout << '(' << std::get<0>(triple) << ',' << std::get<1>(triple)
  38. << ',' << std::get<2>(triple) << ')' << '\n';
  39. }
  40. }
  41. ////////////////////////////////////////////////////////////////////////////////////////////////////
  42. // Benchmark Code
  43. ////////////////////////////////////////////////////////////////////////////////////////////////////
  44. class timer
  45. {
  46. private:
  47. std::chrono::high_resolution_clock::time_point start_;
  48. public:
  49. timer()
  50. {
  51. reset();
  52. }
  53. void reset()
  54. {
  55. start_ = std::chrono::high_resolution_clock::now();
  56. }
  57. std::chrono::milliseconds elapsed() const
  58. {
  59. return std::chrono::duration_cast<std::chrono::milliseconds>(
  60. std::chrono::high_resolution_clock::now() - start_);
  61. }
  62. friend std::ostream &operator<<(std::ostream &sout, timer const &t)
  63. {
  64. return sout << t.elapsed().count() << "ms";
  65. }
  66. };
  67. void
  68. benchmark()
  69. {
  70. // Define an infinite range containing all the Pythagorean triples:
  71. auto triples = views::for_each(views::iota(1), [](int z) {
  72. return views::for_each(views::iota(1, z + 1), [=](int x) {
  73. return views::for_each(views::iota(x, z + 1), [=](int y) {
  74. return yield_if(x * x + y * y == z * z,
  75. std::make_tuple(x, y, z));
  76. });
  77. });
  78. });
  79. static constexpr int max_triples = 3000;
  80. timer t;
  81. int result = 0;
  82. RANGES_FOR(auto triple, triples | views::take(max_triples))
  83. {
  84. int i, j, k;
  85. std::tie(i, j, k) = triple;
  86. result += (i + j + k);
  87. }
  88. std::cout << t << '\n';
  89. std::cout << result << '\n';
  90. result = 0;
  91. int found = 0;
  92. t.reset();
  93. for(int z = 1;; ++z)
  94. {
  95. for(int x = 1; x <= z; ++x)
  96. {
  97. for(int y = x; y <= z; ++y)
  98. {
  99. if(x * x + y * y == z * z)
  100. {
  101. result += (x + y + z);
  102. ++found;
  103. if(found == max_triples)
  104. goto done;
  105. }
  106. }
  107. }
  108. }
  109. done:
  110. std::cout << t << '\n';
  111. std::cout << result << '\n';
  112. }