how can i rewrite this code without using arrays? [closed] - c

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 5 years ago.
Improve this question
#include <stdio.h>
main()
{
int x, y;
scanf("%d", &x);
int a[x][x];
int i, j, low = 0, top = x - 1, n = 1;
for (i = 0; i < x / 2; i++, low++, top--)
{
for (j = low; j <= top; j++, n++)
a[i][j] = n;
for (j = low + 1; j <= top; j++, n++)
a[j][top] = n;
for (j = top - 1; j >= low; j--, n++)
a[top][j] = n;
for (j = top - 1; j > low; j--, n++)
a[j][low] = n;
}
for (i = 0; i < x; i++)
{
for (j = 0; j < x; j++)
{
printf("%d", a[i][j]);
}
printf("\n");
}
}
i want to write a number pattern and this is the code but i wanted to write it without arrays.how can i rewrite this without using any arrays?
and of course x can be both even and odd.
thanks for ur help!]1

#include <stdio.h>
int get(int x, int y, int lt, int n)
{
if(x == 0)
return lt+y;
else if(y == 0)
return lt+4*(n-1)-x;
else if(y == n-1)
return lt+n+x-1;
else if(x == n-1)
return lt+3*(n-1)-y;
else
return get(x-1, y-1, lt+4*(n-1), n-2);
}
int main(void)
{
int n, i, j;
scanf("%d", &n);
for(i = 0; i < n; ++i) {
for(j = 0; j < n; ++j)
printf("%2d ", get(i, j, 1, n));
putchar('\n');
}
return 0;
}

I must agree that this code is incredible difficult for me to understand. I have no clue what is happening here. But I will try to answer it irrespective of the logic/pattern.
So you have a bunch of loops that fill in an array and then another loop that prints it in order. But you don't want to use arrays.
So the value should be calculated when it is to be printed. Let us try it this way -
First I will move your calculating code to a separate function for sake for clarity -
int value_at(int I, int J, int x) {
int i, j, low = 0, top = x - 1, n = 1;
int a = 0;
for (i = 0; i < x / 2; i++, low++, top--) {
for (j = low; j <= top; j++, n++)
if ( i == I && j == J)
a = n;
for (j = low + 1; j <= top; j++, n++)
if ( I == j && J == top)
a = n;
for (j = top - 1; j >= low; j--, n++)
if ( top == I && j == J)
a = n
for (j = top - 1; j > low; j--, n++)
if (j == I && low == J)
a = n;
}
return a;
}
Now this function calculates the value of a for any i or j
Now we can just print the values in a loop -
for (i = 0; i < x; i++)
{
for (j = 0; j < x; j++)
{
printf("%d", value_at(i, j, x));
}
printf("\n");
}

This must do the task :
int min(int a, int b)
{
return a<b ? a:b;
}
void printSpiral(int n)
{
for (int i = 0; i < n; i++)
{
for (int j = 0; j < n; j++)
{
int x;
x = min(min(i, j), min(n-1-i, n-1-j));
// For upper right half
if (i <= j)
printf("%d ", ((n*n) - ((n-2*x)*(n-2*x) - (i-x)
- (j-x)))+1);
// for lower left half
else
printf("%d ", ((n*n) - ((n-2*x-2)*(n-2*x-2) + (i-x)
+ (j-x)))+1);
}
printf("\n");
}
}
Just call printSpiral() and pass your x as argument

Related

Sorting a matrix

