printing alphabets using star pattern side by side in C - c

I am trying to print the initials of My First Name "S S" using * pattern in C. However the patterns are printed one after the other. Is there any way to print the alphabets using * pattern one at the side of the other with a little space in between. I do not want to allot a very big box for both the alphabets. I want to code for individual alphabets and put them side by side with some space in between. My Code and out our is given below:
int k,l,i,j;
for(k=1;k<=7;k++){
for(l=1;l<=4;l++){
if(k==1 && l<=4){
printf("*");
}
else if(k>=2 && k<=3 && l==1){
printf("*");
}
else if(k==4 && l<=4){
printf("*");
}
else if(k>=5 && k<=6 && l==4){
printf("*");
}
else if(k==7 && l<=4){
printf("*");
}
else{
printf(" ");
}
}
printf("\n");
}
for(i=1;i<=7;i++){
for(j=1;j<=4;j++){
if(i==1 && j<=4){
printf("*");
}
else if(i>=2 && i<=3 && j==1){
printf("*");
}
else if(i==4 && j<=4){
printf("*");
}
else if(i>=5 && i<=6 && j==4){
printf("*");
}
else if(i==7 && j<=4){
printf("*");
}
else{
printf(" ");
}
}
printf("\n");
}
return 0;
}
Output:
****
*
*
****
*
*
****
****
*
*
****
*
*
****
However, I want my expected output to be:
**** ****
* *
* *
**** ****
* *
* *
**** ****

The most important thing when approaching problems like this is to decompose your code in smaller pieces, using functions and/or typedefs or structs to organize things. In your case, you can easily separate the "knowledge" of how to print stars and spaces for your letters from the main code (which knows which letters to print in which order) using functions. Refactoring you code that way, we get:
void S(int k, int l) {
if(k==1 && l<=4){
printf("*");
}
else if(k>=2 && k<=3 && l==1){
printf("*");
}
else if(k==4 && l<=4){
printf("*");
}
else if(k>=5 && k<=6 && l==4){
printf("*");
}
else if(k==7 && l<=4){
printf("*");
}
else{
printf(" ");
}
}
int main() {
int k,l,i,j;
for(k=1;k<=7;k++){
for(l=1;l<=4;l++){
S(k, l);
}
printf("\n");
}
for(i=1;i<=7;i++){
for(j=1;j<=4;j++){
S(i, j);
}
printf("\n");
}
return 0;
}
Now you can easily rewrite main to print the letters side by side
int main() {
int k,l,i,j;
for(k=1;k<=7;k++){
for(l=1;l<=4;l++){
S(k, l);
}
printf(" ");
for(j=1;j<=4;j++){
S(k, j);
}
printf("\n");
}
return 0;
}
You could also extend this by writing different letters in different patterns (though having a function for each letter is somewhat verbose -- better would be to store the pixels for all letters in a data structure and print it that way)

Use pattern matrix for every character you want to print. It'll make printing easier. You run through each letter of the string to print for every row in the pattern.
#include <stdio.h>
#include <string.h>
#define ROWMAX 7
#define COLMAX 5
#define CSPACE 1
#define PATTERN '#'
char cCube [26][ROWMAX][COLMAX] = {
{ {0, 1, 1, 1, 1}, // letter S
{1, 1, 0, 0, 1},
{1, 1, 0, 0, 0},
{0, 1, 1, 1, 0},
{0, 0, 0, 1, 1},
{1, 0, 0, 1, 1},
{1, 1, 1, 1, 0}
},
{ {0, 1, 1, 1, 0}, // letter O
{1, 1, 0, 1, 1},
{1, 0, 0, 0, 1},
{1, 0, 0, 0, 1},
{1, 0, 0, 0, 1},
{1, 1, 0, 1, 1},
{0, 1, 1, 1, 0}
},
{ {1, 1, 1, 1, 0}, // letter D
{1, 0, 0, 1, 1},
{1, 0, 0, 0, 1},
{1, 0, 0, 0, 1},
{1, 0, 0, 0, 1},
{1, 0, 0, 1, 1},
{1, 1, 1, 1, 0}
}, //so on for alphabets you want to use
};
int chIndex [256] = {0};
void print_pat_msg (const char* msg) {
int mlen = strlen (msg);
for (int ri = 0; ri < ROWMAX; ++ri) {
for (int mi = 0; mi < mlen; ++mi) {
int chi = chIndex[ (unsigned char) msg[mi]];
for (int ci = 0; ci < COLMAX; ++ci)
(cCube[chi][ri][ci]) ? putchar (PATTERN) : putchar (' ');
for (int spi = 0; spi++ < CSPACE;) putchar (' ');
}
putchar ('\n');
}
printf ("\n");
}
int main () {
// if patterns are indexed alphabetically below initialisation can be omitted
chIndex[ (unsigned char) 'S'] = 0;
chIndex[ (unsigned char) 'O'] = 1;
chIndex[ (unsigned char) 'D'] = 2;
char message [] = "ODDS";
print_pat_msg (message);
return 0;
}
This way you can design/customise the pattern for each letter with ease at one place. Code & pattern can be reused for other messages & names.
Printing here works somewhat like a dot-matrix printer, striping across putting out pattern-line of each letter in the string one at a time.
You can also replace 0/1 flags with pretty much any character to draw ASCII images. You just have to adjust the pattern array, which is easy to follow & change at will.
Come to think of it, this is how fonts work at pixel level, patterns.

