C lan If statement issue about ds problem - c

This below is my ds hw code.
#include <stdio.h>
typedef struct
{
int row;
int col;
int val;
}term;
void CreateTriplet(term t[],int a[][10],int m, int n)
{
int i, j, k = 0;
t[0].row = m;
t[0].col = n;
for (i = 0; i < m; i++)
{
for (j = 0; j < n; j ++)
{
if(a[i][j] == 0)
continue;
k++;
t[k].row = i;
t[k].col = j;
t[k].val = a[i][j];
}
}
t[0].val = k;
}
void printTriplet(term t[], int k)
{
int i;
for(i = 0 ; i < k ; i++)
{
printf("%d\t", t[i].row);
printf("%d\t", t[i].col);
printf("%d\n", t[i].val);
}
}
void findTranspose(term t1[], term t2[])
{
int i, j, k;
t2[0].row = t1[0].col;
t2[0].col = t1[0].row;
t2[0].val = t1[0].val;
k = 1;
for (i = 0; i < t1[0].col; i++)
{
for (j = 1; j <=t1[0].val; j++)
{
if (t1[j].col == i)
{
t2[k].row = t1[j].col;
t2[k].col = t1[j].row;
t2[k].val = t1[j].val;
k++;
}
}
}
}
int main()
{
int a[10][10], i, j, m, n, zero=0, nonzero;
term t1[101], t2[102];
scanf("%d %d", &m, &n);
for(i = 0; i < m ;i++)
{
for(j= 0; j < n ;j++)
{
scanf("%d]\n", &a[i][j]);
if(a[i][j]==0)
zero++;
}
}
if (i*j != i*i && j*j) /* I have no idea how to modify this section for the output*/
{
printf("Input matrix has wrong size. Please input again. \n");
}
else
{
nonzero = m * n - zero;
printf("Sparse matrix by triplet form:\n");
CreateTriplet(t1, a, m, n);
printTriplet(t1, nonzero+1);
findTranspose(t1, t2);
printf("Transpose of the sparse matrix:\n");
printTriplet(t2, nonzero+1);
}
return 0;
}
The main problem is in the section (if statement.)
When I was writing the if conditional, the input size was 6 * 6. Also, the elements in the matrix are not 6 * 6. My idea is to let the condition determine row * col != input elements. I don't know how to modify the if statement. Can someone help me?
**Input**
55
15 0 0 22 0
0 0 3 0 0
0 0 0 -6 0
0 0 0 0 7
91 0 0 0 0
**Output**
Sparse matrix by triplet form:
5 5 6
0 0 15
0 3 22
1 2 3
2 3 -6
3 4 7
4 0 91
Transpose of the sparse matrix:
5 5 6
0 0 15
0 4 91
2 1 3
3 0 22
3 2 -6
4 3 7
**Input**
66
15 0 0 22 0 -15 100
0 11 3 0 0 0
0 0 0 -6 0 0
0 0 0 0 0 0
91 0 0 0 0 0
0 0 28 0 0 0
1 0 0 0 0 0
**Output**
Input matrix has wrong size. Please input again.

#include <stdio.h>
#include <stdlib.h>
typedef struct {
int row;
int col;
int val;
} term;
void CreateTriplet (term t[],int a[][10],int m, int n) {
int i, j, k = 0;
t[0].row = m;
t[0].col = n;
for (i = 0; i < m; i++) {
for (j = 0; j < n; j ++) {
if(a[i][j] == 0)
continue;
k++;
t[k].row = i;
t[k].col = j;
t[k].val = a[i][j];
}
}
t[0].val = k;
}
void printTriplet(term t[], int k) {
int i;
for(i = 0 ; i < k ; i++) {
printf("%d\t", t[i].row);
printf("%d\t", t[i].col);
printf("%d\n", t[i].val);
}
}
void findTranspose(term t1[], term t2[]) {
int i, j, k;
t2[0].row = t1[0].col;
t2[0].col = t1[0].row;
t2[0].val = t1[0].val;
k = 1;
for (i = 0; i < t1[0].col; i++) {
for (j = 1; j <=t1[0].val; j++) {
if (t1[j].col == i) {
t2[k].row = t1[j].col;
t2[k].col = t1[j].row;
t2[k].val = t1[j].val;
k++;
}
}
}
}
int main (int argc, char * *argv, char * *envp) {
int a[10][10], i, j, m, n, zero = 0, nonzero;
term t1[101], t2[102];
int ok_or_not = 1;
while (ok_or_not == 1) {
scanf ("%d %d", &m, &n);
if (m * n != m * m) {
printf ("Input matrix has wrong size. Please input again. \n");
}
else {
ok_or_not = 0;
}
}
for (i = 0; i < m; i++) {
for (j = 0; j < n; j++) {
scanf("%d]\n", &a[i][j]);
if (a[i][j] == 0)
zero++;
}
}
if (i * j != i * i && j * j) { /* I have no idea how to modify this section for the output*/
} else {
nonzero = m * n - zero;
printf("Sparse matrix by triplet form:\n");
CreateTriplet(t1, a, m, n);
printTriplet(t1, nonzero + 1);
findTranspose(t1, t2);
printf("Transpose of the sparse matrix:\n");
printTriplet(t2, nonzero + 1);
}
return (EXIT_SUCCESS);
}