Im trying to sort a matrix by the sum of its row's digits, from highest to lowest. I dont know if i explained that correctly so here's some photos explaining it.
This is what my code outputs. Basically, it asks you for m and n, which are the dimensions of the matrix. In this example it's a 3x4, 3 rows and 4 columns. Then, the matrix should be sorted by rows, by the sum of row's digits. Which means, instead of what's being outputted in the picture above, the correct result should be this:
I have no idea how to sort this from highest to lowest, i have been trying for hours to no avail.
Here's my code:
#include <stdio.h>
#define N 30
void main(){
double a[N][N], s[N], p;
int i, j, m, n, max;
while(1){
printf("\nm, n? ");
scanf("%d%d", &m, &n);
if(m <= 0 || m > N || n <=0 || n > N)
break;
for(i = 0; i < m; i++){
printf("%2d. row? ", i+1);
for(j = 0; j < n; scanf("%lf", &a[i][j++]));
}
for(i = 0; i < m; i++)
for(s[i] = j = 0; j < n; s[i] += a[i][j++]);
for(j = 0; j < n - 1; j++){
for(max = i, j = i+1; j < n; j++)
if(s[j] > s[max])
max = i;
if(max != j){
p = s[j];
s[j] = s[max];
s[max] = p;
for(j = 0; j < m; j++){
p = a[j][i];
a[j][i] = a[j][max];
a[j][max] = p;
}
}
}
printf("New matrix: \n");
for(i = 0; i < m; i++){
for(j = 0; j < n; printf("%8.2lf", a[i][j++]));
printf("\n");
}
for(j = 0; j < m; j++)
printf("-------------");
printf("\n");
for(j = 0; j < m; printf("%8.2f \n", s[j++]));
printf("\n");
}
}
You can sort the rows of the matrix from highest to lowest, using a simple bubble sort algorithm.Your code modified below:
int main() {
double a[N][N], s[N], p;
int i, j, m, n, max;
while (1) {
printf("\nm, n? ");
scanf("%d%d", & m, & n);
if (m <= 0 || m > N || n <= 0 || n > N)
break;
for (i = 0; i < m; i++) {
printf("%2d. row? ", i + 1);
for (j = 0; j < n; scanf("%lf", & a[i][j++]));
}
for (i = 0; i < m; i++)
for (s[i] = j = 0; j < n; s[i] += a[i][j++]);
for (i = 0; i < m - 1; i++) { // modified here
for (j = i + 1; j < m; j++) { // modified here
if (s[j] > s[i]) { // modified here
p = s[i];
s[i] = s[j];
s[j] = p;
for (int k = 0; k < n; k++) {
p = a[i][k];
a[i][k] = a[j][k];
a[j][k] = p;
}
}
}
}
printf("New matrix: \n");
for (i = 0; i < m; i++) {
for (j = 0; j < n; printf("%8.2lf", a[i][j++]));
printf("\n");
}
for (j = 0; j < m; j++)
printf("-------------");
printf("\n");
for (j = 0; j < m; printf("%8.2f \n", s[j++]));
printf("\n");
}
return 0;
}
Here's how i modified your code to achieve that:
Initialize a loop variable i to 0.
In the outer loop, run the inner loop j from i+1 to m-1.
In the inner loop, compare the sum of the row i with the sum of row
j. If the sum of row j is greater than the sum of row i, swap the
rows using a temporary variable.
After the inner loop finishes, increment the value of i by 1. Repeat
the outer loop until i becomes equal to m-1.
Output:
You can just use qsort to let it handle the sorting and item swapping. Then you only need to write the code for comparing two rows with each other.
Given something like this:
int matrix[3][4] =
{
{1,2,3,4},
{5,6,7,8},
{9,1,2,3},
};
You'd call qsort as:
qsort(matrix, 3, sizeof(int[4]), compare);
The only complexity is implementing the comparison callback function. There's two things to consider there:
We've told qsort that we have an array of 3 items, each of type int[4]. So the void pointers it passes along to us will actually be pointers to type int[4]. That is: int(*)[4].
qsort sorts in ascending order by default, where the item considered "less" ends up first. So we need to tweak that to get the largest item first.
Example:
int compare (const void* obj1, const void* obj2)
{
const int (*ptr1)[4] = obj1;
const int (*ptr2)[4] = obj2;
size_t sum1=0;
size_t sum2=0;
for(size_t i=0; i<4; i++)
{
sum1 += (*ptr1)[i];
sum2 += (*ptr2)[i];
}
if(sum1 > sum2) // largest sum considered "less" for qsort
return -1;
else
return 1;
return 0;
}
sum1 < sum2 would have placed the smallest row first.
Full example:
#include <stdio.h>
#include <stdlib.h>
int compare (const void* obj1, const void* obj2)
{
const int (*ptr1)[4] = obj1;
const int (*ptr2)[4] = obj2;
size_t sum1=0;
size_t sum2=0;
for(size_t i=0; i<4; i++)
{
sum1 += (*ptr1)[i];
sum2 += (*ptr2)[i];
}
if(sum1 > sum2) // largest sum considered "less" for qsort
return -1;
else
return 1;
return 0;
}
void print_matrix(size_t col, size_t row, int matrix[col][row])
{
for(size_t i=0; i<col; i++)
{
for(size_t j=0; j<row; j++)
{
printf("%d,", matrix[i][j]);
}
puts("");
}
}
int main (void)
{
int matrix[3][4] =
{
{1,2,3,4},
{5,6,7,8},
{9,1,2,3},
};
print_matrix(3,4,matrix);
puts("");
qsort(matrix, 3, sizeof(int[4]), compare);
print_matrix(3,4,matrix);
}

