Hi so I'm trying to sort my struct with qsort and it sort of works but not really...
Can anyone tell me what's happening and why it goes wrong ? :)
#include <stdio.h>
#include <stdlib.h>
int el_cmp(const void *ep1, const void *ep2);
typedef struct kort
{
int kuloer;
int vaerdi;
} kort;
int main(void){
int i;
int k[] = {3, 4, 5, 6};
int v[] = {2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14};
kort kort[52];
for (i = 0; i < 52; i++){
kort[i].kuloer = k[i % 4];
kort[i].vaerdi = v[i % 13];
}
printf("\n");
qsort(kort, 52, sizeof(int), el_cmp);
for (i = 0; i < 52; i++){
printf("Kort%d: %d %d\n", i + 1, kort[i].kuloer, kort[i].vaerdi);
}
return(0);
}
int el_cmp(const void *ep1, const void *ep2){
int *tp1 = (int*) ep1,
*tp2 = (int*) ep2;
if (*tp1 < *tp2){
return -1;
} else if (*tp1 > *tp2){
return 1;
} else return 0;
}
the result is this:
Kort1: 2 2
Kort2: 3 3
Kort3: 3 3
Kort4: 3 3
...
Kort5: 3 3,
Kort6: 3 4,
Kort7: 4 4,
Kort8: 4 4,
Kort9: 4 4,
Kort10: 4 4,
Kort11: 5 5,
Kort12: 5 5,
Kort13: 5 5,
Kort14: 5 5,
Kort15: 6 6,
Kort16: 6 6
Kort17: 6 6,
Kort18: 6 6,
Kort19: 7 7,
Kort20: 8 8,
Kort21: 9 9,
Kort22: 10 10,
Kort23: 11 11,
Kort24: 12 12,
Kort25: 13 13,
Kort26: 14 14,
Kort27: 5 2
Kort28: 6 3
Kort29: 3 4
...
Kort30: 4 5,
Kort31: 5 6,
Kort32: 6 7,
Kort33: 3 8,
Kort34: 4 9,
Kort35: 5 10,
Kort36: 6 11,
Kort37: 3 12,
Kort38: 4 13,
Kort39: 5 14,
Kort40: 6 2,
Kort41: 3 3,
Kort42: 4 4,
Kort43: 5 5,
Kort44: 6 6,
Kort45: 3 7,
Kort46: 4 8,
Kort47: 5 9,
Kort48: 6 10,
Kort49: 3 11,
Kort50: 4 12,
Kort51: 5 13,
Kort52: 6 14,
but I'm expecting this:
Kort1: 3 2
Kort2: 3 3
Kort3: 3 4
Kort4: 3 5
...
Kort5: 3 6,
Kort6: 3 7,
Kort7: 3 8,
Kort8: 3 9,
Kort9: 3 10,
Kort10: 3 11,
Kort11: 3 12,
Kort12: 3 13,
Kort13: 3 14,
Kort14: 4 2
Kort15: 4 3
...
Kort16: 4 4,
Kort17: 4 5,
Kort18: 4 6,
Kort19: 4 7,
Kort20: 4 8,
Kort21: 4 9,
Kort22: 4 10,
Kort23: 4 11,
Kort24: 4 12,
Kort25: 4 13,
Kort26: 4 14,
...
Kort27: 5 2,
Kort28: 5 3,
Kort29: 5 4,
Kort30: 5 5,
Kort31: 5 6,
Kort32: 5 7,
Kort33: 5 8,
Kort34: 5 9,
Kort35: 5 10,
Kort36: 5 11,
Kort37: 5 12,
Kort38: 5 13,
Kort39: 5 14,
...
Kort40: 6 2,
Kort41: 6 3,
Kort42: 6 4,
Kort43: 6 5,
Kort44: 6 6,
Kort45: 6 7,
Kort46: 6 8,
Kort47: 6 9,
Kort48: 6 10,
Kort49: 6 11,
Kort50: 6 12,
Kort51: 6 13,
Kort52: 6 14,
For starters it is a bad idea to redeclare the name kort
kort kort[52];
Nevertheless this call of qsort
qsort(kort, 52, sizeof(int), el_cmp);
is incorrect. You have an array of structures of the type struct kort not of the type int. The call of qsort can look the following way
qsort(kort, sizeof( kort ) / sizeof( *kort ), sizeof( *kort ), el_cmp);
The comparison function can look the following way
int el_cmp( const void *ep1, const void *ep2 )
{
const struct kort *a = ep1;
const struct kort *b = ep2;
int result = ( b->kuloer < a->kuloer ) - ( a->kuloer < b->kuloer );
if ( result == 0 )
{
result = ( b->vaerdi < a->vaerdi ) - ( a->vaerdi < b->vaerdi );
}
return result;
}
Here is your updated program.
#include <stdio.h>
#include <stdlib.h>
typedef struct kort
{
int kuloer;
int vaerdi;
} kort;
int el_cmp( const void *ep1, const void *ep2 )
{
const struct kort *a = ep1;
const struct kort *b = ep2;
int result = ( b->kuloer < a->kuloer ) - ( a->kuloer < b->kuloer );
if (result == 0)
{
result = ( b->vaerdi < a->vaerdi ) - ( a->vaerdi < b->vaerdi );
}
return result;
}
int main( void )
{
int k[] = { 3, 4, 5, 6 };
int v[] = { 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14 };
const size_t k_size = sizeof( k ) / sizeof( *k );
const size_t v_size = sizeof( v ) / sizeof( *v );
enum { N = 52 };
kort kort[N];
for ( size_t i = 0; i < N; i++ )
{
kort[i].kuloer = k[i % k_size];
kort[i].vaerdi = v[i % v_size];
}
qsort( kort, N, sizeof( *kort ), el_cmp );
for ( size_t i = 0; i < N; i++ )
{
printf( "Kort%zu: %d %d\n", i + 1, kort[i].kuloer, kort[i].vaerdi );
}
putchar( '\n' );
}
The program output is the same as you are expecting
Kort1: 3 2
Kort2: 3 3
Kort3: 3 4
Kort4: 3 5
Kort5: 3 6
Kort6: 3 7
Kort7: 3 8
Kort8: 3 9
Kort9: 3 10
Kort10: 3 11
Kort11: 3 12
Kort12: 3 13
Kort13: 3 14
Kort14: 4 2
Kort15: 4 3
Kort16: 4 4
Kort17: 4 5
Kort18: 4 6
Kort19: 4 7
Kort20: 4 8
Kort21: 4 9
Kort22: 4 10
Kort23: 4 11
Kort24: 4 12
Kort25: 4 13
Kort26: 4 14
//...
Related
Trying to print a 2D array diagonally, going right to down, other solutions I've found are going in the opposite direction
Example of what I'm trying to achieve:
Input:
0 1 2 3
1 2 3 4
2 3 4 5
3 4 5 6
Intended Output:
0 2 4 6
1 3 5
2 4
3
(and other side 1 3 5, 2 4, 3)
Managed to print a diagonal with
for (x=0; x<12; x++) {
printf("%d ", arr[x][x])
}
But unsure how to replicate it for multiple, following attempt is incorrect
for (x=0; x<12; x++) {
for (y=0;y<x+1;y++) {
printf("%d ", arr[x][y]);
}
printf("\n");
}
The following C program meets your requirements. Try to understand the indexing.
int n, i, j, k;
int arr[5][5] = {
0, 1, 2, 3, 4,
1, 2, 3, 4, 5,
2, 3, 4, 5, 6,
3, 4, 5, 6, 7,
4, 5, 6, 7, 8
};
n = 5;
for (k = 0; k < n; k++) {
int ind = 0;
for (i = k; i < n; i++) {
printf("%d ", arr[i][ind++]);
}
printf("\n");
}
Output of the following program:
0 2 4 6 8
1 3 5 7
2 4 6
3 5
4
You can change the size of the array and change the value of n, it will work for your desired n*n array.
I have two arrays:
int group_id[] = {1, 1, 2, 2, 2, 3, 3, 3};
int value[] = {1, 0, 3, 5, 0, 2, 1, 6};
From the second array, I need to return the largest value within the group_id index (not including the current index position), the result (in a new array) would be:
{0, 1, 5, 3, 5, 6, 6, 2}
The arrays are a lot longer (~10 millions), so looking for an efficient solution.
Clarification:
The first two elements of value belong to group_id = 1, the first element will return 0 as the highest value as it can't return its self. The second element will will return 1 as it's the largest value in group_id 1.
the third, fourth and fifth elements (3, 5, 0) belong to group_id 2, the first will return 5, the second 3 (as it can't return its own index and the third will return 5).
It isn't clear that all the elements in group_id with the same number are adjacent (but that is crucial for efficiency).
Good point, you can assume they are all adjacent.
It isn't clear what should happen if there was only one entry in group_id with a given value — there isn't an alternative entry to use, so what should happen (or should the code abandon ship if the input is invalid).
Assume invalid.
The problem can be solved in O(N) time; it does not need O(N•log N) and sorting. This code shows how:
/* SO 5723-6683 */
#include <assert.h>
#include <stdio.h>
static void dump_array(const char *tag, int size, int *data);
static void test_array(const char *tag, int size, int *groups, int *values);
int main(void)
{
int groups1[] = { 1, 1, 2, 2, 2, 3, 3, 3 };
int values1[] = { 1, 0, 3, 5, 0, 2, 1, 6 };
int groups2[] = { 1, 1, 2, 2, 2, 3, 3, 3, 3, 3, 4, 4, 4, 5, 5, 5, 5, 5 };
int values2[] = { 1, 1, 3, 5, 0, 2, 1, 6, 6, 3, 5, 5, 5, 3, 2, 3, 7, 3 };
enum { NUM_VALUES1 = sizeof(values1) / sizeof(values1[0]) };
enum { NUM_VALUES2 = sizeof(values2) / sizeof(values2[0]) };
test_array("Test 1", NUM_VALUES1, groups1, values1);
test_array("Test 2", NUM_VALUES2, groups2, values2);
return 0;
}
static void test_array(const char *tag, int size, int *groups, int *values)
{
printf("%s (%d):\n", tag, size);
dump_array("values", size, values);
dump_array("groups", size, groups);
int output[size];
int grp_size;
for (int lo = 0; lo < size - 1; lo += grp_size)
{
assert(groups[lo+0] == groups[lo+1]);
grp_size = 2;
int max_1 = (values[lo+0] < values[lo+1]) ? values[lo+1] : values[lo+0];
int max_2 = (values[lo+0] < values[lo+1]) ? values[lo+0] : values[lo+1];
for (int hi = lo + 2; hi < size && groups[hi] == groups[lo]; hi++)
{
grp_size++;
if (values[hi] >= max_1)
{
max_2 = max_1;
max_1 = values[hi];
}
else if (values[hi] >= max_2)
max_2 = values[hi];
}
for (int i = lo; i < lo + grp_size; i++)
output[i] = (values[i] == max_1) ? max_2 : max_1;
}
dump_array("output", size, output);
}
static void dump_array(const char *tag, int size, int *data)
{
printf("%s (%d):", tag, size);
for (int i = 0; i < size; i++)
printf(" %d", data[i]);
putchar('\n');
}
Output from this test program:
Test 1 (8):
values (8): 1 0 3 5 0 2 1 6
groups (8): 1 1 2 2 2 3 3 3
output (8): 0 1 5 3 5 6 6 2
Test 2 (18):
values (18): 1 1 3 5 0 2 1 6 6 3 5 5 5 3 2 3 7 3
groups (18): 1 1 2 2 2 3 3 3 3 3 4 4 4 5 5 5 5 5
output (18): 1 1 5 3 5 6 6 6 6 6 5 5 5 7 7 7 3 7
The following code will do it. Its efficiency is O(sum of all n_ilog(n_i)) in which n_i is the size of each subset i, unless we use MPI or OpenMP (in that case, it will be at best O(mlog(m)), in which m is the size of the greatest subset).
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int compare (const void * e1, const void * e2)
{
int f = *((int*)e1);
int s = *((int*)e2);
return (f>s);
}
int main(int argc, char* argv[])
{
int group_id[] = {1, 1, 2, 2, 2, 3, 3, 3};
int value[] = {1, 0, 3, 5, 0, 2, 1, 6};
int i,j,k,count,*tmp;
for (i=0; i<8; i++)
{
/* find subsets */
count = 1;
for (j=i; j<7 && group_id[j]==group_id[j+1]; j++)
count++;
/* copy subset */
tmp = malloc(sizeof(int)*count);
memcpy(tmp, &value[i], sizeof(int)*count);
/* sort */
qsort (tmp, count, sizeof(*tmp), compare);
/* print */
for (k=i; k<=j; k++)
if (value[k] != tmp[count-1])
printf("%d ", tmp[count-1]);
else
printf("%d ", tmp[count-2]);
i = j;
free(tmp);
}
printf("\n");
return 0;
}
PS: You will probably have to do some modifications to it, but I hope its enough for what you want (or to get you started). Please, be aware, I am assuming each subset has size at least 2, and that the greatest value within a subset appears only once.
I'm trying in C to write a recursive function that takes as an input an NxM matrix, and finds, checks specific cells and changes their content based on a scenario.
Original matrix
The matrix elements are:
1 2 3 4 5 6 7 8
------------------
1| 1 6 7 4 4 1 2 8
2| 1 3 6 3 3 1 3 4
3| 3 4 1 5 7 8 5 1
4| 1 7 8 6 2 6 4 4
5| 7 8 1 6 2 2 7 1
6| 3 8 4 3 1 6 8 6
7| 3 8 7 5 4 6 6 6
8| 7 2 2 1 7 4 6 8
Based on a matrix like the above, a user gives the location of a specific cell, e.g. position (5,6) for the integer 2. I want the recursive function to check the cells in the four directions, up, down, left, right and if it finds the same integer to change them to 0s. This will continue for all the "neighborhood" cells. In this example all twos at positions (5,6), (5,5) and (4,5) will change to 0s.
Another example:
user gives location i.e. position (8,7) for the integer 6. The recursive function has to find and change all 6s at the positions (8,7), (7,7), (7,8), (7,6), (6,6), (6,8) and set them to 0s.
void destroy(int (*arr), int rows, int cols,int search,int rowin, int colin) //rows: total rows of matrxi, cols:total cols of matrix, rowin and colin are the x,y co ordinates of the cell that the user wants to destroy and search has the int i.e 6 ..
{
int i, j;
printf("\n");
printf("\n");
int count = 0,temp = 0;
for (j = 0; j < cols; j++) {
for (i = 0; i < rows; i++) {
if (*(arr + i*cols + j)== search) {
if (*(arr + (i-1)*cols + j) == search){//check neighborhood cell
count++; //counter to know how many similar neighborhood integers have been found
(*(arr + i*cols + j)= 0);
*(arr + (i-1)*cols + j) = 0;
destroy(int (*arr), int rows, int cols,int search, j, i) //call recursive function to check the neighborhood cells of the new position i,j
}
}
}
}
}
You don't need for loops but four recursive calls to check each neighborhood.
void destroy(int *arr, int rows, int cols,int search,int rowin, int colin)
{
if (rowin>=rows || colin >= cols || rowin < 0 || colin <0)
return; //base condition
if (arr[rowin*cols+colin] == search)
{
arr[rowin*cols+colin] = 0;
destroy(arr, rows, cols, search, rowin+1, colin);
destroy(arr, rows, cols, search, rowin, colin+1);
destroy(arr, rows, cols, search, rowin-1, colin);
destroy(arr, rows, cols, search, rowin, colin-1);
}
}
Notice that in C an array index starts from zero (not one).
Here is an example that uses a matrix (aka array of array).
#include <stdio.h>
void destroy(int value, int r, int c, int r_size, int c_size, int arr[][r_size])
{
if (value != arr[r][c]) return; // Nothing to do
arr[r][c] = 0;
if (r+1 < r_size) destroy(value, r+1, c, r_size, c_size, arr); // DOWN
if (r-1 >= 0) destroy(value, r-1, c, r_size, c_size, arr); // UP
if (c+1 < c_size) destroy(value, r, c+1, r_size, c_size, arr); // RIGHT
if (c-1 >= 0) destroy(value, r, c-1, r_size, c_size, arr); // LEFT
}
void pm(int r_size, int c_size, int arr[r_size][r_size])
{
printf("-------------------------------------------\n");
for (int r=0; r < r_size; ++r)
{
for (int c=0; c < c_size; ++c)
{
printf("%d ", arr[r][c]);
}
printf("\n");
}
}
#define MSIZE 8
int main(void) {
int arr[MSIZE][MSIZE] =
{
{1, 6, 7, 4, 4, 1, 2, 8},
{1, 3, 6, 3, 3, 1, 3, 4},
{3, 4, 1, 5, 7, 8, 5, 1},
{1, 7, 8, 6, 2, 6, 4, 4},
{7, 8, 1, 6, 2, 2, 7, 1},
{3, 8, 4, 3, 1, 6, 8, 6},
{3, 8, 7, 5, 4, 6, 6, 6},
{7, 2, 2, 1, 7, 4, 6, 8}
};
pm(MSIZE, MSIZE, arr);
destroy(arr[7][6], 7, 6, MSIZE, MSIZE, arr);
pm(MSIZE, MSIZE, arr);
return 0;
}
Output:
-------------------------------------------
1 6 7 4 4 1 2 8
1 3 6 3 3 1 3 4
3 4 1 5 7 8 5 1
1 7 8 6 2 6 4 4
7 8 1 6 2 2 7 1
3 8 4 3 1 6 8 6
3 8 7 5 4 6 6 6
7 2 2 1 7 4 6 8
-------------------------------------------
1 6 7 4 4 1 2 8
1 3 6 3 3 1 3 4
3 4 1 5 7 8 5 1
1 7 8 6 2 6 4 4
7 8 1 6 2 2 7 1
3 8 4 3 1 0 8 0
3 8 7 5 4 0 0 0
7 2 2 1 7 4 0 8
Version 2
This version a little different because it only changes elements if at least one neighbor is found. Also it counts the number of changes.
#include <stdio.h>
#include <stdlib.h>
int destroy_rec(int value, int r, int c, int r_size, int c_size, int arr[][r_size])
{
if (value != arr[r][c]) return 0; // Nothing to do
int changed = 1;
arr[r][c] = 0;
if (r+1 < r_size) changed += destroy_rec(value, r+1, c, r_size, c_size, arr); // DOWN
if (r-1 >= 0) changed += destroy_rec(value, r-1, c, r_size, c_size, arr); // UP
if (c+1 < c_size) changed += destroy_rec(value, r, c+1, r_size, c_size, arr); // RIGHT
if (c-1 >= 0) changed += destroy_rec(value, r, c-1, r_size, c_size, arr); // LEFT
return changed;
}
int destroy(int r, int c, int r_size, int c_size, int arr[][r_size])
{
if (r+1 < r_size && arr[r+1][c] == arr[r][c]) return destroy_rec(arr[r][c], r, c, r_size, c_size, arr);
if (r-1 >= 0 && arr[r-1][c] == arr[r][c]) return destroy_rec(arr[r][c], r, c, r_size, c_size, arr);
if (c+1 < c_size && arr[r][c+1] == arr[r][c]) return destroy_rec(arr[r][c], r, c, r_size, c_size, arr);
if (c-1 >= 0 && arr[r][c-1] == arr[r][c]) return destroy_rec(arr[r][c], r, c, r_size, c_size, arr);
return 0;
}
void pm(int r_size, int c_size, int arr[r_size][r_size])
{
printf("-------------------------------------------\n");
for (int r=0; r < r_size; ++r)
{
for (int c=0; c < c_size; ++c)
{
printf("%d ", arr[r][c]);
}
printf("\n");
}
printf("-------------------------------------------\n");
}
#define MSIZE 8
int main(void) {
int arr[MSIZE][MSIZE] =
{
{1, 6, 7, 4, 4, 1, 2, 8},
{1, 3, 6, 3, 3, 1, 3, 4},
{3, 4, 1, 5, 7, 8, 5, 1},
{1, 7, 8, 6, 2, 6, 4, 4},
{7, 8, 1, 6, 2, 2, 7, 1},
{3, 8, 4, 3, 1, 6, 8, 6},
{3, 8, 7, 5, 4, 6, 6, 6},
{7, 2, 2, 1, 7, 4, 6, 8}
};
pm(MSIZE, MSIZE, arr);
int changed = destroy(7, 6, MSIZE, MSIZE, arr);
printf("%d cells changed\n", changed);
pm(MSIZE, MSIZE, arr);
int (*dyn_arr)[MSIZE] = malloc(MSIZE * sizeof *dyn_arr);
return 0;
}
Output:
-------------------------------------------
1 6 7 4 4 1 2 8
1 3 6 3 3 1 3 4
3 4 1 5 7 8 5 1
1 7 8 6 2 6 4 4
7 8 1 6 2 2 7 1
3 8 4 3 1 6 8 6
3 8 7 5 4 6 6 6
7 2 2 1 7 4 6 8
-------------------------------------------
6 cells changed
-------------------------------------------
1 6 7 4 4 1 2 8
1 3 6 3 3 1 3 4
3 4 1 5 7 8 5 1
1 7 8 6 2 6 4 4
7 8 1 6 2 2 7 1
3 8 4 3 1 0 8 0
3 8 7 5 4 0 0 0
7 2 2 1 7 4 0 8
-------------------------------------------
I don't know what you want to achieve with this because in your code you're already traversing through whole array and after checking one element you want to traverse again.
In my point of view you don't need another iteration to remove the elements. You can perform this in a single iteration.
If the element you're searching exists then remove the neighbor elements
(i,j => (i-1,j : i+1,j : i,j-1 : i,j+1))
In this way you might need to put some checks on index value to avoid undefined behaviour.
#include <stdio.h>
void Turn(int(*ptr)[4], int length, int vertical)
{
int arr[100][100] = { 0, };
for (int i = 0; i < vertical; i++)
{
for (int j = 0; j < length; j++)
{
arr[i][j] = *(*(ptr + (vertical - j - 1)) + i);
}
}
for (int i = 0; i < vertical; i++)
{
for (int j = 0; j < length; j++)
{
*(*(ptr + i) + j) = arr[i][j];
}
}
}
int main(void)
{
int BY[4][4] = {
1,2,3,4,
5,6,7,8,
9,10,11,12,
13,14,15,16,
};
int length = sizeof(BY[0]) / sizeof(int);
int vertical = (sizeof(BY) / sizeof(int)) / length;
Turn(BY, length, vertical);
for (int i = 0; i < vertical; i++)
{
for (int j = 0; j < length; j++)
{
printf("%d ", BY[i][j]);
}
printf("\n");
}
return 0;
}
I wrote a function named Turn to rotate a 2D array right (a 90 degree rotation). I wanted to make this function to turn every array that has same vertical range and length. But I can't hand over
(I used google translate, I don't know how to describe it) parameter of a 2D array.
I first used void Turn(int(*ptr)[] ....)
but it didn't work. So I couldn't help using
int (*ptr)[4] in this function.
How can I make a parameter of a 2D array that can be used with any 2D array?
Using the C99 variable length array (VLA) feature make the problem easy. C11 makes support for VLAs optional, but the implementation must define __STDC_NO_VLA__ to show that it doesn't support VLAs.
Here's one version of the code. I've renamed your Turn() function (which turns the matrix 90° right into TurnR() and added a TurnL() function which turns the matrix 90° left. Because the code handles non-square matrices, the output matrix is separate from the input matrix. (You can simplify the code slightly if you only want to work with square matrices.)
#include <stdio.h>
static void TurnR(size_t rows, size_t cols, int matrix[rows][cols], int result[cols][rows])
{
for (size_t r = 0; r < rows; r++)
{
for (size_t c = 0; c < cols; c++)
result[c][rows - 1 - r] = matrix[r][c];
}
}
static void TurnL(size_t rows, size_t cols, int matrix[rows][cols], int result[cols][rows])
{
for (size_t r = 0; r < rows; r++)
{
for (size_t c = 0; c < cols; c++)
result[cols - 1 - c][r] = matrix[r][c];
}
}
static void Print(const char *tag, size_t rows, size_t cols, int matrix[rows][cols])
{
printf("%s (%zux%zu):\n", tag, rows, cols);
for (size_t r = 0; r < rows; r++)
{
const char *pad = "";
for (size_t c = 0; c < cols; c++)
{
printf("%s%3d", pad, matrix[r][c]);
pad = " ";
}
putchar('\n');
}
}
int main(void)
{
int BY[4][4] = {
{ 1, 2, 3, 4, },
{ 5, 6, 7, 8, },
{ 9, 10, 11, 12, },
{ 13, 14, 15, 16, },
};
int out[4][4];
Print("before", 4, 4, BY);
TurnR(4, 4, BY, out);
Print("right", 4, 4, out);
TurnL(4, 4, BY, out);
Print("left", 4, 4, out);
int m4x6[4][6] =
{
{ 1, 2, 3, 4, 5, 6, },
{ 7, 8, 9, 10, 11, 12, },
{ 13, 14, 15, 16, 17, 18, },
{ 19, 20, 21, 22, 23, 24, },
};
int m6x4[6][4];
Print("before", 4, 6, m4x6);
TurnR(4, 6, m4x6, m6x4);
Print("right", 6, 4, m6x4);
TurnL(4, 6, m4x6, m6x4);
Print("left", 6, 4, m6x4);
int m5x3[5][3] =
{
{ 1, 2, 3, },
{ 4, 5, 6, },
{ 7, 8, 9, },
{ 10, 11, 12, },
{ 13, 14, 15, },
};
int m3x5[3][5];
Print("before", 5, 3, m5x3);
TurnR(5, 3, m5x3, m3x5);
Print("right", 3, 5, m3x5);
TurnL(5, 3, m5x3, m3x5);
Print("left", 3, 5, m3x5);
TurnL(3, 5, m3x5, m5x3);
Print("doubleL", 5, 3, m5x3);
return 0;
}
And sample output is:
before (4x4):
1 2 3 4
5 6 7 8
9 10 11 12
13 14 15 16
right (4x4):
13 9 5 1
14 10 6 2
15 11 7 3
16 12 8 4
left (4x4):
4 8 12 16
3 7 11 15
2 6 10 14
1 5 9 13
before (4x6):
1 2 3 4 5 6
7 8 9 10 11 12
13 14 15 16 17 18
19 20 21 22 23 24
right (6x4):
19 13 7 1
20 14 8 2
21 15 9 3
22 16 10 4
23 17 11 5
24 18 12 6
left (6x4):
6 12 18 24
5 11 17 23
4 10 16 22
3 9 15 21
2 8 14 20
1 7 13 19
before (5x3):
1 2 3
4 5 6
7 8 9
10 11 12
13 14 15
right (3x5):
13 10 7 4 1
14 11 8 5 2
15 12 9 6 3
left (3x5):
3 6 9 12 15
2 5 8 11 14
1 4 7 10 13
doubleL (5x3):
15 14 13
12 11 10
9 8 7
6 5 4
3 2 1
I wouldn't dream of writing the code using the *(ptr + index) notation, especially with the double subscripts; it is just too error prone and hard to read (a nightmare, indeed!).
Is am trying to figure out how to generate this sequence of numbers in C.
0, 1, 2, 3, 4, 4, 5, 6, 7, 7, 8, 8, 9 …
The sequence is generated by forming a triangle of numbers as shown below:
0
1 2
3 4 5
6 7 8 9 ...
Next two numbers in series are located as follows:
Next number is located directly below
Next to next is located one place to the right.
0
|\
1 2
Series -> 0, 1, 2
0
|\
1 2
|\|\
3 4 5
Series -> 0, 1, 2, 3, 4, 4, 5, ........
How can I traverse this number triangle to get this sequence in C?
It means that
0 is replaced with 1 and 2
1 is replaced with 3 and 4
2 is replaced with 4 and 5
0
|\
1 2
|\|\
3 4 5
|\|\|\
6 7 8 9
Series -> 0, 1, 2, 3, 4, 4, 5, 6, 7, 7, 8, 7, 8, 8, 9 ........
It means that
I. Solving 0
0 leads to 1 and 2
0 -> 1 - 2
0 1 2
II. Solving 1 and 2
1 leads to 3 and 4
1 -> 3 - 4
0 1 2 3 4
2 leads to 4 and 5
2 -> 4 - 5
0 1 2 3 4 4 5
III. Solving 3, 4, 4, 5
3 leads to 6 and 7
3 -> 6 - 7
0 1 2 3 4 4 5 6 7
4 leads to 7 and 8
4 -> 7 - 8
0 1 2 3 4 4 5 6 7 7 8
4 leads to 7 and 8
4 -> 7 - 8
0 1 2 3 4 4 5 6 7 7 8 7 8
5 leads to 8 and 9
5 -> 8 - 9
0 1 2 3 4 4 5 6 7 7 8 7 8 8 9
My apologies for not explaining properly. I hope I explain it this time.
I assume (based on the description) your sequence should be indeed
0
1 2
3 4 4 5
6 7 7 8 8 9
10 11 11 12 12 13 13 14
etc.
You can work with it with the code like that:
int nextRowStart = 0;
int nextRowSize = 1;
for (int curr = 0; /*put some ending condition here*/; curr++)
{
yield(curr)
if (curr != nextRowStart - 1 && curr != nextRowStart)
yield(curr);
if (curr == nextRowStart)
{
nextRowStart += nextRowSize;
nextRowSize++;
}
}
void yield(int x)
{
printf("%d ", x);
}
With the changed question, the new one can be done recursively
This is the solution in C#:
IEnumerable<int> Generate(int level)
{
if (level == 0)
{
yield return 0;
yield break;
}
int diff = level;
foreach (int n in Generate(level - 1))
{
yield return n + diff;
yield return n + diff + 1;
}
}
var result = Enumerable.Range(0, maxLevel).SelectMany(Generate);
It would take some time to translate it into C...
C solution:
void Generate(int level, int* resultsize, int** result)
{
if (level == 0)
{
*result = (int*)malloc(sizeof(int));
(*result)[0] = 0;
*resultsize = 1;
}
else
{
int recResultSize;
int* recResult;
Generate(level - 1, &recResultSize, &recResult);
*resultsize = recResultSize * 2;
*result = (int*)malloc(*resultsize * sizeof(int));
for (int i = 0; i < recResultSize; i++)
{
(*result)[2*i] = recResult[i] + level;
(*result)[2*i + 1] = recResult[i] + level + 1;
}
free(recResult);
}
}
This is the code which gives the exact result and solves the problem. I came at this result just when #Lundin asked me to post my code , I tried again and I was successful. Thanks guys.
#include<stdio.h>
int in;
int main(){
int ik, it, icount = 0, ih, temp, ig = 1;
int aisum[100];
aisum[0] = 0;
scanf("%d",&in);
printf("0\n");
it = 1;ih = 0;temp = 2;
for(icount = 0,ig = 1; icount <= in; icount++){
for(ik = 0; ik<2; ik++){
aisum[ig] = aisum[icount] + it + ik ;
printf("%d ",aisum[ig]);
ig++;
}
if(aisum[icount] == ih){
printf("\n");
it++;
ih += temp;
temp++;
}
}
return 0;
}
/*Input the number of elements to be processed*/
/*icount will account for new elements to be formed like if we look
at pascal triangle
0 will form 1 and 2
1 will form 3 and 4
*/
/*ig will account for array indices*/
/*it will account for the periodic addition */
/*ih checks for the codnition for it to increement
0
1 2
3 4 5
it will be increemented at 0, 2, 5 ...
*/
The simplest solution I can give from below triangle to required order is...
0
1 2
3 4 5
6 7 8 9
printing start and end nodes of each line and printing center elements 2 times each...
for each line start will be equals to previous end+1...
end will be equal to end+1+count...
count will be incremented by 1 for each line...
CPP Program:
#include<iostream>
using namespace std;
int main()
{
int start=1,end=2,count=1;
cout<<0<<" ";
while(count<5)
{
cout<<start<<" ";
for(int i=start+1;i<end;i++)
{
cout<<i<<" "<<i<<" ";
}
cout<<end<<" ";
count++;
start=end+1;
end=start+count;
}
return 0;
}