My quickie solution:
#include <stdio.h>
static const unsigned char S[] = {0xF0, 0x80, 0x80, 0xF0, 0x10, 0x10, 0xF0};
int main(void) {
for(int i=0; i<sizeof(S); ++i)
{
for(int b=7;b; --b)
{
printf("%c", "* "[!(S[i] & (1<<b))]);
}
for(int b=7;b; --b)
{
printf("%c", "* "[!(S[i] & (1<<b))]);
}
printf("\n");
}
return 0;
}
Output:
Success #stdin #stdout 0s 5548KB
**** ****
* *
* *
**** ****
* *
* *
**** ****

Related

change indexing of array in c

I am stuck in the problem of an array. I want to print something like this in C language.
input= arr[14]={2,0,2,2,0,1,1,4,0,4,2,2,3,3};
output I need is: output=arr2[6]={2022,01,14,04,22,33};
is this possible in the c language. your help will be very appreciated. thanks
arr2[0] = arr[0]*1000 + arr[1]*100 + arr[2]*10 + arr[3]; arr2[1] = arr[4]*10 + arr[5]; ...
or, if you really really want to make a function
#include <stdio.h>
void mix2(int *a, int *b, int alen) {
for (int i = 0; i < alen; i++) {
a[i] = b[2*i]*10 + b[2*i+1];
}
}
int main(void) {
int arr[14] = {2, 0, 2, 2, 0, 1, 1, 4, 0, 4, 2, 2, 3, 3};
int arr2[6];
mix2(arr2, arr + 2, 6); // 22, 01, 14, 04, 22, 33 into arr2
arr2[0] += arr[0]*1000 + arr[1]*100; // add missing terms
printf("arr2:");
for (int i = 0; i < 6; i++) printf(" %d", arr2[i]);
printf("\n");
return 0;
}

Bellman Ford graph algorithm

