Вот простое решение с использованием целочисленной арифметики:
void check(char boxes[], int total_count, int check_count)
{
int i;
for (i = 0; i < total_count; i++)
boxes[i] = '-';
for (i = 0; i < check_count; i++)
boxes[i * total_count / check_count] = 'x';
}
total_count
- это общее количество блоков, а check_count
- это количество блоков для проверки.
Во-первых,это устанавливает каждую клетку на непроверенную.Затем он проверяет check_count
ящиков, масштабируя счетчик по количеству ящиков.
Предостережение: это смещение влево, а не вправо, как в ваших примерах.То есть печатается x--x--
, а не --x--x
.Вы можете перевернуть его, заменив
boxes[i * total_count / check_count] = 'x';
на:
boxes[total_count - (i * total_count / check_count) - 1] = 'x';
Корректность
Предполагая 0 <= check_count <= total_count
, и что boxes
имеет место как минимум для total_count
пунктов, мы можем доказать, что:
Никакие галочки не будут перекрываться.i * total_count / check_count
увеличивается по крайней мере на одну на каждую итерацию, потому что total_count >= check_count
.
Это не будет переполнять буфер.Индекс i * total_count / check_count
будет >= 0
.i
, total_count
и check_count
будут >= 0
.
будут < total_count
.Когда n > 0
и d > 0
:
(n * d - 1) / d < n
Другими словами, если мы возьмем n * d / d
и подтолкнем числитель вниз, частное тоже уменьшится.
Поэтому(check_count - 1) * total_count / check_count
будет меньше total_count
с учетом сделанных выше предположений.Деление на ноль не произойдет, потому что если check_count
равно 0, рассматриваемый цикл будет иметь нулевые итерации.