C dynamic 2d Matrices struct frustration - arrays

I searched all over the internet and watched tons of video and nobody does this thing :
Create a struct matrix that can dynamicly change its KxN direct from the main , for example
I will use java :
Matrix(int k , int n){
int Mat[k][n];
}
main(){
Matrix a = new Matrix (2,3);
a.Mat[0][0] = 1;
syso(a.Mat[0][0]);
}
Im begining to think its imposible , I tried to alocate memory from the main and it worked , this is how I did it
int** arr = malloc(sizeof(int*)*n)
for (int i = 0 ; i < k ; i=+){
arr[i] = malloc(sizeof(int)*3);
}
but the problem is I cannot do it inside a struct for some reason .. I need to keep my main clean so all my work should be done above the main ,
this is my C program that doesn't work :
//__________________HEADER_________________________________________________//
#include <stdio.h>
#include <stdlib.h>
//__________________________________________________________________________//
//__________________OBJECTS______________________________________________________//
typedef struct {
int n , k ;
int** Mat;
}Matrix;
//______________________________________________________________________________//
//___________________MAIN_____________________________________________________//
int main (void) {
printf("Start..\n\n");
Matrix aqq = {2,5} ;
aqq.Mat[0][0] = 5 ;
printf("\n size : %dx%d first element : %d \n",aqq.n , aqq.k , aqq.Mat[0][0]);
printf("\n\nEnd\n");
}
//______________________________________________________________________________//
I need to make all the getters and setter mult transpose all the matrices functions including linear copying guassian elemination .. everything and I would like to receive maybe a link to some guide lines or even a book , I don't care as long as I could study from it because its really difficult to work like that there are too many rules that involves memory and not a single reliable source of information because every body doing the easy stuff on the tutorials
so to sum up , the final goal is to control every function completely through the main