Gauss-Jacobi iteration method

I'm trying to write a programm that solves system of equations Ax=B using Gauss-Jacobi iteration method.
#include <math.h>
#include <stdlib.h>
#include <stdio.h>
int main(void) {
double **a, *b, *x, *f, eps = 1.e-2, c;
int n = 3, m = 3, i, j, bool = 1, d = 3;
/* printf("n=") ; scanf("%d", &n);
printf("m=") ; scanf("%d", &n) */
a =malloc(n * sizeof *a);
for (i = 0; i < n; i++)
a[i] = (double*)malloc(m * sizeof(double));
b = malloc(m * sizeof *b);
x = malloc(m * sizeof *x) ;
f = malloc(m * sizeof *f) ;
for (i = 0; i < n; i++) {
for (j = 0; j < m; j++) {
printf("a[%d][%d]=", i, j);
scanf("%le", &a[i][j]);
if(fabs(a[i][i])<1.e-10) return 0 ;
}
printf("\n") ;
}
printf("\n") ;
for (i = 0; i < n; i++) {
for (j = 0; j < m; j++) {
printf("a[%d][%d]=%le ", i, j, a[i][j]);
}
printf("\n") ;
}
for (j = 0; j < m; j++) {
printf("x[%d]=", j);
scanf("%le", &x[j]);
} //intial guess
printf("\n") ;
for (j = 0; j < m; j++) {
printf("b[%d]=", j);
scanf("%le", &b[j]);
}
printf("\n") ;
while (1) {
bool = 0;
for (i = 0; i < n; i++) {
c = 0.0;
for (j = 0; j < m; j++)
if (j != i)
c += a[i][j] * x[j];
f[i] = (b[i] - c) / a[i][i];
}
for (i = 0; i < m; i++)
if (fabs(f[i] - x[i]) > eps)
bool = 1;
if (bool == 1)
for (i = 0; i < m; i++)
x[i] = f[i];
else if (bool == 0)
break;
}
for (j = 0; j < m; j++)
printf("%le\n", f[j]);
return 0;
}
The condition of stoping the loop is that previous approximation minus current approximation for all x is less than epsilon.
It seems like i did everything according to algorithm,but the programm doesn't work.
Where did i make a mistake?
While not the most strict condition, the usual condition requiered to guarantee convergence in the Jacobi and Gauss-Seidel methods is diagonal dominance,
abs(a[i][i]) > sum( abs(a[i][j]), j=0...n-1, j!=i)
This test is also easy to implement as a check to run before the iteration.
The larger the relative gap in all these inequalities, the faster the convergence of the method.

Why are random values shown as output to find determinant of a matrix?

I wanted to find determinant of a M*M matrix by using recursion in C.
Here is the code I have tried in Ubuntu.
// Computing determinant of a MXM matrix
#include <stdio.h>
int determinant(int M, int A[10][10]) { //Function to calculate det(A)
int i, j, k, m, n, p, q, pow = 1;
int B[10][10];//assuming M does not cross 10
if (M == 1)
return A[0][0];
else {
det = 0;
for (k = 0; k < M; k += 1) {
m = 0;
n = 0; //m,n are indices of subdeterminant of A
for (i = 0; i < M; i += 1) {
for (j = 0; j < M; j += 1) {
if (i != 0 && j != k) {
B[m][n] = A[i][j]; //finding submatrix
if (n < (k - 2))
n += 1;
else {
n = 0;
m += 1;
}
}
}
}
det += pow * (A[0][k] * determinant(M - 1, B));
pow = -1 * pow;
}
return det;
}
}
int main() {
int M, i, j; // M is order of matrix A for which determinant has to be found
printf("Enter the order of matrix: ");
scanf("%d", &M);
int A[10][10];
printf("Enter matrix A: ");
for (i = 0; i < M; i += 1) {
for (j = 0; j < M; j += 1) {
scanf("%d", &A[i][j]); //Entering elements of matrix A
}
}
printf("Given matrix A is: \n");
for (i = 0; i < M; i += 1) {
for (j = 0; j < M; j += 1) {
printf("%d ", A[i][j]);
}
printf("\n");
}
int det = determinant(M, A);
printf("The determinant of given matrix is %d\n", det);
return 0;
}
This code works fine for a matrix of order 2. But for higher orders, the output is some random number. I am unable to identify any mistake in this. Can anyone explain why the output is not as expected and how to rectify the code to get the expected output?
The inner loop that extracts the submatrix B from A seems broken.
Here is a simpler version:
for (i = 1, m = 0; i < M; i++, m++) {
for (j = 0, n = 0; j < k; j++, n++)
B[m][n] = A[i][j];
for (j = k + 1; j < M; j++, n++)
B[m][n] = A[i][j];
}