Related

Unexpected output for simple 2d array in c

This is the initialising part of a program im writing. I am new ish to c and am quite confused with one of the outputs I am getting. Any advice would be greatly appreciated
for input 9 11 I get
1 2 3 4 5 6 7 8 9
9 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
when I expect to get
1 2 3 4 5 6 7 8 9
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
void *safeMalloc(int n) {
void *p = malloc(n);
if (p == NULL) {
printf("Error: malloc(%d) failed. Out of memory?\n", n);
exit(EXIT_FAILURE);
}
return p;
}
int **makeIntArray2D(int width, int height) {
int **arr = safeMalloc(height*sizeof(int *));
for (int row=0; row < height; row++) {
arr[row] = safeMalloc(width*sizeof(int));
}
return arr;
}
int main(int argc, char *argv[]) {
int numDisks;
int numMoves;
scanf("%d %d", &numDisks, &numMoves);
int **tohan = makeIntArray2D(3, numDisks);
for(int i = 0; i < 3; i++) {
for(int j =0; j < numDisks; j++) {
tohan[i][j] = 0;
}
}
for(int i = 0; i < 3; i++) {
for(int j = 0; j < numDisks; j++) {
printf("%d ", tohan[i][j]);
}
printf("\n");
}
printf("\n");
for(int k = 0; k < numDisks; k++) {
tohan[0][k] = k+1;
}
for(int i = 0; i < 3; i++) {
for(int j = 0; j < numDisks; j++) {
printf("%d ", tohan[i][j]);
}
printf("\n");
}
printf("\n");
}
You have:
int **makeIntArray2D(int width, int height) { … }
You call:
int **tohan = makeIntArray2D(3, numDisks);
You expect the height of the array to be 3 and the width 9, but you are passing the parameters in the wrong sequence for the function.
Note: this diagnosis could not be made without seeing the code for makeIntArray2D().

Count Sort in C - incomplete sorting