I have a homework to implement Bellman Ford's algorithm and test it on some graphs. I implemented the algorithm, tested it on 2 of 3 graphs and it works. But on the third graph I have no output when calling the function.
Graph* temaTrecuta = createGraph(10, 12);
addOrientedEdge(temaTrecuta, 0, 0, 1, 5);
addOrientedEdge(temaTrecuta, 1, 1, 2, 3);
addOrientedEdge(temaTrecuta, 2, 2, 3, 5);
addOrientedEdge(temaTrecuta, 4, 3, 9, 5);
addOrientedEdge(temaTrecuta, 5, 1, 9, 1);
addOrientedEdge(temaTrecuta, 6, 3, 4, 1);
addOrientedEdge(temaTrecuta, 7, 4, 8, 5);
addOrientedEdge(temaTrecuta, 8, 8, 7, 1);
addOrientedEdge(temaTrecuta, 9, 7, 5, 1);
addOrientedEdge(temaTrecuta, 10, 7, 6, 3);
addOrientedEdge(temaTrecuta, 11, 6, 0, 1);
This part creates the graph and its edges. The createGraph function takes as parameters number of vertices and edges.
void addOrientedEdge(Graph* graph, int index, int source, int destination, int cost) {
graph->edge[index].src = source;
graph->edge[index].dest = destination;
graph->edge[index].cost = cost;
graph->matrix[source][destination] = cost;
}
This is the function that adds a new edge.
Below is my implementation for Bellman Ford's algorithm.
void bellmanFord(Graph* gr, int src) {
int* dist = (int*)malloc(sizeof(int) * gr->V);
int* path = (int*)malloc(sizeof(int) * gr->V);
if (!path || !dist) {
printf("Nu am putut aloca.\n");
exit(1);
}
for (int i = 0; i < gr->V; ++i) {
dist[i] = INT_MAX;
path[i] = 0;
}
path[src] = -1;
dist[src] = 0;
for (int i = 1; i <= gr->V - 1; ++i) {
for (int j = 0; j < gr->E; ++j) {
int m = gr->edge[j].src;
int n = gr->edge[j].dest;
int cost = gr->edge[j].cost;
if (dist[m] != INT_MAX && dist[m] + cost < dist[n]) {
dist[n] = dist[m] + cost;
path[n] = m;
}
}
}
for (int i = 0; i < gr->E; ++i) {
int m = gr->edge[i].src;
int n = gr->edge[i].dest;
int cost = gr->edge[i].cost;
if (dist[m] != INT_MAX && dist[m] + cost < dist[n]) {
printf("Exista un ciclu negativ.");
return;
}
}
printBellmanSol(dist, gr->V, path);
free(dist);
free(path);
}
Since nothing references edge index, as long as it is unique and sequental, you should consider auto-incrementing. In addition to edge index E, have a new edge capacity. That is the number that is passed to createGraph, and set the counter, E = 0, initially. You could write your addOrientedEdge with one less parameter; take the next edge index.
static void addOrientedEdge(struct Graph* graph, int source, int destination, int cost) {
const int index = graph->E;
assert(graph && graph->E < graph->E_capacity);
graph->edge[index].src = source;
graph->edge[index].dest = destination;
graph->edge[index].cost = cost;
graph->E++;
graph->matrix[source][destination] = cost;
}
This would free you from having to worry about the edge numbers.
There was an edge missing that was causing the problem. Thanks to #user3386109 for seeing it.

How to fix ' Error: invalid read of size 4'

