Answer the question
In order to leave comments, you need to log in
How to create an array with equidistant elements?
Colleagues help me come up with an algorithm.
Everything seems to be simple, but the head does not cook;
Given:
array(
A=3,
B=6,
C=9
)
Answer the question
In order to leave comments, you need to log in
I have such an idea,
for example, we need to place:
9-A
6-B
3-C
firstly we create an array that will be the answer
secondly we create an array in which empty indices in the output array will be stored
and now the filling itself: we
go from those elements of which are more to those of which there are less
1) insert 9-A
calculate the coefficient = the number of free places in the output array / the number of elements to be inserted
K=18/9=2
at the moment we have such a thing
output array
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
array of empty indices in output
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
further in 2,4,6,8,10,12, 14,16,18 elements are inserted K=2
output array
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
A A A A A A A A A
array of empty indices in output
1 2 3 4 5 6 7 8 9
1 3 5 7 9 11 13 15 17
SECOND STEP
counting for B
K=9/6=1.5
we get indices for uniform distribution, it is worth rounding down
1.5=1
3=3
4.5=4
6=6
7.5=7
9=9
it turns out that these indices in the array empty places are the indices of those places where it is necessary to insert B,
we
get an output array of this type
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
18 times for the triple, we get the same output array
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
B A C A B A B A C A B A B A C A B A
Good results were obtained with one of the first versions with the simplest patch for repetitions.
#include <iostream>
struct Sector
{
char name;
int total, counter, remainder;
bool allowNearby;
};
enum { N = 3 };
Sector secs[] { { 'A', 3 }, { 'B', 6 }, { 'C', 30 } };
int main()
{
int nTotal = 0;
for (int i = 0; i < N; ++i) {
Sector& sec = secs[i];
nTotal += sec.total;
}
for (int i = 0; i < N; ++i) {
Sector& sec = secs[i];
sec.counter = sec.total;
sec.remainder = sec.total;
sec.allowNearby = (sec.total * 2 > nTotal);
}
Sector* repeatS = nullptr;
for (int iSec = 0; iSec < nTotal; ++iSec) {
Sector* bestS = nullptr;
for (int i = 0; i < N; ++i) {
Sector& sec = secs[i];
if (sec.remainder != 0 && &sec != repeatS) {
if (!bestS) { // первый подходящий?
bestS = &sec;
} else { // лучше bestS?
if (sec.counter < bestS->counter
|| (sec.counter == bestS->counter && sec.total > bestS->total))
bestS = &sec;
}
}
}
if (!bestS) // так и не нашли, что брать — берём repeatS
bestS = repeatS;
// пересчитаем счётчик и остаток
bestS->counter += nTotal * 2;
--bestS->remainder;
for (int i = 0; i < N; ++i) {
Sector& sec = secs[i];
sec.counter -= sec.total * 2;
}
repeatS = bestS->allowNearby ? nullptr : bestS;
std::cout << bestS->name;
}
std::cout << std::endl;
}
Didn't find what you were looking for?
Ask your questionAsk a Question
731 491 924 answers to any question