2

I have a question about some trying to wrap around a sequence of numbers that I'm trying to shift in the C programming language. The first value that is found in the sequence of numbers I calculate via a loop gets thrown out in the end. Here is what the code looks like right now:

numbers[d] = numbers[x];
for (d = y-1; d >=0; d --){
 numbers[d] = numbers[(d -  1) % y];
 printf(" numbers[d] = %d \n", numbers[d]);
}

Here are the numbers[x] I calculated from my previous loop:

1, 17, 3, 15, 14, 6, 12, 8, 10

Here is what the numbers[d] currently looks like:

17, 3, 15, 14, 6, 12, 8, 10, 10

...and here is what it should look like:

17, 3, 15, 14, 6, 12, 8, 10, 1

It seems like it doesn't wrap the 1 around to the end. Is there a conditional that I am missing in my loop? Thanks!

  • 2
    Welcome to Stack Overflow. Please read the [About] page soon. What is the value of `d` before the loop starts? What is the value of `x`? Note that the `%` (modulus) operator returns a negative value when the dividend is negative and the divisor is positive. When you reach `d == 0`, you are copying from `(d - 1) % y` which is `-1`. – Jonathan Leffler Apr 19 '14 at 02:06

4 Answers4

1

Code

#include <stdio.h>

static const int debug = 0;

static void dump_array(const char *tag, int n, const int array[n])
{
    printf("%s (%d)", tag, n);
    for (int i = 0; i < n; i++)
        printf("%3d", array[i]);
    putchar('\n');
}

static void rot1u(int n, int numbers[n])
{
    int v = numbers[n-1];
    for (int d = n - 1; d >= 0; d--)
    {
        numbers[d] = numbers[(n + d - 1) % n];
        if (debug)
            printf(" numbers[%d] = %d\n", d, numbers[d]);
    }
    numbers[0] = v;

    dump_array("Up After: ", n, numbers);
}

static void rot1d(int n, int numbers[n])
{
    int v = numbers[0];
    for (int d = 0; d < n; d++)
    {
        numbers[d] = numbers[(d + 1) % n];
        if (debug)
            printf(" numbers[%d] = %d\n", d, numbers[d]);
    }
    numbers[n-1] = v;

    dump_array("Dn After: ", n, numbers);
}

int main(void)
{
    int numbers[] = { 1, 17, 3, 15, 14, 6, 12, 8, 10 };
    enum { N_NUMBERS = sizeof(numbers) / sizeof(numbers[0]) };
    dump_array("-- Before:", N_NUMBERS, numbers);

    rot1u(N_NUMBERS, numbers);
    rot1d(N_NUMBERS, numbers);
    rot1d(N_NUMBERS, numbers);
    rot1d(N_NUMBERS, numbers);
    rot1u(N_NUMBERS, numbers);
    rot1u(N_NUMBERS, numbers);

    return 0;
}

Example output

-- Before: (9)  1 17  3 15 14  6 12  8 10
Up After:  (9) 10  1 17  3 15 14  6 12  8
Dn After:  (9)  1 17  3 15 14  6 12  8 10
Dn After:  (9) 17  3 15 14  6 12  8 10  1
Dn After:  (9)  3 15 14  6 12  8 10  1 17
Up After:  (9) 17  3 15 14  6 12  8 10  1
Up After:  (9)  1 17  3 15 14  6 12  8 10
Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
1

Let's analyze your for loop, minus the printf statement.

for (d = y-1; d >=0; d --){
 numbers[d] = numbers[(d -  1) % y];
}

Before you start the loop, you have the following values in numbers.

1, 17, 3, 15, 14, 6, 12, 8, 10

The value of y is 9.

In the first iteration of the loop, d = 8. (d-1)%y = 7. You replace the value of number[8] by number[7]. The array becomes:

1, 17, 3, 15, 14, 6, 12, 8, 8

In the next iteration of the loop, d = 7. (d-1)%y = 6. You replace the value of number[7] by number[6]. The array becomes:

1, 17, 3, 15, 14, 6, 12, 12, 8

When you reach the iteration where d=1, (d-1)%y = 0. You replace the value of number[1] by number[0]. The array becomes:

1, 1, 17, 3, 15, 14, 6, 12, 8

In the next iteration, d=0, (d-1)%y = -1. The statement

 numbers[d] = numbers[(d -  1) % y];

is equivalent to

 numbers[0] = numbers[-1];

This certainly leads to undefined behavior but it doesn't explain the other numbers in your output. Maybe the output that you posted corresponds to a different block of code.

I think the answer by @JonathanLeffler gives a solution to your algorithmic problem. I won't repeat that here.

R Sahu
  • 204,454
  • 14
  • 159
  • 270
0

You need to save the element(s) which should be rotated to the the other side before the loop, and only put it into its proper place (theem into their proper places) afterwards.

Deduplicator
  • 44,692
  • 7
  • 66
  • 118
0
#include <stdio.h>
#include <time.h>
#define METHOD 2
#define MAX_SKIERS 20
int starting_lineup[MAX_SKIERS+1];
int main(void)
{
int i, num_skiers = 20;
srand(time(NULL));
int pos1, pos2, temp;
for (i = 0; i <= num_skiers; i++)
starting_lineup[i] = i;
for (i = 0; i < num_skiers*2; i++) {
// Generate two random positions
pos1 = rand() % num_skiers + 1;
pos2 = rand() % num_skiers + 1;
// Swap the skiers at the two positions
temp = starting_lineup[pos1];
starting_lineup[pos1] = starting_lineup[pos2];
starting_lineup[pos2] = temp;
}
printf("The starting lineup (first to last):\n");
for (i = 1; i <= num_skiers; i++)
printf("%s%d", (i == 1 ? "" : ", "), starting_lineup[i]);
putchar('\n');
return 0;
}
Vinay Guru
  • 79
  • 1
  • 6
  • 19