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).
Related
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).
So I have an assignment, and within it is a question that requires you to construct a 2D array with 5 rows and 4 columns, with each of them containing grades. The question requires you to determine how many grades are less than 60, between 60 and 70 and so on (till 100). Thing is when I try to search through it, there should only be 20 total grades, but my solution gives some far fetched number like 60,000 or whatever. I'm at a loss as to what is wrong with my code. I used two for loops to search through the array. Attached is what I've tried. Thanks a ton for any help
#include <stdio.h>
int main(){
double grades[5][4] = {
{69, 58, 95, 78},
{84, 75, 86, 32},
{75, 68, 65, 73},
{99, 54, 24, 88},
{65, 78, 84, 65}
};
int lessthan60, sixtyseventy, seventyeighty, eightyninety, greaterthan90;
for (int r = 0; r < 5; r++){
for (int c=0; c < 4; c++){
if (grades[r][c] < 60){
lessthan60++;
}
else if (grades[r][c] >=60 && grades[r][c] < 70){
sixtyseventy++;
}
else if (grades[r][c] >=70 && grades[r][c] < 80){
seventyeighty++;
}
else if (grades[r][c] >=80 && grades[r][c] < 90){
eightyninety++;
}
else{
greaterthan90++;
}
}
}
printf("Grades less than 60: %d\n", lessthan60);
printf("Grades between 60 and 70: %d\n", sixtyseventy);
printf("Grades between 70 and 80: %d\n", seventyeighty);
printf("Grades between 80 and 90: %d\n", eightyninety);
printf("Grades between 90 and 100: %d\n", greaterthan90);
return 0;
}
These variables having automatic storage duration
int lessthan60, sixtyseventy, seventyeighty, eightyninety, greaterthan90;
are uninitialized and have indeterminate values. You have to initialize them by zero explicitly
int lessthan60 = 0, sixtyseventy = 0, seventyeighty = 0, eightyninety = 0, greaterthan90 = 0;
Also if statements can be written simpler like
if (grades[r][c] < 60){
lessthan60++;
}
else if ( grades[r][c] < 70){
sixtyseventy++;
}
else if ( grades[r][c] < 80){
seventyeighty++;
}
else if ( grades[r][c] < 90){
eightyninety++;
}
else{
greaterthan90++;
}
Also instead of the magic numbers 4 and 5 it is better to use named constants as for example
enum { ROWS = 5, COLS = 4 };
double grades[ROWS][COLS] = {
{69, 58, 95, 78},
{84, 75, 86, 32},
{75, 68, 65, 73},
{99, 54, 24, 88},
{65, 78, 84, 65}
};
//...
for (int r = 0; r < ROWS; r++){
for (int c=0; c < COLS; c++){
//...
This way, you are starting with garbage values.
You need to initialize counters lessthan60, sixtyseventy, seventyeighty, eightyninety, greaterthan90 to zero.
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
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
I'm implementing a FIR Low Pass Filter in C. Got some coefficients generated in MATLAB, which I use to calculate the output.
The audio comes from the Zynq Zedboard and is in real time.
If I run the application, I get lots of noise. But I don't know how the signal gets distorted..
Do I need an audio buffer to keep the processed samples? Or do I just have crappy code? I analyzed practically all elements in my code, but can't get my head around it...
Here is the function call
#define FILTER_LEN_LP 44
int32_t coeffsLPF[ FILTER_LEN_LP ] =
{
87, 76, 106, 143, 185, 234, 289, 349,
414, 483, 555, 628, 701, 773, 842, 907,
966, 1017, 1060, 1093, 1115, 1126, 1126,
1115, 1093, 1060, 1017, 966, 907, 842, 773,
701, 628, 555, 483, 414, 349, 289, 234, 185,
143, 106, 76, 87
};
void low_pass_filter(){
int k = 0;
int filter_length = FILTER_LEN_LP;
int32_t *coeffp; // pointer to coefficients
int32_t in_left;
while (!XUartPs_IsReceiveData(UART_BASEADDR)) {
int32_t out_left;
int32_t acc; // accumulator
in_left = Xil_In32(I2S_DATA_RX_L_REG);
//printf("%d\r\n", in_left);
coeffp = coeffsLPF;
acc = 1 << 14 ;
for ( k = 0; k < filter_length; k++ )
{
acc += (int32_t)(*coeffp++) * (int32_t)(in_left);
}
//printf("%d\r\n", acc);
//printf("\r\n");
// saturate the result
// 32768^2
if ( acc > 1073741823)
{
acc = 1073741823;
} else if ( acc < -1073741824 ){
acc = -1073741824;
}
out_left = (int32_t) (acc >> 13);
//xil_printf("%d\n\r", out_left);
//in_right = Xil_In32(I2S_DATA_RX_R_REG);
Xil_Out32(I2S_DATA_TX_L_REG, out_left);
//Xil_Out32(I2S_DATA_TX_R_REG, in_right);
}
// break
if(XUartPs_ReadReg(UART_BASEADDR, XUARTPS_FIFO_OFFSET) == 'q') menu();
else low_pass_filter();
}
The formula for a FIR filter is:
y[n] = b0*x[n] + b1*x[n-1] + b2*x[n-2]...
To calculate one output, you need the last 44 input samples and multiply and accumulate it with the filter coefficients.
My recommendation would be to use a ring buffer of size 44 to store the input samples.
Allocate a ring buffer and initialize it with zero.
ring_buffer[FILTER_LEN_LP] = {0};
rb_index = 0;
and then use the following example code to store your input samples and calculate the output.
ring_buffer[rb_idx] = Xil_In32(I2S_DATA_RX_L_REG);
rb_idx = (rb_idx + 1) % filter_length;
for (k=0; k<filter_length; k++) {
acc += (int32_t)(*coeffp++) * (int32_t)(ring_buffer[(k+rb_idx)%filter_length]);
}