In the middle of matrix is number x. Matrix is filled with x in a spiral, while the rest is filled with y.
Example:
int x=4, y=6, v=7, s=9;
OUTPUT:
6 6 6 6 6 6 6 6 4
4 4 4 4 4 4 4 6 4
4 6 6 6 6 6 4 6 4
4 6 4 4 x 6 4 6 4
4 6 4 6 6 6 4 6 4
4 6 4 4 4 4 4 6 4
4 6 6 6 6 6 6 6 4
Note: In the output instead of the letter x program should print 4, but I wrote x to make it easier for understanding task.
Spiral filling looks like --> this
#include <stdio.h>
int main() {
int v = 7, s = 9, x = 4, y = 6, mat[7][9], i, j, l, k;
for (i = 0; i < v; i++)
for (j = 0; j < s; j++)
mat[i][j] = y;
for (i = 0; i < v; i++) {
for (j = 0; j < s; j++) {
// spiral goes here
// mat[i][j] = x;
}
}
for (i = 0; i < v; i++) {
for (j = 0; j < s; j++)
printf("%4d", mat[i][j]);
printf("\n");
}
return 0;
}
EDIT: After applying suggestions, now the whole matrix is filled with y. How to make it fill spiral with x?
Below is a program for constructing a spiral from the center in an s by v matrix.
Here's the algorithm:
The matrix is filled with y values
Calculating the center, the cursor cx, cy is set there, 0 is written
The spiral drawing direction is set, dir, 1 - left, 2 - down, 3 - right, 4 - up, first 1
Draw 1 step by setting x value to matrix
If the value in the matrix for dir+1 (if dir+1=5 then dir=1) = y (empty) then dir is incremented by +1. If not (center (0) or already drawn (x)) then dir remains the same.
If beyond the edge of the matrix, then dir is incremented +1 as if empty, but nothing is drawn.
Step 4 is repeated s*v/2 times
The program is compiled with the gcc compiler.
Output:
cx - 4, xy - 3
6 6 6 6 6 6 6 6 4
4 4 4 4 4 4 4 6 4
4 6 6 6 6 6 4 6 4
4 6 4 4 0 6 4 6 4
4 6 4 6 6 6 4 6 4
4 6 4 4 4 4 4 6 4
4 6 6 6 6 6 6 6 4
Required:
6 6 6 6 6 6 6 6 4
4 4 4 4 4 4 4 6 4
4 6 6 6 6 6 4 6 4
4 6 4 4 x 6 4 6 4
4 6 4 6 6 6 4 6 4
4 6 4 4 4 4 4 6 4
4 6 6 6 6 6 6 6 4
#include <stdio.h>
/*
Increase dir
*/
int incdir (int dir) {
// direction, 1 - left, 2 - down, 3 - right, 4 - up
dir++;
if (dir==5) dir=1;
return dir;
}
/*
Is coord in matrix
*/
int inmat (int y, int x, int v, int s) {
// direction, 1 - left, 2 - down, 3 - right, 4 - up
if (x<0 || x>=s) return 0;
if (y<0 || y>=v) return 0;
return 1;
}
/*
Value in some direction
*/
int dirval(int cx, int cy, int v, int s, int dir, int mat[v][s]) {
// direction, 1 - left, 2 - down, 3 - right, 4 - up
if (dir==1) {
if (!inmat(cy, cx-2, v, s)) return -1;
return mat[cy][cx-2];
}
if (dir==2) {
if (!inmat(cy+2, cx, v, s)) return -1;
return mat[cy+2][cx];
}
if (dir==3) {
if (!inmat(cy, cx+2, v, s)) return -1;
return mat[cy][cx+2];
}
if (dir==4) {
if (!inmat(cy-2, cx, v, s)) return -1;
return mat[cy-2][cx];
}
}
int main() {
int v = 7, s = 9, x = 4, y = 6, mat[7][9], i, j, l, k;
// cursor
int cx, cy;
cx=((int)s/2);
cy=((int)v/2);
printf("cx - %4d, xy - %4d\n", cx, cy);
int dir=1; // direction, 1 - left, 2 - down, 3 - right, 4 - up
int dv;
for (i = 0; i < v; i++)
for (j = 0; j < s; j++)
mat[i][j] = y;
mat[cy][cx]=0; // start
// spiral goes here
for (i = 0; i < s*v/2; i++) {
if (dir==1) {
if (inmat(cy, cx-1, v, s)) mat[cy][cx-1]=x;
if (inmat(cy, cx-2, v, s)) mat[cy][cx-2]=x;
cx=cx-2;
}
if (dir==2) {
if (inmat(cy+1, cx, v, s)) mat[cy+1][cx]=x;
if (inmat(cy+2, cx, v, s)) mat[cy+2][cx]=x;
cy=cy+2;
}
if (dir==3) {
if (inmat(cy, cx+1, v, s)) mat[cy][cx+1]=x;
if (inmat(cy, cx+2, v, s)) mat[cy][cx+2]=x;
cx=cx+2;
}
if (dir==4) {
if (inmat(cy-1, cx, v, s)) mat[cy-1][cx]=x;
if (inmat(cy-2, cx, v, s)) mat[cy-2][cx]=x;
cy=cy-2;
}
dv=dirval(cx, cy, v, s, incdir(dir), mat);
if (dv==y || dv==-1) dir=incdir(dir);
}
for (i = 0; i < v; i++) {
for (j = 0; j < s; j++)
printf("%4d", mat[i][j]);
printf("\n");
}
return 0;
}
In the first iteration of the inner loop if (i == v / 2 && j == s / 2) is always false so you keep doing:
mat[l][k--] = x; // Decrement k
mat[l++][j] = y; // Increment l
Now add the inner-loop:
------ Increment k
|
for (k = j; k < s; k++) {
//if (i == v / 2 && j == s / 2) // Always false when i is zero
// mat[i][j] = x;
//else
{
mat[l][k--] = x; // Decrement k
mat[l++][j] = y; // Increment l
}
}
So you decrement k and the increment k in the for loop. In other words - k doesn't change and you have an endless loop. In that endless loop you keep incrementing l and use it as array index. That will access the array out of bounds and crash your program.
Related
I just worked to my final exam with simple codes; when I try to sorting strings, I face annoying error. Why 2 is not smaller than 10 on my CodeBlocks IDE but is smaller than 10 on real and onlinegdb.com?
This is the annoying code:
#include <string.h>
#include <stdio.h>
#define STR_SIZ 20
int main()
{
char strArr[][STR_SIZ] = {"abc", "hdas", "sdfasf", "kakldf", "caksl", "casd", "keam", "cznjcx", "mnxzv", "jkalkds"};
char minStr[STR_SIZ];
strcpy(minStr, strArr[0]);
int N = sizeof(strArr)/sizeof(minStr);
// int N = 10;
for(int x = 0; x < N-1; x++)
{
printf("%d", x);
strcpy(minStr,strArr[x]);
int j;
for(j=1+x; j < 10; j++)
{
printf("%4d\n", j);
int cmp = strcmp(strArr[j], minStr);
if(cmp < 0)
strcpy(minStr,strArr[j]);
}
char temp[STR_SIZ];
strcpy(temp,strArr[x]);
strcpy(strArr[x], minStr);
strcpy(strArr[j], temp);
}
return 0;
}
Output on onlinegdb.com:
0 1
2
3
4
5
6
7
8
9
1 2
3
4
5
6
7
8
9
2 3
4
5
6
7
8
9
3 4
5
6
7
8
9
4 5
6
7
8
9
5 6
7
8
9
6 7
8
9
7 8
9
8 9
Output on CodeBlocks:
0 1
2
3
4
5
6
7
8
9
1 2
3
4
5
6
7
8
9
2
PS: I just have used Codeblock in the morning and it was okey with executing.
strArr has 10 elements. At the end of your loop, you call strcpy(strArr[j], temp);. This will write to strArr[10], which is out of bounds and will overwrite some unknown memory. Anything can happen after that.
You should save the j value when you copy a string into minStr.
FYI, your code above prints this as your final string order with onlinegdb:
abc
caksl
caksl
caksl
caksl
casd
cznjcx
cznjcx
jkalkds
jkalkds
So I think you have other problems as well.
try this
#include <string.h>
#include <stdio.h>
#define STR_SIZ 20
int main()
{
char strArr[][STR_SIZ] = {"abc", "hdas", "sdfasf", "kakldf", "caksl", "casd", "keam", "cznjcx", "mnxzv", "jkalkds"};
strcpy(minStr, strArr[0]);
// Calculate the number of elements this way.
const int N = sizeof(strArr)/sizeof(strArr[0]);
// int N = 10;
for(int x = 0; x < N-1; x++)
{
printf("%d", x);
int j;
for(j=1+x; j < N; j++) // Use N here too!
{
printf("%4d\n", j);
int cmp = strcmp(strArr[j], strArr[x]);
if(cmp < 0)
{
// Do the swaps only when needed.
char temp[STR_SIZ];
strcpy(temp,strArr[x]);
strcpy(strArr[x], strArr[j]);
strcpy(strArr[j], temp);
}
}
}
// Verify result
for(int x = 0; x < N; x++) printf("%s\n", strArr[x]);
return 0;
}
I moved your swap into your if check and got rid of your minStr as it was not needed. Notice how I calculate the N size too. Honestly, you were close, but you needed to verify your output.
I'm trying to implement a simple game where the array symbolizes people standing in a circle, drawing an integer at the beginning of the game. each iteration is the size of the integer and removes people from the game.
so if array[]={a,b,c,d} and integer=3;
c is the first to be removed. Then b , then d. the winner is a.
at the end I need to print the array with the results by order of removal. so the printed array should be: a, d, b, c.
I'm trying to accomplish this only with use of pointers with no additional arrays.
Here's what i got, the problem is i'm trying to restart the for loop from the correct index and iterate through the remaining players who have not yet lost and cant get it right:
char *names[] = {"Tyrion Lannister","Daenerys Targaryen","Jon Snow","Arya Stark","Theon Greyjoy", "Joffrey Baratheon","Khal Drogo","Ted Mosby","Marshall Eriksen","Robin Scherbatsky","Barney Stinson", "Lily Aldrin", "Tracy McConnell", "Ted Mosby", "Leonard Hofstadter","Sheldon Cooper", "Penny", "Howard Wolowitz", "Raj Koothrappali", "Bernadette Rostenkowski-Wolowitz","Amy Farrah Fowler", "Gregory House", "Lisa Cuddy", "James Wilson","Eric Foreman", "Allison Cameron", "Robert Chase" ,"Lawrence Kutner", "Chris Taub","Remy 13 Hadley", "Amber Volakis"};
int Length = 31;
int number = 10;
char *tmp;
int i = 0, j;
int boom = number;
for (int i = number - 1; i < Length; i += boom - 1)
{
tmp = *(names + i);
for (int index = i; index < Length - 1; index++)
{
*(names + index) = *(names + index + 1);
}
*(names + Length - 1) = tmp;
Length--;
if (((number - 1) + i) >= Length)
{
int tempIndex = i;
i = tempIndex - Length;
printf("tmep index is %d, i is %d, Length is %d\n", tempIndex, i, Length);
}
}
for (i = 0; i < 31; i++)
printf("%s\n", names[i]);
I also tried another way with % operator, but couldn't quite get it done. Help would be much appreciated:
for (int i = number - 1; i < Length * (number - 1); i += boom - 1)
{
int t = i % Length;
printf("%d\n", t);
if (t < size)
{
counter++;
tmp = *(names + t);
// tmptwo = *(names + 31 - j);
for (int index = t; index < size - 1; index++)
{
*(names + index) = *(names + index + 1);
}
*(names + size - 1) = tmp;
size--;
printf("size %d\n", size);
}
}
You are thinking along the correct lines, but this is one circumstance where declaring and defining a simple function to shift elements down within an array moving the losing index to the end will simplify your life. By doing it this way, your only chores within the body of your code will be to provide the losing index and keeping track of the live number of players that remain with a simple counter.
An implementation of a function to move a given index to the last index for a given size could be similar to the following where a is the array to be reordered, elem_idx is the element index to move to the last element within sz elements:
void element_to_last (int *a, int elem_idx, int sz)
{
if (elem_idx > sz - 1) { /* valdate index in range */
fprintf (stderr, "error: index %d out of range for size %d\n",
elem_idx, sz);
return;
}
int i = elem_idx, /* declare, initialize i, tmp */
tmp = *(a + i);
if (elem_idx == sz - 1) /* elem_idx is last index */
return; /* no-swap */
for (; i < sz - 1; i++) /* loop shifting elements down */
*(a + i) = *(a + i + 1);
*(a + i) = tmp; /* set last to tmp */
}
(note: you will want to validate the element index to move to the end is within the valid range of indexes, and there is no need to perform the swap if the losing index is already the last in range).
A short working example where the WRAP constant simply controls output of no more than WRAP values per-line when printing results and the added DEBUG define allows outputting of additional information showing each operation if -DDEBUG is included in your compile string, e.g.
#include <stdio.h>
#ifndef WRAP
#define WRAP 10
#endif
void element_to_last (int *a, int elem_idx, int sz)
{
if (elem_idx > sz - 1) { /* valdate index in range */
fprintf (stderr, "error: index %d out of range for size %d\n",
elem_idx, sz);
return;
}
int i = elem_idx, /* declare, initialize i, tmp */
tmp = *(a + i);
if (elem_idx == sz - 1) { /* elem_idx is last index */
#ifdef DEBUG
fprintf (stderr, " index %d (%d) is last index %d - no swap.\n",
elem_idx, tmp, sz - 1);
#endif
return; /* no-swap */
}
#ifdef DEBUG
printf (" index %d (%d) to end %d\n", elem_idx, tmp, sz - 1);
#endif
for (; i < sz - 1; i++) /* loop shifting elements down */
*(a + i) = *(a + i + 1);
*(a + i) = tmp; /* set last to tmp */
}
void prn_array (int *a, int sz, int wrap)
{
for (int i = 0; i < sz; i++) {
if (i && i % wrap == 0)
putchar ('\n');
printf (" %2d", *(a + i));
}
putchar ('\n');
}
int main (void) {
int a[] = {0,1,2,3,4,5,6,7,8,9}, /* original array order */
sz = sizeof a/sizeof *a, /* nelem in original */
n = sz, /* n tracks remaining size */
loser[] = {2,0,7,3,2,3,2,1,1}, /* order of losing indexes */
lsz = sizeof loser/sizeof *loser; /* nelem in loser array */
puts ("before:");
prn_array (a, sz, WRAP);
puts ("\nelimination\n(remove indexes 2,0,7,3,2,3,2,1,1):");
for (int i = 0; i < lsz; i++) {
element_to_last (a, loser[i], n > 0 ? n-- : n);
prn_array (a, sz, WRAP);
}
puts ("\nafter:");
prn_array (a, sz, WRAP);
}
(note: the remaining players, e.g. the remaining number of elements is tracked with n while sz preserves the original size of the full array. lsz is used for the size of the loser array)
Example Use/Output
Without DEBUG defined, the output simply shows the state of the array after a loser is moved to the end of the remaining players:
$ ./bin/array_rotate
before:
0 1 2 3 4 5 6 7 8 9
elimination
(remove indexes 2,0,7,3,2,3,2,1,1):
0 1 3 4 5 6 7 8 9 2
1 3 4 5 6 7 8 9 0 2
1 3 4 5 6 7 8 9 0 2
1 3 4 6 7 8 5 9 0 2
1 3 6 7 8 4 5 9 0 2
1 3 6 8 7 4 5 9 0 2
1 3 8 6 7 4 5 9 0 2
1 8 3 6 7 4 5 9 0 2
1 8 3 6 7 4 5 9 0 2
after:
1 8 3 6 7 4 5 9 0 2
DEBUG Output
With DEBUG defined, additional information showing each index and (value) being moved to the end index shown, along with a note whether then end index was the loser in which case "no-swap" was attempted:
$ ./bin/array_rotate
before:
0 1 2 3 4 5 6 7 8 9
elimination
(remove indexes 2,0,7,3,2,3,2,1,1):
index 2 (2) to end 9
0 1 3 4 5 6 7 8 9 2
index 0 (0) to end 8
1 3 4 5 6 7 8 9 0 2
index 7 (9) is last index 7 - no swap.
1 3 4 5 6 7 8 9 0 2
index 3 (5) to end 6
1 3 4 6 7 8 5 9 0 2
index 2 (4) to end 5
1 3 6 7 8 4 5 9 0 2
index 3 (7) to end 4
1 3 6 8 7 4 5 9 0 2
index 2 (6) to end 3
1 3 8 6 7 4 5 9 0 2
index 1 (3) to end 2
1 8 3 6 7 4 5 9 0 2
index 1 (8) is last index 1 - no swap.
1 8 3 6 7 4 5 9 0 2
after:
1 8 3 6 7 4 5 9 0 2
Look things over and let me know if you have further questions.
This code should solve the problem by using modulo.
int size = 31;
int inc = 10;
for (int i = 0; i < size; i++)
{
int t = ((i + 1) * inc) % (size - i);
int *tmp = *(names + t);
printf("%d\n", t);
for (int j = t; j < (size - 1); j++)
{
*(names + j) = *(names + j + 1);
}
*(names + size - 1) = tmp;
}
Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 6 years ago.
Improve this question
I am having trouble with implementing the sort function on pset3. I have used the GDB and found that my sort function does not sort anything. I am not sure if there is a syntax issue, or if the logic is a bit screwed up.
void sort(int values[], int n)
{
for (int k = 0; k < n; k++)
{
for (int j = 0; j < n; j++)
{
if (values[k] >= values[j])
{
int temp = values[k];
values[k] = values[j];
values[j] = temp;
}
}
}
}
You are close, but your loops are not quite right - change:
for (int k = 0; k < n; k++)
{
for (int j = 0; j < n; j++)
{
to:
for (int k = 0; k < n - 1; k++)
{
for (int j = k + 1; j < n; j++)
{
To understand why you need to make this change, consider that the inner loop (j) need only compare elements above index k with the current element at index k. So the outer loop (k) needs to iterate from 0 to n - 2 (one less than the last element), and for each outer loop iteration the inner loop needs to iterate from k + 1 (first element above k) to n - 1 (the last element).
NOTE: by pure chance it seems that the original code does appear to work correctly, even though it appears at first glance that it shouldn't. I have tested it with various edge cases and even though it performs many redundant swaps, the final result always seems to be sorted (suprisingly though the output is in descending order whereas the fixed code generates results in ascending order, as expected). Credit to Jonathan Leffler for spotting this - see his answer and demo program.
One other minor point -- this test:
if (values[k] >= values[j])
should really just be:
if (values[k] > values[j])
It's not incorrect as it stands (the code will still work), but there is no point in swapping elements that are equal, so it's somewhat inefficient as written.
I took your code and converted into a complete program. It's larger than an MCVE because it has support code for shuffling arrays, and for printing results, as well as a main() that exercises these, of course.
#include <stdio.h>
#include <stdlib.h>
static int rand_int(int n)
{
int limit = RAND_MAX - RAND_MAX % n;
int rnd;
while ((rnd = rand()) >= limit)
;
return rnd % n;
}
static void shuffle(int *array, int n)
{
for (int i = n - 1; i > 0; i--)
{
int j = rand_int(i + 1);
int tmp = array[j];
array[j] = array[i];
array[i] = tmp;
}
}
static void print_array(int n, int a[n])
{
for (int i = 0; i < n; i++)
printf(" %d", a[i]);
putchar('\n');
}
static void sort(int values[], int n)
{
for (int k = 0; k < n; k++)
{
for (int j = 0; j < n; j++)
{
if (values[k] >= values[j])
{
int temp = values[k];
values[k] = values[j];
values[j] = temp;
}
}
}
}
int main(int argc, char **argv)
{
if (argc > 1)
{
long l = strtol(argv[1], 0, 0);
unsigned u = (unsigned)l;
printf("Seed: %u\n", u);
srand(u);
}
int data3[3] = { 3, 1, 2 };
print_array(3, data3);
sort(data3, 3);
print_array(3, data3);
int data5[5] = { 0, 2, 6, 1, 5, };
for (int i = 0; i < 5; i++)
{
shuffle(data5, 5);
print_array(5, data5);
sort(data5, 5);
print_array(5, data5);
}
int data9[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
for (int i = 0; i < 9; i++)
{
shuffle(data9, 9);
print_array(9, data9);
sort(data9, 9);
print_array(9, data9);
}
return 0;
}
The shuffle code implements a Fisher-Yates shuffle, and is
based on code from an answer by Roland Illig. If invoked without a seed argument, it generates the same output each time.
Code compiled and tested on macOS Sierra 10.12.1 with GCC 6.2.0.
An example output:
Seed: 123456789
3 1 2
3 2 1
6 0 1 5 2
6 5 2 1 0
0 6 1 2 5
6 5 2 1 0
0 1 2 6 5
6 5 2 1 0
5 0 6 1 2
6 5 2 1 0
1 6 5 2 0
6 5 2 1 0
0 4 8 3 7 5 1 6 2
8 7 6 5 4 3 2 1 0
7 4 0 5 6 8 3 2 1
8 7 6 5 4 3 2 1 0
1 2 7 5 0 8 3 6 4
8 7 6 5 4 3 2 1 0
3 8 7 5 2 1 0 6 4
8 7 6 5 4 3 2 1 0
1 4 2 6 3 0 7 5 8
8 7 6 5 4 3 2 1 0
2 3 7 4 8 0 5 6 1
8 7 6 5 4 3 2 1 0
3 4 5 8 6 2 0 7 1
8 7 6 5 4 3 2 1 0
3 6 7 4 8 2 5 1 0
8 7 6 5 4 3 2 1 0
0 8 7 3 4 6 5 1 2
8 7 6 5 4 3 2 1 0
This shows the data being sorted in descending order every time, despite different randomized inputs.
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 6 years ago.
Improve this question
This code is designed by someone to change array [a1 a2...am b1 b2..bn ] to the array [b1 b2 ..bn a1 a2..am], but it involves the greatest common divisor which I can't get the point.
void Exchange(int a[],int m,int n,int s){
int p=m,temp=m+n;int k=s%p;
while(k!=0){temp=p;p=k;k=temp%p;}
for(k=0 ; k<p ;k++){ //below is where i cant't understand
temp=a[k];i=k;j=(i+m)%(m+n);
while(j!=k)
{a[i]=a[j];i=j;j=(j+m)%(m+n);}
a[i]=temp;
}
};
EDIT: "Properly" indented:
void Exchange(int a[], int m, int n, int s) {
int p = m, temp = m + n, k = s % p;
while (k != 0) {
temp = p;
p = k;
k = temp % p;
}
for (k = 0 ; k < p; k ++) { // below is where i cant't understand
temp = a[k];
i = k;
j = (i + m) % (m + n);
while (j != k) {
a[i] = a[j];
i = j;
j = (j + m) % (m + n);
}
a[i] = temp;
}
};
The code is using a single value of overhead to implement array rotation. If the lengths are mutually prime, a single pass suffices. If not, you have to repeat the shift cycle by the GCD of the lengths
I said earlier that there are other questions on SO that cover this. A look found SO 3333-3814 which deals with a single rotation. I did some messing with code to support that a while ago, demonstrating the need for GCD, but I didn't previously post it.
Here's the code — it uses C99 VLAs — variable length arrays.
#include <stdio.h>
static int gcd(int x, int y)
{
int r;
if (x <= 0 || y <= 0)
return(0);
while ((r = x % y) != 0)
{
x = y;
y = r;
}
return(y);
}
static void dump_matrix(int m, int n, int source[m][n])
{
for (int i = 0; i < m; i++)
{
for (int j = 0; j < n; j++)
printf("%4d", source[i][j]);
putchar('\n');
}
}
static void init_matrix(int m, int n, int source[m][n])
{
for (int i = 0; i < m; i++)
{
for (int j = 0; j < n; j++)
source[i][j] = (i + 1) * (j + 2);
}
}
static void rotate_1col(int n, int vector[n], int z)
{
z %= n;
if (z != 0)
{
int c = gcd(n, z);
int s = n / c;
for (int r = 0; r < c; r++)
{
int x = r;
int t = vector[x];
for (int i = 0; i < s; i++)
{
int j = (x + z) % n;
int v = vector[j];
vector[j] = t;
x = j;
t = v;
}
}
}
}
static void rotate_cols(int m, int n, int source[m][n], int z)
{
for (int i = 0; i < m; i++)
rotate_1col(n, source[i], z);
}
int main(void)
{
int m = 3;
for (int n = 2; n < 9; n++)
{
int source[m][n];
for (int z = 0; z <= n; z++)
{
init_matrix(m, n, source);
printf("Initial:\n");
dump_matrix(m, n, source);
rotate_cols(m, n, source, z);
printf("Post-rotate %d:\n", z);
dump_matrix(m, n, source);
putchar('\n');
}
}
return 0;
}
The code demonstrates different sizes of rotation on different sizes of array. Example sections of the output:
…
Initial:
2 3 4
4 6 8
6 9 12
Post-rotate 1:
4 2 3
8 4 6
12 6 9
…
Initial:
2 3 4 5
4 6 8 10
6 9 12 15
Post-rotate 3:
3 4 5 2
6 8 10 4
9 12 15 6
…
Initial:
2 3 4 5 6 7
4 6 8 10 12 14
6 9 12 15 18 21
Post-rotate 1:
7 2 3 4 5 6
14 4 6 8 10 12
21 6 9 12 15 18
Initial:
2 3 4 5 6 7
4 6 8 10 12 14
6 9 12 15 18 21
Post-rotate 2:
6 7 2 3 4 5
12 14 4 6 8 10
18 21 6 9 12 15
Initial:
2 3 4 5 6 7
4 6 8 10 12 14
6 9 12 15 18 21
Post-rotate 3:
5 6 7 2 3 4
10 12 14 4 6 8
15 18 21 6 9 12
…
Initial:
2 3 4 5 6 7 8 9
4 6 8 10 12 14 16 18
6 9 12 15 18 21 24 27
Post-rotate 4:
6 7 8 9 2 3 4 5
12 14 16 18 4 6 8 10
18 21 24 27 6 9 12 15
Initial:
2 3 4 5 6 7 8 9
4 6 8 10 12 14 16 18
6 9 12 15 18 21 24 27
Post-rotate 5:
5 6 7 8 9 2 3 4
10 12 14 16 18 4 6 8
15 18 21 24 27 6 9 12
Initial:
2 3 4 5 6 7 8 9
4 6 8 10 12 14 16 18
6 9 12 15 18 21 24 27
Post-rotate 6:
4 5 6 7 8 9 2 3
8 10 12 14 16 18 4 6
12 15 18 21 24 27 6 9
…
First of all, to get the result you said you expected, I have set m and n to be half the array size. I also assumed that s would be initialised to zero, in which case, the first while loop does not iterate. Also, there are several declarations missing in your code so my explanation makes some assumptions.
The variable p holds the number of array elements to swap;
// This is to keep the value to be overwritten by the swap
temp=a[k];
// This is the array index of the bottom half element to write the top half element to
i=k;
// this is to get the current index of the top half;
j=(i+m)%(m+n);
// This assignes the bottom index value with the top half value
while(j!=k)
{
// Write top half element to corresponding bottom half element
a[i]=a[j];
// We can now overwrite top half element; this assignes the index at wich to copy the bottom half element
i=j;
// This is to get out of the loop
j=(j+m)%(m+n);
}
// The bottom half element held at the beginning is now written to the top half at the corresponding index
a[i]=temp;
Hope this is the answer you were looking for. I arrived at this result by using a debugger and by stepping in the code line by line. I don't know if you know how to use a debugger but if not, then I highly recommend your lean how to use one; it it time well spent and it returns an awesome dividend :-)
So what I'm trying to do is have the first row of the 8 x 10 matrix say 12345678910. The second line would say 10123456789. The third would say 91012345678. Ect. This is what I have so far. It just continues to count up.
#include<stdio.h>
#define ROWS 8
#define COLS 10
int main(int argc, char *argv[])
{
int A[ROWS][COLS];
int B[COLS][ROWS];
int x,y;
for (x=0; x<ROWS; x++)
{
for (y=0; y<COLS; y++)
{
A[x][y] = 1*x + y;
}
}
printf("=== Original matrix === \n");
for (x=0; x<ROWS; x++)
{
for (y=0; y<COLS; y++)
{
printf("%3d ", A[x][y]);
}
printf("\n");
}
First, just fill the first row with whatever you want in it. For example, for numbers counting up from zero:
for (y = 0; y < COLS; y++)
A[0][y] = y;
Once you have the first row filled, this will fill the remaining rows as you described (each row right-rotated by one from the previous row):
for (x = 1; x < ROWS; x++)
for (y = 0; y < COLS; y++)
A[x][(x + y) % COLS] = A[0][y];
The above starts filling from the second row (index of 1) onward, and always copies values from the first row. However, the position in the current row it copies to is offset by the row number, so it starts one place later for each row. The % operator is used to wrap the index back around to the start of the row when it gets to the end.
I'm not following your logic in the line
A[x][y] = 1*x + y;
I seem to have gotten closer using %:
A[x][y] = (1+x + y) % 10;
This takes the remainder of the sum of x and y when divided by 10 - which, if we start with 1 rather than 0, begins to approach what you want. It's not exactly correct, but it's a start.
=== Original matrix ===
1 2 3 4 5 6 7 8 9 0
2 3 4 5 6 7 8 9 0 1
3 4 5 6 7 8 9 0 1 2
4 5 6 7 8 9 0 1 2 3
5 6 7 8 9 0 1 2 3 4
6 7 8 9 0 1 2 3 4 5
7 8 9 0 1 2 3 4 5 6
8 9 0 1 2 3 4 5 6 7
Here's the code:
#include <stdio.h>
#define ROWS 8
#define COLS 10
int main(int argc, char* argv[]) {
int A[ROWS][COLS];
int B[COLS][ROWS];
int x,y;
for (x=0; x<ROWS; x++) {
for (y=0; y<COLS; y++) {
A[x][y] = (1+x + y) % 10;
}
}
printf("=== Original matrix === \n");
for (x=0; x<ROWS; x++) {
for (y=0; y<COLS; y++) {
printf("%3d ", A[x][y]);
}
printf("\n");
}
}