I'm trying to write an Count sort Program. My Problem is that it seems to sort the first 4 Numbers and after that he only prints 0. My input comes from an external file.
This is my sorted output:
0 1 5 8 0 0 0 0 0 0 0 0 0 0 0 0 0
The following is my code so far:
int MAX_LAENGE = 1000;
int MAX_VALUE = 100;
int i, k, j;
void count_sort_calculate_counts(int input_array[], int len, int count_array[]) {
for ( i = 0; i < len; i++)
{
count_array[i] = 0;
}
for (j = 0; j < len; j++)
{
count_array[input_array[j]] = count_array[input_array[j]] + 1;
}
}
void count_sort_write_output_array(int output_array[], int len, int count_array[]) {
k = 0;
for (j = 0; j < len; j++)
{
for (i = 0; i < count_array[j]; i++)
{
output_array[k] = j;
k = k + 1;
}
}
Two of the cycles - the one setting the counts to 0 and the one printing the numbers should not be until len, instead they should be until MAX_VALUE.
for ( i = 0; i < MAX_VALUE; i++)
{
count_array[i] = 0;
}
Similarly in the function that prints the numbers:
for (j = 0; j < MAX_VALUE; j++)
Without having more context around how you use this code, this is the only issue I spot.

what is the better way to loop this problem?

#include <stdio.h>
int main()
{
int arr[9][9];
int i = 0, x = 10;
for (int i = 0, j = 0; j <= 8; j++) {
x++;
arr[i][j] = x;
}
for (int j = 8, i = 1; i <= 8; i++) {
x++;
arr[i][j] = x;
}
for (int i = 8, j = 7; j >= 0; j--) {
x++;
arr[i][j] = x;
}
for (int j = 0, i = 7; i >= 1; i--) {
x++;
arr[i][j] = x;
}
for (int i = 1, j = 1; j <= 7; j++) {
x++;
arr[i][j] = x;
}
for (int j = 7, i = 2; i <= 7; i++) {
x++;
arr[i][j] = x;
}
for (int i = 7, j = 6; j >= 1; j--) {
x++;
arr[i][j] = x;
}
for (int j = 1, i = 6; i >= 2; i--) {
x++;
arr[i][j] = x;
}
...
arr[4][4] = x + 1;
for (int i = 0; i <= 8; i++) {
for (int j = 0; j <= 8; j++)
printf("%d ", arr[i][j]);
printf("\n");
}
getch();
}
so I have this program, and I know you can loop it but how ? been sitting for an hour thinking and nothing came to my mind. By the way, the task is to append a matrix like on picture. Does anyone know to do it ? Maybe use some complex for loop
Here's one way to do it:
int arr[9][9] = {0};
int x = 0, i = 0, j = 0, vi = 0, vj = 1;
do {
++x;
arr[i][j] = x;
{
int ii = i+vi;
int jj = j+vj;
if (ii < 0 || ii >= 9 || jj < 0 || jj >= 9 || arr[ii][jj] != 0) {
if (vi != 0) {
vj = -vi;
vi = 0;
} else {
vi = vj;
vj = 0;
}
}
}
i = i+vi;
j = j+vj;
} while (arr[i][j] == 0);
Live on Coliru
Here's another way:
int arr[9][9] = {0};
int x = 0, i = 0, j = 0, vi = 0, vj = 1, lk = 8;
while (lk > 0) {
for (int k = 0; k < lk; ++k) {
++x;
arr[i][j] = x;
i += vi;
j += vj;
}
vi = vj;
vj = 0;
for (int k = 0; k < lk; ++k) {
++x;
arr[i][j] = x;
i += vi;
j += vj;
}
vj = -vi;
vi = 0;
if (vj > 0) {
++i;
++j;
lk -= 2;
}
}
arr[9/2][9/2] = x+1; // Only if odd dimensions
Live on Coliru
And here is yet another:
int arr[9][9] = {0};
int i = 0, lk = 8, x = 1;
while (lk > 0) {
for (int k = 0; k < lk; ++k) {
arr[i][i+k] = x + k;
arr[i+k][lk+i] = x + lk + k;
arr[lk+i][lk+i-k] = x + 2*lk + k;
arr[lk+i-k][i] = x + 3*lk + k;
}
x += 4*lk;
lk -= 2;
++i;
}
arr[9/2][9/2] = x; // Only if odd dimensions
Live on Coliru
Here is the "straight forward" option with for loops:
#include <stdio.h>
#define N 5
int main(void) {
int i,j,dim;
int matrix[N][N];
// init and print the matrix
for (i=0; i < N; i++)
{
for (j=0; j< N; j++)
{
matrix[i][j] = i*N + j;
printf("%2d ", matrix[i][j]);
}
printf("\n");
}
printf("\n");
// perform spiral print
for (dim = 0; dim < (N+1)/2; dim++)
{
// set initial i and go till the "last column"
i = dim;
for (j = dim; j < N - dim; j++)
{
printf("%2d ", matrix[i][j]);
}
printf("\n");
// bring back i and j to the proper coordinate
// and move down to the "last row"
j--;i++;
for (; i < N - dim; i++)
{
printf("%2d ", matrix[i][j]);
}
printf("\n");
// bring back i and j to the proper coordinate
// and move back to the "first column"
i--;j--;
for (; j >= dim; j--)
{
printf("%2d ", matrix[i][j]);
}
printf("\n");
// bring back i and j to the proper coordinate
// and move up to the "first row"
j++;i--;
for (; i > dim; i--)
{
printf("%2d ", matrix[i][j]);
}
printf("\n");
}
return 0;
}
The output, as can be seen here is
0 1 2 3 4
5 6 7 8 9
10 11 12 13 14
15 16 17 18 19
20 21 22 23 24
0 1 2 3 4
9 14 19 24
23 22 21 20
15 10 5
6 7 8
13 18
17 16
11
12
==========================================================================
Looks like I misunderstood the question but the step from "printing" clockwise to "setting" clockwise is really small. Here is the setting flow:
#include <stdio.h>
#define N 5
int main(void) {
int i,j,dim, val = 1;
int matrix[N][N];
// perform spiral print
for (dim = 0; dim < (N+1)/2; dim++)
{
// set initial i and go till the "last column"
i = dim;
for (j = dim; j < N - dim; j++)
{
matrix[i][j] = val++;
}
// bring back i and j to the proper coordinate
// and move down to the "last row"
j--;i++;
for (; i < N - dim; i++)
{
matrix[i][j] = val++;
}
// bring back i and j to the proper coordinate
// and move back to the "first column"
i--;j--;
for (; j >= dim; j--)
{
matrix[i][j] = val++;
}
// bring back i and j to the proper coordinate
// and move up to the "first row"
j++;i--;
for (; i > dim; i--)
{
matrix[i][j] = val++;
}
}
// print the matrix
for (i=0; i < N; i++)
{
for (j=0; j< N; j++)
{
printf("%2d ", matrix[i][j]);
}
printf("\n");
}
return 0;
}
The output as shown here is
1 2 3 4 5
16 17 18 19 6
15 24 25 20 7
14 23 22 21 8
13 12 11 10 9
My solution. Using an "object" struct strangeite_s (from strange ite-rator). It allows ease reusing on different arrays and probably could be even rescaled to support n-dimensional arrays.
The strangeite is initialized using _init function with specified dimensions sizes of an 2d array. Each time _loop is evaluated, the x and y positions are updated and the condition for loop end is checked (and returned). The _inc function should be called on each increment of the iterator.
#include <stdio.h>
#include <limits.h>
#include <stddef.h>
#include <assert.h>
#include <stdint.h>
#include <string.h>
#include <stdbool.h>
struct strangeite_s {
size_t steplen[2];
size_t idx[2];
size_t cursteplen;
int direction;
};
void strangeite_init(struct strangeite_s *t, size_t max_x, size_t max_y)
{
assert(t != NULL);
t->steplen[0] = max_y;
t->steplen[1] = max_x;
memset(t->idx, 0, sizeof(t->idx));
t->direction = 0;
t->cursteplen = t->steplen[0];
}
bool strangeite_loop(const struct strangeite_s *t, size_t *x, size_t *y)
{
if (x) *x = t->idx[0];
if (y) *y = t->idx[1];
for (size_t i = 0; i < sizeof(t->steplen)/sizeof(t->steplen[0]); ++i) {
if (t->steplen[i] == 0) {
return false;
}
}
return true;
}
void strangeite_inc(struct strangeite_s *t)
{
if (t->cursteplen != 1) {
--t->cursteplen;
} else {
t->direction = ++t->direction % (2 * 2);
t->cursteplen = --t->steplen[t->direction % 2];
}
const size_t idx_to_change = t->direction % 2;
t->idx[idx_to_change] = t->idx[idx_to_change] + ( t->direction < 2 ? +1 : -1 );
}
int main()
{
int var[5][5];
struct strangeite_s i;
strangeite_init(&i, 5, 5);
int idx = 0;
for (size_t x, y; strangeite_loop(&i, &x, &y); strangeite_inc(&i)) {
var[y][x] = ++idx;
}
for (size_t i = 0; i < 5; ++i) {
for (size_t j = 0; j < 5; ++j) {
printf("%d ", var[i][j]);
}
printf("\n");
}
return 0;
}
Produces the following output:
1 2 3 4 5
16 17 18 19 6
15 24 25 20 7
14 23 22 21 8
13 12 11 10 9
Live version at onlinegdb.
It's possible to deterministically compute any one entry in the array A_{i,j} as a function only given the array size N, and i, j, in O(1), on-line, without any state, noticing the radius is a geometric progression. The space requirement is O(1) since one doesn't actually need the array to store the values; we can scan the array sequentially. However, like ray-tracing, it probably is slower, (up to a constant, it's still O(N^2).)
#include <stdio.h>
/* N: The size of the (simulated) array. */
#define N (16)
/* i, j: The array indices, as if, a[i][j]. */
static int a(const int i, const int j) {
/* (x,y) translation of (i,-j) to the centre, scaled up 2x for int math. */
const int x = 2 * i + 1 - N, y = -2 * j - 1 + N;
/* Geometric series and an offset +fiddling to get the directionality. */
return N*N - ((x < -y) ?
(-x > -y) ? (x+1)*(x+1) - (y+x)/2 - 1: y*y + (x+y)/2 :
(x > y) ? x*x + (x+y)/2 : (y+1)*y + (-x+y)/2);
}
int main(void) {
int i, j;
for(j = 0; j < N; j++) {
for(i = 0; i < N; i++) {
printf("%3d ", a(i, j));
}
printf("\n");
}
return 0;
}

use to matrix and double pointer

The size of the square matrix is entered as standard input (the range of input values is 2 to 10). Create a program that prints the unit matrix of the input size.
The unit matrix is a matrix whose diagonal from the top left to the bottom right (main diagonal) is 1 and all others are zero.
ex) input: 5
result :
1 0 0 0 0\n
0 1 0 0 0\n
0 0 1 0 0\n
0 0 0 1 0\n
0 0 0 0 1\n
my code:
int main(){
int n;
scanf("%d", &n);
int **matrix = malloc(sizeof(int *) * n);
for (int i = 0; i < n; i++)
{
matrix[i] = malloc(sizeof(int) * n);
memset(matrix[i], 0, sizeof(int) * n);
}
for (int i = 0; i < n; i++)
{
matrix[i][i] = 1;
printf("%d ", matrix[i][i]);
}
printf("\n");
for (int i = 0; i < n; i++)
{
free(matrix[i]);
}
free(matrix);
return 0;
}
.. what 's the error?
You need a double loop to print the output:
for (int i = 0; i < n; i++)
{
matrix[i][i] = 1; // set identity
}
for (int j=0; j<n; j++)
{
for (int i = 0; i < n; i++)
{
printf("%d ", matrix[j][i]);
}
printf("\n");
}
One error is to think yo need a data strucure to print the output requested.
#include <stdlib.h>
#include <stdio.h>
int main(void)
{
int n;
if (scanf("%d", &n) != 1 || n < 2 || 10 < n) {
perror("Input error!\n\n");
return EXIT_FAILURE;
}
for (int i = 0; i < n; ++i) {
for (int k = 0; k < n; ++k)
printf(i == k ? "1 " : "0 ");
putchar('\n');
}
}

Program only looping on the last input

Right now I am programming a thing that takes clues to mastermind and return how many guesses should be left to get the secret code correct. I have a small problem however, as it only works on the last guess that is input, so if only one guess is input, it is correct, but any more and it is not...
Here is my code right now:
#include <stdio.h>
#include <stdlib.h>
int bPegs(int *secret, int *sarr);
void frequency(int *array, int *freq);
int tPegs(int *freqA, int *freqG);
void perm(int list[],int k, int n);
int check(int ba, int bb, int wa, int wb);
int slots, colors, guesses;
int *guess;
int counter = 0;
int main() {
int runs, k;
scanf("%d", &runs);
for (k = 0; k < runs; k++) {
int i, j;
scanf("%d", &slots);
scanf("%d", &colors);
scanf("%d", &guesses);
guess = malloc(sizeof(int) * slots + 2);
int *list = malloc(sizeof(int) * slots);
for (i = 0; i < guesses; i++) {
for (j = 0; j < slots + 2; j++) {
scanf("%d", &guess[j]);
}
}
perm(list, 0, slots);
printf("%d", counter);
}
return 0;
}
int bPegs(int *secrets, int *sarr) {
int i;
int black = 0;
for (i = 0; i < slots; i++) {
if (secrets[i] == sarr[i]) {
black++;
}
}
return black;
}
void frequency(int *array, int *freq) {
int i;
for (i = 0; i < slots; i++) {
freq[array[i]]++;
}
}
int tPegs(int *freqA, int *freqG) {
int i, total = 0;
for (i = 0; i < colors; i++) {
if (freqG[i] > freqA[i]) {
total += freqA[i];
}
if (freqG[i] < freqA[i] && freqG[i] != 0) {
total += freqG[i];
}
if (freqG[i] == freqA[i] && freqA[i] != 0) {
total+=freqG[i];
}
}
return total;
}
int check(int ba,int bb, int wa, int wb) {
if (ba == bb && wa == wb) {
return 1;
} else {
return 0;
}
}
void perm(int list[], int k, int n) {
int j;
int *freqA = calloc(colors, sizeof(int));
int *freqG = calloc(colors, sizeof(int));
if (k == n) {
frequency(list, freqA);
frequency(guess, freqG);
int ba = bPegs(list, guess);
int ta = tPegs(freqA, freqG);
int wa = ta - ba;
int bb = guess[slots];
int wb = guess[slots + 1];
if (check(ba, bb, wa, wb)) {
counter++;
}
} else {
int i;
for (i = 0; i < colors; i++) {
list[k] = i;
perm(list, k + 1, n);
}
}
}
Here is some sample input / output:
input:
1
10 2 1
1 0 1 0 1 0 1 0 1 5 4
output:
200
this much is correct, for an example of it breaking:
input:
1
4 6 4
0 1 2 3 0 2
2 2 4 1 0 2
4 3 3 2 1 1
1 3 5 4 1 3
should give:
1
but it does give:
8
and I cannot figure out how to set this up for more than just one clue... any help would be great.
The main reading loop seems incorrect:
for (j = 0; j < slots + 2; j++) {
("%d", &guess[j]);
}
Did you mean this instead:
for (j = 0; j < slots + 2; j++) {
scanf("%d", &guess[j]);
}

Resources