Here's code that could be split into three files — matrix.h, matrix.c and test.matrix.c.
The header matrix.h declares an opaque type Matrix and some functions to manipulate that type — a constructor (the third option in my comment), a destructor, routines to get and set element values, and routines to get the array dimensions.
The implementation file matrix.c defines the functions. It uses assertions to ensure the validity of arguments — lazy but effective as long as you never compile with -DNDEBUG. If you do suppress assertions, you need to put proper error handling into the functions. Deciding how to handle errors detected by corrupted data structures is a project-wide decision. The code is careful to free any already allocated memory if there is an allocation failure during the construction of a matrix. It defines the struct Matrix, but that type is not accessible outside this source file.
The test file test.matrix.c provides some code to use all the functions declared in matrix.h and demonstrates that square and rectangular matrices work. The code in this file cannot dereference the matrix structure; it must use the access functions.
The resulting code is quite big, but it does the job and demonstrates that you can indeed use structures to store matrices. Write a matrix multiplication routine is a simple exercise.
/* SOF - matrix.h */
#ifndef MATRIX_H_INCLUDED
#define MATRIX_H_INCLUDED
#include <stddef.h> /* size_t */
enum { MATRIX_MAX_SIZE = 1000 };
typedef struct Matrix Matrix; /* Opaque type */
extern Matrix *matrix_constructor(size_t rows, size_t cols);
extern void matrix_destructor(Matrix *mtx);
extern int matrix_get_element(const Matrix *mtx, size_t r, size_t c);
extern void matrix_set_element(Matrix *mtx, size_t r, size_t c, int v);
extern size_t matrix_get_cols(const Matrix *mtx);
extern size_t matrix_get_rows(const Matrix *mtx);
#endif /* MATRIX_H_INCLUDED */
/* EOF - matrix.h */
/* SOF - matrix.c */
/*#include "matrix.h"*/
#include <assert.h>
#include <stdlib.h>
struct Matrix
{
size_t rows;
size_t cols;
int **data;
};
/* It is important to prevent memory leaks on allocation failure */
Matrix *matrix_constructor(size_t rows, size_t cols)
{
assert(rows <= MATRIX_MAX_SIZE && rows > 0);
assert(cols <= MATRIX_MAX_SIZE && cols > 0);
Matrix *mtx = malloc(sizeof(*mtx));
if (mtx == NULL)
return NULL;
mtx->data = malloc(sizeof(*mtx->data) * rows);
if (mtx->data == NULL)
{
free(mtx);
return NULL;
}
for (size_t i = 0; i < rows; i++)
{
mtx->data[i] = malloc(sizeof(*mtx->data[i]) * cols);
if (mtx->data[i] == NULL)
{
while (i > 0)
free(mtx->data[--i]);
free(mtx);
return NULL;
}
}
mtx->rows = rows;
mtx->cols = cols;
return mtx;
}
void matrix_destructor(Matrix *mtx)
{
assert(mtx != NULL && mtx->data != NULL);
assert(mtx->rows <= MATRIX_MAX_SIZE && mtx->rows > 0);
assert(mtx->cols <= MATRIX_MAX_SIZE && mtx->cols > 0);
for (size_t i = 0; i < mtx->rows; i++)
free(mtx->data[i]);
free(mtx->data);
free(mtx);
}
int matrix_get_element(const Matrix *mtx, size_t r, size_t c)
{
assert(mtx != NULL && mtx->data != NULL);
assert(mtx->rows <= MATRIX_MAX_SIZE && mtx->rows > 0);
assert(mtx->cols <= MATRIX_MAX_SIZE && mtx->cols > 0);
return mtx->data[r][c];
}
void matrix_set_element(Matrix *mtx, size_t r, size_t c, int v)
{
assert(mtx != NULL && mtx->data != NULL);
assert(mtx->rows <= MATRIX_MAX_SIZE && mtx->rows > 0);
assert(mtx->cols <= MATRIX_MAX_SIZE && mtx->cols > 0);
mtx->data[r][c] = v;
}
size_t matrix_get_rows(const Matrix *mtx)
{
assert(mtx != NULL && mtx->data != NULL);
assert(mtx->rows <= MATRIX_MAX_SIZE && mtx->rows > 0);
assert(mtx->cols <= MATRIX_MAX_SIZE && mtx->cols > 0);
return mtx->rows;
}
size_t matrix_get_cols(const Matrix *mtx)
{
assert(mtx != NULL && mtx->data != NULL);
assert(mtx->rows <= MATRIX_MAX_SIZE && mtx->rows > 0);
assert(mtx->cols <= MATRIX_MAX_SIZE && mtx->cols > 0);
return mtx->cols;
}
/* EOF - matrix.c */
/* SOF - test.matrix.c */
/*#include "matrix.h"*/
#include <errno.h>
#include <stdarg.h>
#include <stdint.h> /* intmax_t */
#include <stdio.h>
/*#include <stdlib.h>*/
#include <string.h>
#include <time.h>
/* Cannot dereference Matrix pointers here! */
static void matrix_print(const char *tag, const Matrix *mtx, int width)
{
size_t rows = matrix_get_rows(mtx);
size_t cols = matrix_get_cols(mtx);
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%*d", pad, width, matrix_get_element(mtx, r, c));
pad = ", ";
}
putchar('\n');
}
}
static void matrix_random(Matrix *mtx)
{
size_t rows = matrix_get_rows(mtx);
size_t cols = matrix_get_cols(mtx);
for (size_t r = 0; r < rows; r++)
{
for (size_t c = 0; c < cols; c++)
matrix_set_element(mtx, r, c, (rand() % (rows * cols) + 1));
}
}
static int i_log10(size_t n)
{
if (n < 10)
return 1;
int c = 1;
while (n >= 10)
{
n /= 10;
c++;
}
return c;
}
static int i_pow10(int n)
{
int r = 1;
while (n-- > 0)
r *= 10;
return r;
}
static void matrix_ordered(Matrix *mtx)
{
size_t rows = matrix_get_rows(mtx);
size_t cols = matrix_get_cols(mtx);
int mul = i_pow10(i_log10(cols));
for (size_t r = 0; r < rows; r++)
{
for (size_t c = 0; c < cols; c++)
matrix_set_element(mtx, r, c, (r + 1) * mul + c + 1);
}
}
static void err_exit(const char *fmt, ...)
{
va_list args;
int errnum = errno;
va_start(args, fmt);
vfprintf(stderr, fmt, args);
if (errnum != 0)
fprintf(stderr, " (%d: %s)", errnum, strerror(errnum));
putc('\n', stderr);
exit(EXIT_FAILURE);
}
static Matrix *matrix_checked_constructor(const char *tag, size_t rows, size_t cols)
{
Matrix *mp = matrix_constructor(rows, cols);
if (mp == NULL)
err_exit("Failed to construct matrix %s", tag);
return mp;
}
int main(void)
{
Matrix *mi5 = matrix_checked_constructor("MI5", 5, 5);
Matrix *mi6 = matrix_checked_constructor("MI6", 6, 6);
Matrix *ks69 = matrix_checked_constructor("KS69", 6, 9);
Matrix *bw1815 = matrix_checked_constructor("BW1815", 18, 15);
time_t now = time(0);
srand(now);
printf("Seed: %jd\n", (intmax_t)now);
matrix_random(mi5);
matrix_random(mi6);
matrix_ordered(ks69);
matrix_ordered(bw1815);
matrix_print("MI5", mi5, 2);
matrix_print("MI6", mi6, 2);
matrix_print("KS69", ks69, 3);
matrix_print("BW1815", bw1815, 4);
matrix_destructor(mi5);
matrix_destructor(mi6);
return 0;
}
/* EOF - test.matrix.c */
Example output:
Seed: 1605897737
MI5 (5x5):
14, 22, 5, 21, 11
23, 5, 23, 7, 2
10, 9, 9, 2, 24
10, 6, 21, 6, 11
5, 11, 5, 18, 3
MI6 (6x6):
25, 33, 4, 18, 24, 19
6, 1, 23, 19, 6, 24
17, 2, 26, 3, 2, 32
7, 34, 8, 5, 11, 33
6, 7, 34, 13, 21, 14
15, 25, 32, 11, 28, 28
KS69 (6x9):
11, 12, 13, 14, 15, 16, 17, 18, 19
21, 22, 23, 24, 25, 26, 27, 28, 29
31, 32, 33, 34, 35, 36, 37, 38, 39
41, 42, 43, 44, 45, 46, 47, 48, 49
51, 52, 53, 54, 55, 56, 57, 58, 59
61, 62, 63, 64, 65, 66, 67, 68, 69
BW1815 (18x15):
101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115
201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215
301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315
401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415
501, 502, 503, 504, 505, 506, 507, 508, 509, 510, 511, 512, 513, 514, 515
601, 602, 603, 604, 605, 606, 607, 608, 609, 610, 611, 612, 613, 614, 615
701, 702, 703, 704, 705, 706, 707, 708, 709, 710, 711, 712, 713, 714, 715
801, 802, 803, 804, 805, 806, 807, 808, 809, 810, 811, 812, 813, 814, 815
901, 902, 903, 904, 905, 906, 907, 908, 909, 910, 911, 912, 913, 914, 915
1001, 1002, 1003, 1004, 1005, 1006, 1007, 1008, 1009, 1010, 1011, 1012, 1013, 1014, 1015
1101, 1102, 1103, 1104, 1105, 1106, 1107, 1108, 1109, 1110, 1111, 1112, 1113, 1114, 1115
1201, 1202, 1203, 1204, 1205, 1206, 1207, 1208, 1209, 1210, 1211, 1212, 1213, 1214, 1215
1301, 1302, 1303, 1304, 1305, 1306, 1307, 1308, 1309, 1310, 1311, 1312, 1313, 1314, 1315
1401, 1402, 1403, 1404, 1405, 1406, 1407, 1408, 1409, 1410, 1411, 1412, 1413, 1414, 1415
1501, 1502, 1503, 1504, 1505, 1506, 1507, 1508, 1509, 1510, 1511, 1512, 1513, 1514, 1515
1601, 1602, 1603, 1604, 1605, 1606, 1607, 1608, 1609, 1610, 1611, 1612, 1613, 1614, 1615
1701, 1702, 1703, 1704, 1705, 1706, 1707, 1708, 1709, 1710, 1711, 1712, 1713, 1714, 1715
1801, 1802, 1803, 1804, 1805, 1806, 1807, 1808, 1809, 1810, 1811, 1812, 1813, 1814, 1815

