The problem specification is self-inconsistent. It specifies:
x = 0 1 2 3 8 9 10 11 ... 93 94 95 96
y = 4 5 6 7 12 13 14 15 ... 97 98 99 100
There are at least two problems:
- Groups of 4 should start on even numbers, so the last sets are wrongly grouped.
- The
x
line should end with 96 97 98 99
and the y
line should end with 92 93 94 95
(and maybe 100
too, if that should be included in the output).
The code in the question is flawed because of the way it uses k = i; k = i % divisor;
and because there isn't the necessary nested loop structure. I suppose that strictly you could write the code without nested loops, but using nested loops is simpler.
The two lines are a bit inconveniently long for display, so it would be better, perhaps, to wrap them at a suitable length. The code below deals with these various issues. It exploits the fact that printf()
returns the number of characters printed. It ignores the possibility that printf()
returns an error (a negative return value).
#include <stdio.h>
#include <string.h>
/*
** tag = string at start of line
** start = starting value
** finish = last value to be printed
** major = major increment
** minor = number of elements in each sub-sequence
** num_wid = width to use for numbers (1 for minimum width)
** line_wid = wrap lines after this width
*/
static void print_sequence(const char *tag, int start, int finish,
int major, int minor, int num_wid, int line_wid)
{
int count = printf("%s =", tag);
for (int i = start; i <= finish; i += major)
{
for (int j = 0; j < minor && i + j <= finish; j++)
{
if (count > line_wid)
{
putchar('\n');
count = printf("%*s ", (int)strlen(tag), "");
}
count += printf(" %*d", num_wid, i + j);
}
}
putchar('\n');
}
int main(void)
{
print_sequence("x", 0, 100, 8, 4, 2, 70);
print_sequence("y", 4, 100, 8, 4, 2, 70);
print_sequence("x", 0, 100, 8, 4, 2, 160);
print_sequence("y", 4, 100, 8, 4, 2, 160);
print_sequence("x", 0, 100, 8, 4, 3, 70);
print_sequence("y", 4, 100, 8, 4, 3, 70);
return 0;
}
Example output:
x = 0 1 2 3 8 9 10 11 16 17 18 19 24 25 26 27 32 33 34 35 40 41 42
43 48 49 50 51 56 57 58 59 64 65 66 67 72 73 74 75 80 81 82 83 88 89
90 91 96 97 98 99
y = 4 5 6 7 12 13 14 15 20 21 22 23 28 29 30 31 36 37 38 39 44 45 46
47 52 53 54 55 60 61 62 63 68 69 70 71 76 77 78 79 84 85 86 87 92 93
94 95 100
x = 0 1 2 3 8 9 10 11 16 17 18 19 24 25 26 27 32 33 34 35 40 41 42 43 48 49 50 51 56 57 58 59 64 65 66 67 72 73 74 75 80 81 82 83 88 89 90 91 96 97 98 99
y = 4 5 6 7 12 13 14 15 20 21 22 23 28 29 30 31 36 37 38 39 44 45 46 47 52 53 54 55 60 61 62 63 68 69 70 71 76 77 78 79 84 85 86 87 92 93 94 95 100
x = 0 1 2 3 8 9 10 11 16 17 18 19 24 25 26 27 32
33 34 35 40 41 42 43 48 49 50 51 56 57 58 59 64 65
66 67 72 73 74 75 80 81 82 83 88 89 90 91 96 97 98
99
y = 4 5 6 7 12 13 14 15 20 21 22 23 28 29 30 31 36
37 38 39 44 45 46 47 52 53 54 55 60 61 62 63 68 69
70 71 76 77 78 79 84 85 86 87 92 93 94 95 100
You probably shouldn't submit this code as the answer to the homework assignment. It is probably too configurable for it to be safe.
Single loop code
This implementation of the print_sequence()
function presents the same external interface, but the implementation is a bit different.
static void print_sequence(const char *tag, int start, int finish,
int major, int minor, int num_wid, int line_wid)
{
assert(major > 0 && minor > 0 && major > minor);
int count = printf("%s =", tag);
int p_limit = start + minor; // print limit
int c_limit = start + major - 1; // count limit
for (int i = start; i <= finish; i++)
{
if (i < p_limit)
{
if (count > line_wid)
{
putchar('\n');
count = printf("%*s ", (int)strlen(tag), "");
}
count += printf(" %*d", num_wid, i);
}
else if (i == c_limit)
{
p_limit += major;
c_limit += major;
}
}
putchar('\n');
}
This produces the same output as before. It is marginally less efficient than the original, but you'd be hard pressed to measure the cost of incrementing i
a few extra times around the loop.
Also note that both these solutions can print up to num_wid + 1
characters beyond the specified line length. You can fix that by adjusting line_wid
by num_wid + 1
. The code could also check that major
is at least as big as minor
, and that both are strictly positive; also that line_wid
is big enough for the tag, the =
and at least one number. There's an element of GIGO — if you provide bogus parameters, the output will be correspondingly bogus.