Merging (interleaving) two sorted arrays sequentially (but NOT sorting it after merging)

I have one array of elements with 1 5 9 (e.g. a1 a2 a3)
and second array of elements with 2 4 8 (e.g. b1 b2 b3)
I want the output to be 1,2 5,4 9,8 (i.e. a1,b1 a2,b2 a3,b3)... Is it possible?
All the loops I tried sort the entire thing like 1,2,4,5,8,9?
Code block:
void merge(int a[], int m, int b[], int n, int sorted[]) {
int i, j, k;
j = k = 0;
for (i = 0; i < m + n;) {
if (j < m && k < n) {
if (a[j] < b[k]) {
sorted[i] = a[j];
j++;
}
else {
sorted[i] = b[k];
k++;
}
i++;
}
else if (j == m) {
for (; i < m + n;) {
sorted[i] = b[k];
k++;
i++;
}
}
else {
for (; i < m + n;) {
sorted[i] = a[j];
j++;
i++;
}
}
}
}
Your condition:
if (a[j] < b[k]) {
enforces sorting, but you said you didn't want sorting, so don't do it.
I'd prefer a simpler looping structure:
while (j < m && k < n)
{
sorted[i++] = a[j++];
sorted[i++] = b[k++];
}
while (j < m)
sorted[i++] = a[j++];
while (k < n)
sorted[i++] = b[k++];
This is more nearly idiomatic C.
The requirement in the question doesn't depend on the input arrays being sorted — it simply interleaves the elements of the two arrays in sequence until one or the other runs out of data, and then copies the rest (if any) of the other array to the output.
It is possible to simplify this code — it doesn't need both j and k:
int i = 0;
int j;
int min = (m < n) ? m : n;
for (j = 0; j < min; j++)
{
sorted[i++] = a[j];
sorted[i++] = b[j];
}
while (j < m)
sorted[i++] = a[j++];
while (j < n)
sorted[i++] = b[j++];
Only one of the while loops will execute the body of the loop, but the while conditions make a separate if test superfluous.
int k = m < n ? n : m;
int j = 0;
for (int i = 0; i < k; i++)
{
if (i < m && i < n)
{
sorted[j++] = a[i];
sorted[j++] = b[i];
}
else
{
while (i < m)
{
sorted[j++] = a[i++];
}
while (i < n)
{
sorted[j++] = b[i++];
}
}
}
Try this....
int i,j,k,m;
int arr[] = {1,5,9};
int arr1[] = {2,4,8};
int l1 = sizeof(arr)/sizeof(int);
int l2 = sizeof(arr1)/sizeof(int);
int arr3[l1+l2];
int l3 = sizeof(arr3)/sizeof(int);
j=0;
k=0;
if(l1>=l2){
for(i=0;i<l1;){
if(arr[i]<arr1[j]){
arr3[k]=arr[i];
i++;
k++;
}else{
arr3[k]=arr1[j];
k++;
j++;
}
if(j==l2){
arr3[k]=arr[i];
i++;
k++;
}
}
}
for(i=0;i<l3;i++){
printf("%d ",arr3[i]);
}
Output
1 2 4 5 8 9
If you want output like this 1,2 5,4 9,8
then change your ifcondition
if (j < m && k < n) {
sorted[i++] = a[j];
j++;
sorted[i++] = b[k];
k++;
}

Initializing a 2d array in C

Here is my code:
int main() {
int x, y;
int *xptr, *yptr;
int array[10][10];
int j;
int k;
int z = 0;
for(j = 0; j < 10; j++) {
for(k = 0; k < 10; k++) {
array[j][k] = j * 10 + k;
}
}
xptr = &array[0][0];
for(j = 0; j < 10; j++) {
for(k = 0; k < 10; k++) {
printf("array[%d][%d] = %d \n", j, k, *(xptr + j), (xptr + k));
}
}
system("PAUSE");
}
I am trying to initialize a 2d array so that at [0][0] it equals 0 and at [9][9] it equals 99. With the way that it is now, [0][0-9] all equal 0 and then [1][0-9] all equal 1. How would I properly load this array in the fashion that I mentioned?
for(j = 0; j < 10; j++) {
for(k = 0; k < 10; k++) {
array[j][k] = j*10 + k;
}
}
I'm assuming you've actually declared everything, but didn't include it in the example. You simply want
array[j][k] = j*10 + k;

Resources