Related

Generate all possible combinations of 3 digits without repetition

I'm trying to write a program that prints all possible combinations of three digits.
And there is the constraint that:
The three digits must be different
012, 120, 102, 021, 201, and 210 are considered the same combination of the three digits 0, 1 and 2
Print only the smallest combination of three digits
The expected output is as follows
012, 013, 014, 015, 016, 017, 018, 019, 023, 024, 025, 026, 027, 028, 029, 034, 035, 036, 037, 038, 039, 045, 046, 047, 048, 049, 056, 057, 058, 059, 067, 068, 069, 078, 079, 089, 123, 124, 125, 126, 127, 128, 129, 134, 135, 136, 137, 138, 139, 145, 146, 147, 148, 149, 156, 157, 158, 159, 167, 168, 169, 178, 179, 189, 234, 235, 236, 237, 238, 239, 245, 246, 247, 248, 249, 256, 257, 258, 259, 267, 268, 269, 278, 279, 289, 345, 346, 347, 348, 349, 356, 357, 358, 359, 367, 368, 369, 378, 379, 389, 456, 457, 458, 459, 467, 468, 469, 478, 479, 489, 567, 568, 569, 578, 579, 589, 678, 679, 689, 789
I'm trying to implement in C but the algorithm or any language implementation will suffice.
Here is what I've done so far but it's inacurrate.
#include <stdio.h>
/**
* main - entry point
*
* Description: display triple digits and ,
*
* Return: Always 0 (successful)
*/
int main(void)
{
int i, j, k, l;
i = 0;
while (i < 1000)
{
j = i / 100; /* hundreds */
k = (i / 10) % 10; /* tens */
l = i % 100; /* units */
if (j < k && k < l)
{
putchar(l + '0');
putchar(k + '0');
putchar(j + '0');
if (i < 789)
{
putchar(',');
putchar(' ');
}
}
i++;
}
putchar('\n');
return (0);
}
Here is a fairly compact snippet of code for giving the smallest unique three-digit number.
#include <stdio.h>
int main()
{
char digit[4];
for (int i = 0; i < 8; i++)
{
for (int j = i + 1; j < 9; j++)
{
for (int k = j + 1; k < 10; k++)
{
digit[0] = i + '0';
digit[1] = j + '0';
digit[2] = k + '0';
digit[3] = '\0';
printf("%s\n", digit);
}
}
}
return 0;
}
You can give that a try.
You can do:
#include <stdio.h>
int main (void) {
char h = '0', t = '1', u = '2';
while ((h <= '7') || (t <= '8') || (u <= '9')) {
printf ("%c%c%c, ", h, t, u);
u != '9' ? ++u : (t != '8' ? (++t, u = t + 1) : (++h, t = h + 1, u = t + 1));
}
return 0;
}
Output:
012, 013, 014, 015, 016, 017, 018, 019, 023, 024, 025, 026, 027, 028, 029, 034,
035, 036, 037, 038, 039, 045, 046, 047, 048, 049, 056, 057, 058, 059, 067, 068,
069, 078, 079, 089, 123, 124, 125, 126, 127, 128, 129, 134, 135, 136, 137, 138,
139, 145, 146, 147, 148, 149, 156, 157, 158, 159, 167, 168, 169, 178, 179, 189,
234, 235, 236, 237, 238, 239, 245, 246, 247, 248, 249, 256, 257, 258, 259, 267,
268, 269, 278, 279, 289, 345, 346, 347, 348, 349, 356, 357, 358, 359, 367, 368,
369, 378, 379, 389, 456, 457, 458, 459, 467, 468, 469, 478, 479, 489, 567, 568,
569, 578, 579, 589, 678, 679, 689, 789,
Explanation:
In the program - h, t and u represents digit at hundredth location, digit at tenth location and digit at unit location respectively in a three digit number.
Initialised h with '0', t with '1' and u with '2' because 012 is the smallest three digit number without any of the digits being repeated.
while loop condition ((h <= '7') || (t <= '8') || (u <= '9')) because 789 is biggest three digit number which follow constraint of - smallest combination of three digits without any of the digits being repeated. Any other combination of 7, 8 and 9 will be bigger than 789 and any three digit number bigger than 789 will violat one of the given constraints.
If you find it difficult to understand the expression with ternary operation
u != '9' ? ++u : (t != '8' ? (++t, u = t + 1) : (++h, t = h + 1, u = t + 1));
then here is simplified version using if else :
if (u != '9') {
++u;
} else {
if (t != '8') {
++t;
u = t + 1; // due to given constraint, u will always greater than t
} else {
++h;
t = h + 1; // due to given constraint, t will always greater than h
u = t + 1; // due to given constraint, u will always greater than t
}
}
Here's some annotated code that might improve the outcome.
char *sep = ""; // the separator to use. Put this line ahead of the loop
and
// meaningful names mean no comment required
// EDIT: thank you, #Chux
int unit = i % 10;
int tens = i / 10 % 10;
int hund = i /100 % 10;
if ( unit < tens && tens < hund )
printf( "%s%c%c%c", sep, hund + '0', tens + '0', unit + '0' ), sep = ", ";
Notice that 'j', 'k' and 'l' have no meaning to this problem. Easy to putchar() the numbers in reverse order without noticing...
Of course, if this is not a homework assignment (Prof wouldn't believe you wrote this)...
#include <stdio.h>
int main() {
char *sep = "", *dgts = "0123456789";
for( int h = 0; dgts[h]; h++ )
for( int t = h+1; dgts[t]; t++ )
for( int u = t+1; dgts[u]; u++ )
printf( "%s%c%c%c", sep, dgts[h], dgts[t], dgts[u] ), sep = ", ";
putchar( '\n' );
return 0;
}
And, to use the equivalence of array addressing and pointers.
#include <stdio.h>
int main() {
char *h, *t, *u, *sep = "";
for( h = "0123456789"; *h; h++ )
for( t = h+1; *t; t++ )
for( u = t+1; *u; u++ )
printf( "%s%c%c%c", sep, *h, *t, *u), sep = ", ";
putchar( '\n' );
return 0;
}
Inspired by comment by #Chux, here is the same thing expanded to printing 4 digits. Comparison will show the few trivial alterations needed.
#include <stdio.h>
int main() {
char *m, *h, *t, *u, *sep = "";
for( m = "0123456789"; *m; m++ )
for( h = m+1; *h; h++ )
for( t = h+1; *t; t++ )
for( u = t+1; *u; u++ )
printf( "%s%c%c%c%c", sep, *m, *h, *t, *u), sep = ", ";
putchar( '\n' );
return 0;
}
Here is how I went about my solution:
int main(void)
{
int a, b, c;
for (a = 0; a < 8; a++)
{
for (b = a + 1; b < 9; b++)
{
for (c = b + 1; c < 10; c++)
{
if (a != b && a != c && b != c)
{
putchar(a + '0');
putchar(b + '0');
putchar(c + '0');
if (a + b + c < 24)
{
putchar(',');
putchar(' ');
}
}
}
}
}
putchar('\n');
return (0);
}
The variables in order of a, b, & c; a for 1st digit, b for 2nd and c for 3rd.
The use of b = a + 1 & c = b + 1 was an idea given to me by user #chux - Reinstate Monica in another post that linked me to this one that involved two integers instead of 3 (For two digits, the code only needs to be slightly tweaked to cater for 2 integers).
Moving on.
The if statements:
if (a != b && a != c && b != c)
and
if (a + b + c < 24)
will filter out the duplicates and ensure that the comma and space are not applied to the last combo of integers respectively (i.e. 789, which sum up to give 24).

Possible different combinations of two digits in C language [duplicate]

I'm trying to write a program that prints all possible combinations of three digits.
And there is the constraint that:
The three digits must be different
012, 120, 102, 021, 201, and 210 are considered the same combination of the three digits 0, 1 and 2
Print only the smallest combination of three digits
The expected output is as follows
012, 013, 014, 015, 016, 017, 018, 019, 023, 024, 025, 026, 027, 028, 029, 034, 035, 036, 037, 038, 039, 045, 046, 047, 048, 049, 056, 057, 058, 059, 067, 068, 069, 078, 079, 089, 123, 124, 125, 126, 127, 128, 129, 134, 135, 136, 137, 138, 139, 145, 146, 147, 148, 149, 156, 157, 158, 159, 167, 168, 169, 178, 179, 189, 234, 235, 236, 237, 238, 239, 245, 246, 247, 248, 249, 256, 257, 258, 259, 267, 268, 269, 278, 279, 289, 345, 346, 347, 348, 349, 356, 357, 358, 359, 367, 368, 369, 378, 379, 389, 456, 457, 458, 459, 467, 468, 469, 478, 479, 489, 567, 568, 569, 578, 579, 589, 678, 679, 689, 789
I'm trying to implement in C but the algorithm or any language implementation will suffice.
Here is what I've done so far but it's inacurrate.
#include <stdio.h>
/**
* main - entry point
*
* Description: display triple digits and ,
*
* Return: Always 0 (successful)
*/
int main(void)
{
int i, j, k, l;
i = 0;
while (i < 1000)
{
j = i / 100; /* hundreds */
k = (i / 10) % 10; /* tens */
l = i % 100; /* units */
if (j < k && k < l)
{
putchar(l + '0');
putchar(k + '0');
putchar(j + '0');
if (i < 789)
{
putchar(',');
putchar(' ');
}
}
i++;
}
putchar('\n');
return (0);
}
Here is a fairly compact snippet of code for giving the smallest unique three-digit number.
#include <stdio.h>
int main()
{
char digit[4];
for (int i = 0; i < 8; i++)
{
for (int j = i + 1; j < 9; j++)
{
for (int k = j + 1; k < 10; k++)
{
digit[0] = i + '0';
digit[1] = j + '0';
digit[2] = k + '0';
digit[3] = '\0';
printf("%s\n", digit);
}
}
}
return 0;
}
You can give that a try.
You can do:
#include <stdio.h>
int main (void) {
char h = '0', t = '1', u = '2';
while ((h <= '7') || (t <= '8') || (u <= '9')) {
printf ("%c%c%c, ", h, t, u);
u != '9' ? ++u : (t != '8' ? (++t, u = t + 1) : (++h, t = h + 1, u = t + 1));
}
return 0;
}
Output:
012, 013, 014, 015, 016, 017, 018, 019, 023, 024, 025, 026, 027, 028, 029, 034,
035, 036, 037, 038, 039, 045, 046, 047, 048, 049, 056, 057, 058, 059, 067, 068,
069, 078, 079, 089, 123, 124, 125, 126, 127, 128, 129, 134, 135, 136, 137, 138,
139, 145, 146, 147, 148, 149, 156, 157, 158, 159, 167, 168, 169, 178, 179, 189,
234, 235, 236, 237, 238, 239, 245, 246, 247, 248, 249, 256, 257, 258, 259, 267,
268, 269, 278, 279, 289, 345, 346, 347, 348, 349, 356, 357, 358, 359, 367, 368,
369, 378, 379, 389, 456, 457, 458, 459, 467, 468, 469, 478, 479, 489, 567, 568,
569, 578, 579, 589, 678, 679, 689, 789,
Explanation:
In the program - h, t and u represents digit at hundredth location, digit at tenth location and digit at unit location respectively in a three digit number.
Initialised h with '0', t with '1' and u with '2' because 012 is the smallest three digit number without any of the digits being repeated.
while loop condition ((h <= '7') || (t <= '8') || (u <= '9')) because 789 is biggest three digit number which follow constraint of - smallest combination of three digits without any of the digits being repeated. Any other combination of 7, 8 and 9 will be bigger than 789 and any three digit number bigger than 789 will violat one of the given constraints.
If you find it difficult to understand the expression with ternary operation
u != '9' ? ++u : (t != '8' ? (++t, u = t + 1) : (++h, t = h + 1, u = t + 1));
then here is simplified version using if else :
if (u != '9') {
++u;
} else {
if (t != '8') {
++t;
u = t + 1; // due to given constraint, u will always greater than t
} else {
++h;
t = h + 1; // due to given constraint, t will always greater than h
u = t + 1; // due to given constraint, u will always greater than t
}
}
Here's some annotated code that might improve the outcome.
char *sep = ""; // the separator to use. Put this line ahead of the loop
and
// meaningful names mean no comment required
// EDIT: thank you, #Chux
int unit = i % 10;
int tens = i / 10 % 10;
int hund = i /100 % 10;
if ( unit < tens && tens < hund )
printf( "%s%c%c%c", sep, hund + '0', tens + '0', unit + '0' ), sep = ", ";
Notice that 'j', 'k' and 'l' have no meaning to this problem. Easy to putchar() the numbers in reverse order without noticing...
Of course, if this is not a homework assignment (Prof wouldn't believe you wrote this)...
#include <stdio.h>
int main() {
char *sep = "", *dgts = "0123456789";
for( int h = 0; dgts[h]; h++ )
for( int t = h+1; dgts[t]; t++ )
for( int u = t+1; dgts[u]; u++ )
printf( "%s%c%c%c", sep, dgts[h], dgts[t], dgts[u] ), sep = ", ";
putchar( '\n' );
return 0;
}
And, to use the equivalence of array addressing and pointers.
#include <stdio.h>
int main() {
char *h, *t, *u, *sep = "";
for( h = "0123456789"; *h; h++ )
for( t = h+1; *t; t++ )
for( u = t+1; *u; u++ )
printf( "%s%c%c%c", sep, *h, *t, *u), sep = ", ";
putchar( '\n' );
return 0;
}
Inspired by comment by #Chux, here is the same thing expanded to printing 4 digits. Comparison will show the few trivial alterations needed.
#include <stdio.h>
int main() {
char *m, *h, *t, *u, *sep = "";
for( m = "0123456789"; *m; m++ )
for( h = m+1; *h; h++ )
for( t = h+1; *t; t++ )
for( u = t+1; *u; u++ )
printf( "%s%c%c%c%c", sep, *m, *h, *t, *u), sep = ", ";
putchar( '\n' );
return 0;
}
Here is how I went about my solution:
int main(void)
{
int a, b, c;
for (a = 0; a < 8; a++)
{
for (b = a + 1; b < 9; b++)
{
for (c = b + 1; c < 10; c++)
{
if (a != b && a != c && b != c)
{
putchar(a + '0');
putchar(b + '0');
putchar(c + '0');
if (a + b + c < 24)
{
putchar(',');
putchar(' ');
}
}
}
}
}
putchar('\n');
return (0);
}
The variables in order of a, b, & c; a for 1st digit, b for 2nd and c for 3rd.
The use of b = a + 1 & c = b + 1 was an idea given to me by user #chux - Reinstate Monica in another post that linked me to this one that involved two integers instead of 3 (For two digits, the code only needs to be slightly tweaked to cater for 2 integers).
Moving on.
The if statements:
if (a != b && a != c && b != c)
and
if (a + b + c < 24)
will filter out the duplicates and ensure that the comma and space are not applied to the last combo of integers respectively (i.e. 789, which sum up to give 24).

Finding the first prime number after the entered one

I'm trying to find the first prime number after n, unless entered n is already prime (then the program prints out n and terminates).
Example input:
n = 7
The first prime number is: 7 (Good)
n = 591
The first prime number is: 591 (Not right, 591 is not a prime number)
n = 14
The first prime number is: 15 (This is also false, shouldn't it be 17?)
Where am I making a mistake? It might be an obvious one, but I'm just starting out.
#include <stdio.h>
int main(){
int i = 2, n, m;
printf("n = ");
do
scanf("%d", &n);
while (n < 2);
m = n / 2;
if (n == 2){
printf("The first prime number is: %d", n);
return 0;
}
while ( i <= m ){
if (n % i == 0)
n++;
if (n % i != 0){
printf("The first prime number is: %d", n);
return 0;
} else i++;
}
return 0;
}
Your logic for determining a prime number is wrong.
First of all you should write a function ( not necessarily but it is recommended ) to check whether one number is prime. Here's the code for this function:
int checkPrimeNumber(int n)
{
int j, flag = 1;
for(j=2; j <= n/2; ++j)
{
if (n%j == 0)
{
flag =0;
break;
}
}
return flag;
}
Once you include the function your while loop should loop until if finds the first prime number starting from N using that function. Below is a code for that function.
You can also check this answer here:
https://codereview.stackexchange.com/questions/71212/find-smallest-prime-number-greater-than-given-n
The following two pieces of logic should solve your problem.
int IsPrime(int n)
{
int i;
for( i=2; i <= n/i; i++)
if( n%i == 0 ) return 0;
return 1;
}
This function determines reasonably quickly whether the integer passed in is prime. It stops testing once it has passed the square root of the test integer.
int FirstPrime(int n)
{
while( !IsPrime(n) )
n++;
return n;
}
This function contains the basic logic set out in your problem statement: return the input value, if prime, or failing that the first integer after that value that is prime.
Breaking the code into separate functions makes it much easier to test and to reason about the code.
Checking primality
This is the simpler code that I use for detecting primes:
int isprime(unsigned number)
{
if (number <= 1)
return 0;
if (number == 2 || number == 3)
return 1;
if (number % 2 == 0 || number % 3 == 0)
return 0;
for (unsigned x = 5; x * x <= number; x += 6)
{
if (number % x == 0 || number % (x + 2) == 0)
return 0;
}
return 1;
}
It exploits the fact that all prime numbers larger than 3 have the form 6N±1. It's easy to see why. All the numbers of the forms 6N+0, 6N+2, 6N+4 are clearly divisible by 2 and the numbers of the form 6N+3 are clearly divisible by 3, which leaves only 6N+1 and 6N+5 as possibly prime — and 6N+5 is equivalent to 6(N+1)-1, so the formula 6N±1 covers them properly. For N = 1, 6N±1 yields 5 and 7 which are prime; N = 2 yields 11 and 13 which are prime; N = 3 yields 17 and 19 which are prime; N = 4 yields 23 and 25, of which 23 is prime and 25 is not. All primes bigger than 3 are of the form 6N±1; not all numbers of the form 6N±1 are prime. All this means that the code only checks two divisors out of every six as it steps through the range up to the square root of the number.
I have a more complex variant which knows the primes up to 100, and then goes stepping every 6:
int isprime(unsigned number)
{
if (number <= 1)
return 0;
if (number == 2 || number == 3)
return 1;
if (number % 2 == 0 || number % 3 == 0)
return 0;
static const unsigned int small_primes[] =
{
5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47,
53, 59, 61, 67, 71, 73, 79, 83, 87, 89, 91, 97
};
enum { NUM_SMALL_PRIMES = sizeof(small_primes) / sizeof(small_primes[0]) };
for (unsigned i = 0; i < NUM_SMALL_PRIMES; i++)
{
if (number == small_primes[i])
return 1;
if (number % small_primes[i] == 0)
return 0;
}
for (unsigned i = 101; i * i <= number; i += 6)
{
if (number % i == 0 || number % (i + 2) == 0)
return 0;
}
return 1;
}
This is usually marginally faster than the other, but only by a very small amount.
Next prime after
I originally wrote this code for another SO question that was deleted before I posted an answer; it uses another variant of isprime() with a table of primes up to 1013.
/* Inspired by the deleted question SO 5308-6674 */
/* Determine the next prime after a given number */
#include <assert.h>
#include <stdio.h>
#include <limits.h>
#include <stdbool.h>
#define NEXT_PRIME_AFTER /* Avoid unnecessary checks in is_prime() */
#ifdef TEST
static unsigned primes[] = { 2, 3, 5, 7, 11 };
#else
static unsigned primes[] =
{
2, 3, 5, 7, 11, 13, 17, 19, 23, 29,
31, 37, 41, 43, 47, 53, 59, 61, 67, 71,
73, 79, 83, 89, 97, 101, 103, 107, 109, 113,
127, 131, 137, 139, 149, 151, 157, 163, 167, 173,
179, 181, 191, 193, 197, 199, 211, 223, 227, 229,
233, 239, 241, 251, 257, 263, 269, 271, 277, 281,
283, 293, 307, 311, 313, 317, 331, 337, 347, 349,
353, 359, 367, 373, 379, 383, 389, 397, 401, 409,
419, 421, 431, 433, 439, 443, 449, 457, 461, 463,
467, 479, 487, 491, 499, 503, 509, 521, 523, 541,
547, 557, 563, 569, 571, 577, 587, 593, 599, 601,
607, 613, 617, 619, 631, 641, 643, 647, 653, 659,
661, 673, 677, 683, 691, 701, 709, 719, 727, 733,
739, 743, 751, 757, 761, 769, 773, 787, 797, 809,
811, 821, 823, 827, 829, 839, 853, 857, 859, 863,
877, 881, 883, 887, 907, 911, 919, 929, 937, 941,
947, 953, 967, 971, 977, 983, 991, 997, 1009, 1013,
};
#endif /* TEST */
enum { N_PRIMES = sizeof(primes) / sizeof(primes[0]) };
/*
** In the context of next_prime_after(), this function is never called
** upon to validate small numbers - numbers less than primes[N_PRIMES-1]
** are not passed here. In more general contexts, the extra conditions
** in the conditionally compiled code are necessary for accuracy.
*/
static bool is_prime(unsigned p)
{
for (int i = 0; i < N_PRIMES; i++)
{
#ifndef NEXT_PRIME_AFTER
if (p < primes[i])
return false;
if (p == primes[i])
return true;
#endif /* NEXT_PRIME_AFTER */
if (p % primes[i] == 0)
return false;
}
for (unsigned t = primes[N_PRIMES - 1]; t * t <= p; t += 6)
{
if (p % t == 0)
return false;
if (p % (t + 2) == 0)
return false;
}
return true;
}
static unsigned next_prime_after(unsigned start)
{
for (int i = 0; i < N_PRIMES; i++)
{
if (start < primes[i])
return primes[i];
}
for (unsigned x = (start + 1) / 6; x < UINT_MAX / 6; x++)
{
unsigned t = 6 * x - 1;
if (t > start && is_prime(t))
return(t);
t += 2;
if (t > start && is_prime(t))
return(t);
}
return 0;
}
int main(void)
{
assert((primes[N_PRIMES-1]+1) % 6 == 0);
for (unsigned u = 0; u < 100; u++)
printf("%3u => %3u\n", u, next_prime_after(u));
for (unsigned t = 100, u = next_prime_after(t); u < 12345678; t = u)
printf("%3u => %3u\n", t, (u = next_prime_after(t)));
}
Be wary of the isprime() function here. It is tailored to this context and omits checks that would be necessary with a general purpose, standalone prime tester. The next_prime_after() steps through the list of known primes (if you're likely to be dealing with many big possible primes, you might add a test to see whether it is worth stepping through the first loop at all), and then steps through the 6N±1 sequence looking for a prime.
The test code prints the next prime after each number from 0 to 99. Thereafter, it steps through the primes up to 12345701 (which is the first prime after 12345678).
0 => 2
1 => 2
2 => 3
3 => 5
4 => 5
5 => 7
6 => 7
7 => 11
8 => 11
9 => 11
10 => 11
11 => 13
12 => 13
13 => 17
14 => 17
15 => 17
16 => 17
17 => 19
18 => 19
19 => 23
20 => 23
21 => 23
22 => 23
23 => 29
…
95 => 97
96 => 97
97 => 101
98 => 101
99 => 101
100 => 101
101 => 103
103 => 107
107 => 109
109 => 113
113 => 127
127 => 131
…
12345581 => 12345623
12345623 => 12345637
12345637 => 12345643
12345643 => 12345647
12345647 => 12345653
12345653 => 12345701

C qsort not sorting last item in multidimensional array

I am using the qsort function in C to sort 3 columns of integers. It sorts my 2D array fine, except for the last item.
Here is my code:
#include <stdio.h>
#include <stdlib.h>
#define ARRAYSIZE 10
int array[ARRAYSIZE][3];
static int x_then_z(const void *a, const void *b) {
const int *arr1 = (const int*)a;
const int *arr2 = (const int*)b;
int diff1 = arr1[0] - arr2[0]; //x
if(diff1) return diff1;
return arr1[2] - arr2[2]; //z
}
static int z_then_x(const void *a, const void *b) {
const int *arr1 = (const int*)a;
const int *arr2 = (const int*)b;
int diff1 = arr1[2] - arr2[2]; //z
if(diff1) return diff1;
return arr1[0] - arr2[0]; //x
}
void print_array() {
for(int i = 0; i < ARRAYSIZE; i++){
printf("%d, %d, %d\n", array[i][0], array[i][1], array[i][2]);
}
}
int main(int argc, char *argv[]){
fill_array();
//print_array();
//printf("\n");
qsort(array, ARRAYSIZE, 3*sizeof(int), x_then_z);
fprintf(stderr, "Sorted by x then z\n");
print_array();
printf("\n");
qsort(array, ARRAYSIZE, 3*sizeof(int), z_then_x);
fprintf(stderr, "Sorted by z then x\n");
print_array();
return EXIT_SUCCESS;
}
I have named my columns x, y and z (so as not to confuse myself in the comparison functions where I have a and b). The fill_array function fills the array with the following computed input:
31, 56, 8
39, 71, 9
65, 76, 10
64, 129, 12
44, 191, 14
105, 199, 15
169, 319, 19
44, 321, 18
319, 364, 22
295, 551, 25
However, the output is this:
Sorted by x then z
31, 56, 8
39, 71, 9
44, 191, 14
44, 321, 18
64, 129, 12
65, 76, 10
105, 199, 15
169, 319, 19
319, 364, 22
**295, 551, 25**
Sorted by z then x
31, 56, 8
39, 71, 9
65, 76, 10
64, 129, 12
44, 191, 14
105, 199, 15
44, 321, 18
169, 319, 19
319, 364, 22
295, 551, 25
You can see that the last value of the array is not sorted. If I change ARRAYSIZE to a larger number, the last value in the array is not sorted. Where am I going wrong?
The fill_array function had an off by 1 error. When filling the array, it was starting at 1, not 0

How to generate a set of numbers [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about programming within the scope defined in the help center.
Closed 7 years ago.
Improve this question
I have to generate the set Z of the first 100 integers that satisfy the equation i = 2^a * 3^b, with a and b being integers.
That is, Z = {1, 2, 3, 4, 6, 8, 9, 12, ...}
What algorithm could I use ? I'll need to implement it in C.
In C
#include <stdio.h>
#include <math.h>
#include <stdint.h>
typedef unsigned long long int ull;
ull cmp(const void * a, const void * b) { return *(ull *)a - *(ull *)b; }
int main() {
int i = 0, a, b;
int A = 17,
B = 16;
int MAX = A * B;
ull z[MAX];
for (b = 0; b < B; ++b) {
for (a = 0; a < A; ++a) {
if (i >= MAX) break;
z[i++] = pow(2, a) * pow(3, b);
}
}
qsort(z, MAX, sizeof(ull), cmp);
printf("{ ");
for (i = 0; i < 100; ++i)
printf("%lld%c ", z[i], i < 99 ? ',' : 0);
printf("}");
return 0;
}
Output
{ 1, 2, 3, 4, 6, 8, 9, 12, 16, 18, 24, 27, 32, 36, 48, 54, 64, 72, 81, 96, 108, 128, 144, 162, 192, 216, 243, 256, 288, 324, 384, 432, 486, 512, 576, 648, 729, 768, 864, 972, 1024, 1152, 1296, 1458, 1536, 1728, 1944, 2048, 2187, 2304, 2592, 2916, 3072, 3456, 3888, 4096, 4374, 4608, 5184, 5832, 6144, 6561, 6912, 7776, 8192, 8748, 9216, 10368, 11664, 12288, 13122, 13824, 15552, 16384, 17496, 18432, 19683, 20736, 23328, 24576, 26244, 27648, 31104, 32768, 34992, 36864, 39366, 41472, 46656, 49152, 52488, 55296, 59049, 62208, 65536, 69984, 73728, 78732, 82944, 93312 }
EDIT: Gives correct output now without overflow (see http://ideone.com/Rpbqms)
too much brute force...
let me propose a O(n*lg n) time O(n) space algorithm to achieve these.
i am not gonna provide any real code, but a piece of self invented pseudocode.
the idea is to use min-heap to maintain ordering:
func first-n-of-that(limit)
heap = min-heap()
heap.insert 1
results = []
while results.length < limit
to-add = heap.pop
results.add to-add
heap.insert 2 * to-add
heap.insert 3 * to-add
return results
the correctness is provable by deduction.
Brute force in Python (I know that C code is required):
sorted(2**a*3**b for a in range(100) for b in range(100))[:100]
And the result is …

Resources