I'm trying to learn C and am completing different challenges in order to learn faster. The code seems logical to me and should progress. However, I'm getting an invalid read of size four on line 29
I've tried to change the data type that gets parsed through, but it didn't seem to work.
#include <unistd.h>
typedef struct s_grid
{
int x;
int y;
} t_grid;
void set_point(t_grid *coord, int i, int j)
{
coord->x = i;
coord->y = j;
}
//check loccation of next zero
int where_is_zero(int **sudoku)
{
int x;
int y;
t_grid coord;
x = 0;
y = 0;
while (x < 9)
{
y = 0;
while (y < 9)
{
if (sudoku[x][y] == 0) //Here I'm getting the error.
{
set_point(&coord, x, y);
return (0);
}
x++;
}
y++;
}
return (1);
}
int solve_sudoku(int **grid)
{
int row;
int col;
int num;
t_grid coord;
if (where_is_zero(grid) == 1)
return (1);
row = coord.x;
col = coord.y;
//where_is_zero(grid);
num = 1;
while (num <= 9)
{
if (check_number(grid, row, col, num) == 1)
{
grid[row][col] = num;
if (solve_sudoku(grid) == 1)
return (1);
grid[row][col] = 0;
}
num++;
}
return (0);
}
void ft_putchar(char c)
{
write(1, &c, 1);
}
void ft_putstr(char *str)
{
while (*str != '\0')
{
ft_putchar(*str);
str++;
}
}
//my main function
int main(int argc, char **argv)
{
int board[9][9] ={ { 0, 9, 0, 0, 0, 0, 8, 5, 3 },
{ 0, 0, 0, 8, 0, 0, 0, 0, 4 },
{ 0, 0, 8, 2, 0, 3, 0, 6, 9 },
{ 5, 7, 4, 0, 0, 2, 0, 0, 0 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0, 0, 0, 9, 0, 0, 6, 3, 7 },
{ 9, 4, 0, 1, 0, 8, 5, 0, 0 },
{ 7, 0, 0, 0, 0, 6, 0, 0, 0 },
{ 6, 8, 2, 0, 0, 0, 0, 9, 0 } };
solve_sudoku(board);
return (0);
}
I removed some code just to highlight where the problem is. It should find the next 0 in the table and set the coordinations to my structure.
The problem lies in how you have the loop set up. See my comments below:
while (x < 9)
{
y = 0;
while (y < 9)
{
if (sudoku[x][y] == 0) //Here I'm getting the error.
{
set_point(&coord, x, y);
return (0);
}
x++; // This increments the x index while you're inside the y loop
}
y++; // This increments the y index when you meant to increment the x
}
If you swap both lines, that should work fine and will resolve your out-of-bounds error.
What would also help you write this better is instead of using a while loop, use a for loop. If you haven't covered that topic yet, it's really straightforward:
for(int x = 0; x < 9 ; ++x)
{
for (int y = 0; y < 9; ++y)
{
if (sudoku[x][y] == 0) //Here you won't get the error anymore!
{
set_point(&coord, x, y);
return (0);
}
}
}
What the for loop line means there is this: Start the loop by setting it to 0, at the end of an iteration, increment it. On the next iteration, check if x is still less than 9. If so, proceed with the next iteration.
Your problem is due to mixing types. In main() you declare:
int board[9][9] = { ....
You then pass:
solve_sudoku(board);
board has the type int (*)[9] (a pointer to array of int [9]). See C11 Standard - 6.3.2.1 Other Operands - Lvalues, arrays, and function designators(p3). Your solve_soduku expects a parameter of type int** (pointer to pointer to int).
int solve_sudoku(int **grid) { ...
The type are NOT compatible. (and your compiler should be screaming warnings at you)
board is a pointer to array of int [9], while grid is a pointer to pointer to int. You must make the types compatible. The easiest way is to change solve_sudoku to
int solve_sudoku(int (*grid)[9]) { ...
Otherwise you will need to declare board as int** and allocate and fill in main().

Changing of elements of array when passed as an index of another array

I am a rookie, and I hope this question is not a naive one!
I have the following function, where I use elements of one array as indices of another. However, despite my making no changes to the former, I see that the elements are being modified. The code is as follows:
void convert_to_bitmap(int n_shapes, int sizex, int sizey,
int ll_x[n_shapes], int ll_y[n_shapes],
int ur_x[n_shapes], int ur_y[n_shapes],
int shapes_ll_bitmap[sizex][sizey],
int shapes_ur_bitmap[sizex][sizey] )
{
int i;
for (i = 0; i < n_shapes; i++)
{
printf("%d, %d, %d, %d check1\n", ll_x[i], ll_y[i], ur_x[i], ur_y[i]);
}
for (i = 0; i < n_shapes; i++)
{
shapes_ll_bitmap[ll_x[i]][ll_y[i]] = 1;
shapes_ur_bitmap[ur_x[i]][ur_y[i]] = 1;
printf("%d, %d, %d, %d check2\n", ll_x[i], ll_y[i], ur_x[i], ur_y[i]);
}
}
And, the output shows that the first array has changed when I do so. Is there some way to keep it immutable?
Output:
0, 0, 0, 7 check1
0, 9, 0, 15 check1
1, 0, 1, 7 check1
1, 9, 1, 15 check1
2, 13, 2, 15 check1
2, 17, 2, 24 check1
2, 26, 2, 32 check1
0, 0, 0, 7 check2
0, 9, 0, 15 check2
1, 0, 1, 7 check2
1, 9, 1, 15 check2
1, 13, 2, 15 check2
2, 1, 2, 1 check2
1, 26, 2, 32 check2
This is how I invoke the function in main():
convert_to_bitmap(n_shapes, sizex, sizey, ll_x, ll_y, ur_x, ur_y, shapes_ll_bitmap, shapes_ur_bitmap);
And the declaration and initialization of the matrices in int main() is as follows:
int ll_x[n_shapes];
int ll_y[n_shapes];
int ur_x[n_shapes];
int ur_y[n_shapes];
int sizex;
int sizey;
int shapes_ll_bitmap[sizex][sizey];
int shapes_ur_bitmap[sizex][sizey];
for (i=0; i < sizex; i++)
{
for (j = 0; j < sizey; j++)
{
shapes_ll_bitmap[i][j] = 0;
shapes_ur_bitmap[i][j] = 0;
}
printf("\n");
}
Thank you!
Edit:
Here's some self-contained code:
int main(void)
{
enum { MAX_SHAPES = 100000 };
struct Rectangle rect_array[MAX_SHAPES];
int n_shapes = read_shapes_rpt("shapes.rpt", MAX_SHAPES, rect_array);
int i, j;
float pitch_x = 0.044;
float pitch_y = 0.042;
float ll_x_flt[n_shapes];
float ll_y_flt[n_shapes];
float ur_x_flt[n_shapes];
float ur_y_flt[n_shapes];
int ll_x[n_shapes];
int ll_y[n_shapes];
int ur_x[n_shapes];
int ur_y[n_shapes];
int sizex;
int sizey;
int shapes_ll_bitmap[sizex][sizey];
int shapes_ur_bitmap[sizex][sizey];
for (i=0; i < sizex; i++)
{
for (j = 0; j < sizey; j++)
{
shapes_ll_bitmap[i][j] = 0;
shapes_ur_bitmap[i][j] = 0;
}
printf("\n");
}
if (n_shapes > 0)
{
transform_to_shape_bit_locations(n_shapes, rect_array, ll_x_flt, ll_y_flt, ur_x_flt, ur_y_flt, ll_x, ll_y, ur_x, ur_y, &pitch_x, &pitch_y, &sizex, &sizey);
convert_to_bitmap(n_shapes, sizex, sizey, ll_x, ll_y, ur_x, ur_y, shapes_ll_bitmap, shapes_ur_bitmap);
printf("%d\n%d\n%d\n", n_shapes, sizex, sizey);
/* Use the shapes that were read */
}
return 0;
}
My shapes.rpt file contained the following csv values:
1.408,529.237,1.43,529.523
1.408,529.597,1.43,529.883
1.452,529.237,1.474,529.523
1.452,529.597,1.474,529.883
1.496,529.777,1.518,529.883
1.496,529.957,1.518,530.243
1.496,530.317,1.518,530.564
Your variables sizex and sizey are left uninitialized. Which means that your matrices shapes_ll_bitmap and shapes_ur_bitmap have unpredictable size (the behavior is actually undefined).
Note that when you actually assign meaningful values to your your sizex and sizey later, it is already too late. The matrices are already declared with indeterminate sizes and that's final. Once the matrices are declared, any changes to the values of sizex and sizey will have no effect on the matrices.
Your matrices end up with some indeterminate size, which results in out-of-bounds access inside convert_to_bitmap function and destruction of unrelated memory values.

Linux C LibPCRE output unique results

I have the following code that matches a REGEX in a string that contains multiple duplicates, what I want to do is to print out only unique matches, what can I do? Add to an array than make it unique and only then print out the results? Thanks!
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <pcre.h>
int main() {
pcre *myregexp;
const char *error;
int erroroffset;
int offsetcount;
int offsets[(0+1)*3]; // (max_capturing_groups+1)*3
const char *result;
char *subject = "9,5,3,2,5,6,3,2,5,6,3,2,2,2,5,0,5,5,6,6,1,";
myregexp = pcre_compile("\\d,", PCRE_MULTILINE|PCRE_DOTALL|PCRE_NEWLINE_ANYCRLF, &error, &erroroffset, NULL);
if (myregexp != NULL) {
offsetcount = pcre_exec(myregexp, NULL, subject, strlen(subject), 0, 0, offsets, (0+1)*3);
while (offsetcount > 0) {
if (pcre_get_substring(subject, offsets, offsetcount, 0, &result) >= 0) {
printf("%s\n", result);
}
offsetcount = pcre_exec(myregexp, NULL, subject, strlen(subject), offsets[1], 0, offsets, (0+1)*3);
}
} else {
printf("Syntax error in REGEX at erroroffset\n");
}
}
This outputs:
bash$ ./regex
9,
5,
3,
2,
5,
6,
3,
2,
5,
6,
3,
2,
2,
2,
5,
0,
5,
5,
6,
6,
1,
and I need:
bash$ ./regex
0,
1,
2,
3,
5,
6,
9,
Yes, add to an array and deduplicate from there.
You can not search unique values with regex. You can search replace with regex and deduplicate some things like double new lines, multiple spaces and so on, but this doesn't work when the deduplication needs to occur using random seeking.
Here is an example of how to deduplicate: a -> b
#include <stdio.h>
#include <string.h>
main()
{
char *a[5];
int a_len = 5;
a[0] = "a";
a[1] = "b";
a[2] = "b";
a[3] = "a";
a[4] = "c";
char *b[a_len];
int b_len = 0;
int already_exists;
int i, j;
for (i = 0; i < a_len; i++)
{
already_exists = 0;
for ( j = 0; j < b_len; j++)
{
if (!strcmp(a[i], b[j]))
{
already_exists = 1;
break;
}
}
if (!already_exists)
{
b[b_len] = a[i];
b_len++;
}
}
for (i = 0; i < b_len; i++)
{
printf("%s", b[i]);
}
}
For these small arrays this is probably the fastest algorithm. For better performance on bigger arrays I would suggest deduplication on a sorted array.

Resources