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
|
#include <iostream>
#include <iomanip>
#include <vector>
#include <random>
#include <functional>
using row_type = std::vector<unsigned>;
using grid_type = std::vector<row_type>;
std::function<unsigned()> get_rng(unsigned min, unsigned max)
{
std::mt19937 generator((std::random_device())());
return [=]() mutable
{
return std::uniform_int_distribution<unsigned>(min, max)(generator);
};
}
// note that max_value is treated as a bit of a suggestion.
// modify rnd_non_multiple if that isn't satisfactory.
grid_type generate_grid(unsigned target, unsigned n_target_values,
unsigned width, unsigned height, unsigned max_value)
{
grid_type grid(height, row_type(width));
// convenience functions
auto rnd_width = get_rng(0, width - 1);
auto rnd_height = get_rng(0, height - 1);
auto factor = get_rng(1, max_value / target);
auto rnd_multiple = [target, &factor] { return factor() * target; };
auto lt_target = get_rng(1, target - 1); // less than target
auto rnd_non_multiple = [&rnd_multiple, <_target]
{ return rnd_multiple() + lt_target(); };
{
// place multiples randomly
unsigned targets_assigned = 0;
while (targets_assigned < n_target_values)
{
unsigned y = rnd_height();
unsigned x = rnd_width();
if (!grid[y][x])
{
grid[y][x] = rnd_multiple();
++targets_assigned;
}
}
}
// fill the rest of the grid with non-multiples
for (auto& row : grid)
for (auto & cell : row)
if (!cell) cell = rnd_non_multiple();
return grid;
}
void display(const grid_type& grid)
{
for (auto& row : grid)
{
for (auto& cell : row)
std::cout << std::setw(3) << cell;
std::cout << '\n';
}
}
void display(const std::vector<unsigned>& v)
{
for (auto& e : v)
std::cout << e << ' ';
std::cout << '\n';
}
std::vector<unsigned> extract_multiples(const grid_type& grid, unsigned val)
{
std::vector<unsigned> mults;
for (auto& row : grid)
for (auto& cell : row)
if (cell % val == 0) mults.push_back(cell);
return mults;
}
int main()
{
unsigned target = 7;
auto grid = generate_grid(target, 10, 5, 5, target * 9);
display(grid);
std::cout << "\nMultiples are:\n\t";
display(extract_multiples(grid, target));
}
|