Nested loops creating pattern (not diamond) in C - c

So for my assignment I have to take the inputs of length and width and print out patterns of "*" based on the inputs. The minimum height is 7 and only goes up by odd integers and width is any multiple of 6.
The basic format of the output using a height of 7 and width of 12:
************
************
*** ***
*** ***
*** ***
************
************
So basically the first and last 2 lines are straight through the entire width, with the odd numbered rows containing 3 asterisks followed by 3 spaces, until it reaches the end of the width. The even numbered rows start off with 3 spaces.
I've figured out how to print the first two lines using the following code:
do
{
printf("*");
++i;
}while(i<width);
printf("\n");
do
{
printf("*");
++j;
}while(j<=width);
printf("\n");
But for the life of me, I cannot come up with the correct way to use basic nested loops to print out the inside pattern. I asked a programmer friend who is unfamiliar with C but wrote up a basic program in Java. I don't know Java and have tried to translate it but notice some big discrepancies in the logic between the two languages that is causing me headaches. Here is his code:
// LOGGING
var consoleLine = "<p class=\"console-line\"></p>";
console = {
log: function (text) {
$("#console-log").append($(consoleLine).html(text));
}
};
// PATTERN PARAMETERS
var rows = 6;
var cols = 7;
// hard code a space so html respects it
var space = " "
console.log("cols: " + cols + " rows: " + rows);
for (y = 0; y < rows; ++y) {
var line = "";
for (x = 0; x < cols; ++x) {
// First two and last two rows do not have patterns and just print filled
if (y == 0 || y == 1 || y == rows - 1 || y == rows - 2) {
line += "*";
} else {
if (y % 2 == 0) {
// Even row
line += x % 6 < 3 ? "*" : space;
} else {
// Odd row
line += x % 6 >= 3 ? "*" : space;
}
}
}
console.log(line);
}
Please help me or point me in the right direction!! I've searched online but can't seem to find a solution that's worked yet!
Edit- forgot to mention that all "printf" uses can only print one character at a time... Such as a single *
Edit edit- I GOT IT WORKING!!!! Thank you all so, so much for your input and guidance! Here's what I have that is working perfectly:
for (y = 0; y < height; ++y)
{
printf("\n");
for (x = 0; x < width; ++x)
{
// First two and last two rows do not have patterns and just print filled lines
if (y == 0 || y == 1 || y == height - 1 || y == height - 2)
{
printf("*");
}
else
{
if (y % 2 == 0)
{
if(x%6<3)
{
printf("*");
}
else
{
printf(" ");
}
} else {
// Odd row
if(x%6>=3)
{
printf("*");
}
else
{
printf(" ");
}
}
}
}
printf("\n");

Write a function with 3 arguments n,a,b that prints n groups of 3 of each argument a and b alternately. You can call this function to print the 4 different kinds of lines. You can make a loop to print the middle section repeatedly. Have fun!

A simpler alternative:
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char **argv) {
int row, col, height = atoi(argv[1]), cols = atoi(argv[2]);
for (row = 0; row < height; row++) {
for (col = 0; col < cols; col++) {
putchar(row < 2 || row >= height - 2 ||
col % 6 / 3 == row % 2 ? '*' : ' ');
}
putchar('\n');
}
}

Related

How to print V in c programming in 10X10 row and column in a optimized way?

I printed V using * in specific rows and columns. I had lots of if statements. I am sharing my code below.
Is there any optimised way to print the V pattern in 10X10 row column? (without many if conditions)?
#include <stdio.h>
int main() {
int row, column;
for (row = 1; row <= 10; row++) {
for (column = 1; column <= 10; column++) {
if (row == 1 && (column == 1 || column == 10)
|| row == 3 && (column == 2 || column == 9)
|| row == 5 && (column == 3 || column == 8)
|| row == 7 && (column == 4 || column == 7)
|| row == 10 && column == 5)
printf("*");
else
printf(" ");
}
printf("\n");
}
return 0;
}
A reasonable option when you need to output arbitrary amounts of spaces is to use printf string width specifier to left-pad with spaces:
printf("%*s*", spaces, "");
The above will output the empty string, padded up to a width of the integer value spaces, and then output a *. Note that the format string %*s means that you specify both a width and then a string as extra arguments. The * in that part has nothing to do with an actual *. We add that onto the end of the format string.
So, for the V shape, each line has two * characters on it, except the last line (if the width is odd). One way to do this intuitively is to track the position of the left and the right part of the V for each line, and then do the math for determining how much padding to add.
Example:
void v(int width)
{
int l = 0, r = width;
for (; l < r; l++, r--)
{
printf("%*s*%*s\n", l, "", r-l, "*");
}
if (l == r)
printf("%*s*\n", l, "");
}
If you really want more condensed code, you can elect to roll that last line into the loop. In this case, when l == r you want to only output a single asterisk. Otherwise you want two. So you could output the string &"*"[l==r] -- that will mean that when l==r is true, you'll skip over the asterisk and it will look like an empty string (because you land on the NUL terminator).
Note this is not great style. It sacrifices readability for compactness.
void v(int width)
{
for (int l = 0, r = width; l <= r; l++, r--)
{
printf("%*s*%*s\n", l, "", r-l, &"*"[l==r]);
}
}
So, this is "efficient" in terms of compact code and not many function calls. If you instead are concerned about the format parsing of printf then you can avoid it entirely. Below, we use the same left/right bounds and just walk through each row using loops. This essentially does what our printf is doing internally, except it's more obvious what's going on:
void v(int width)
{
int l = 0, r = width-1;
for (; l <= r; l++, r--)
{
int x = 0;
for (; x < l; x++) putchar(' ');
putchar('*');
if (x < r)
{
for (x++; x < r; x++) putchar(' ');
putchar('*');
}
putchar('\n');
}
}
Now for some fun...
As an exercise, here is the printf approach but with no loops (using recursion):
void vv(int width, int row) {
if(width >= 0) {
printf("%*s*%*s\n", row, "", width, &"*"[width==0]);
vv(width-2, row+1);
}
}
void v(int width) {
vv(width, 0);
}
And here is that idea turned into an intentionally horrendous mess that looks cool. ;)
#include <stdio.h>
#define VV int
#define vV "*\0%*s%*s\n"
VV Vv( VV v ,VV
vv){if(v -->0){
printf (vV+2,
vv++ ,vV,v
,vV+ !v);
Vv(-- v,vv
);}} VV V
(VV v){
Vv(v,
1);
}
int main() {
for (int v = 1; v < 12; v++) {
printf("size %d\n", v);
V(v);
}
}
I don't think this is optimized but will be simpler and scalable with SIZE.
#include <stdio.h>
#define SIZE 10
#define MID ((SIZE-1)/2) // midst position of SIZE
#define ABS(x) ((x)<0?-(x):(x)) // absolute value of x
int main()
{
int i, j;
for (i = 0; i < SIZE; i++) {
for (j = 0; j < SIZE; j++) {
if (i % 2 == 0 && ABS(j - MID) == MID - i / 2) putchar('*');
else putchar(' ');
}
putchar('\n');
}
return 0;
}
[Explanation]
Assuming SIZE equals to 10, the value MID is calculated to be 4.
Then the v shaped asterisks will be placed symmetrically wrt the 4th column.
Let's put numbers in columns (j) and rows (i) as follows:
012345678
* * 0 ABS(0 - 4) == 4 - 0, ABS(8 - 4) == 4 - 0
1 skipped as i & 2 != 0
* * 2 ABS(1 - 4) == 4 - 1, ABS(7 - 4) == 4 - 1
3 skipped
* * 4 ABS(2 - 4) == 4 - 2, ABS(6 - 4) == 4 - 2
5 skipped
* * 6 ABS(3 - 4) == 4 - 3, ABS(5 - 4) == 4 - 3
7 skipped
* 8 ABS(4 - 4) == 4 - 4
The equations above are the conditions to put the asterisks.
For instance, in the 0th row, we want to put it on 0th column and 8th.
The condition j - 4 == +/- 4 or ABS(j - 4) == 4 will represent the conditions due to the symmetricity.
If we generarize the condition across rows, we can describe it as
i % 2 == 0 && ABS(j - MID) == MID - i / 2.
This code considers the relation between the row and the position of the *, if you are in the first row, then we want the column 0 and colum 9 to print *, then second row, we want column 1 and column 8 and so on. Thus, I used an iterator for the rows and iterator for columns to know in a concrete row which column I'm printing.
#include <stdio.h>
int main()
{
int matrix_size = 10; //Assuming is squared matrix 10x10
int counter = 0;
int i,j;
for(i=0;i<(int)(matrix_size/2);i++) {
for(j=0;j<matrix_size;j++) {
if(j==i || j==(matrix_size-1-i)) {
printf("*");
}else{
printf(" ");
}
}
printf("\n");
}
return 0;
}
EDIT: compared to tshiono solution, I write the V in just 5 rows and he prints it in 10 rows but assuming an space line between each line. Boths solutions are ok depending on what u want.
For the V shape to be symmetric, the number of rows and columns should be odd. Here is a simpler method:
#include <stdio.h>
#include <stdlib.h>
int main() {
for (int n = 11, row = 0; row < n; row++) {
for (int column = 0; column < n; column++)
putchar(" *"[2 * abs(column - n / 2) == n - 1 - row]);
printf("\n");
}
return 0;
}
Output:
* *
* *
* *
* *
* *
*
For a thicker V shape:
#include <stdio.h>
#include <stdlib.h>
int main() {
for (int n = 11, row = 0; row < n; row++) {
for (int column = 0; column < n; column++)
putchar(" *"[abs(2 * abs(column - n / 2) - (n - 1 - row)) <= 1]);
printf("\n");
}
return 0;
}
Output:
* *
** **
* *
** **
* *
** **
* *
** **
* *
***
*
Other answers take into account the specific shape of V and optimize around that.
I suggest an optimized solution for any shape.
This involves a lookup table containing all the locations of * characters composing the shape.
struct { int row,col; } shape[] = {
{1,1}, {1,10}, {3,2}, {3,9}, {5,3}, {5,8}, {7,4}, {7,7}, {10,5},
{-1,-1}
};
The last location ({-1,-1}) has the same purpose as terminating '\0' for strings.

How to find all possible 5 dots alignments in Join Five game

I'm trying to implement the Join Five game. It is a game where, given a grid and a starting configuration of dots, you have to add dots in free crossings, so that each dot that you add forms a 5-dot line with those already in the grid. Two lines may only have 1 dot in common (they may cross or touch end to end)
My game grid is an int array that contains 0 or 1. 1 if there is a dot, 0 if there isn't.
I'm doing kinda well in the implementation, but I'd like to display all the possibles moves.
I made a very long and ugly function that is available here : https://pastebin.com/tw9RdNgi (it was way too long for my post i'm sorry)
here is a code snippet :
if(jeu->plat[i][j] == 0) // if we're on a empty spot
{
for(k = 0; k < lineSize; k++) // for each direction
{
//NORTH
if(jeu->plat[i-1-k][j] == 1) // if there is a dot north
{
n++; // we count it
}
else
{
break; //we change direction
}
} //
This code repeats itself 7 other times changing directions and if n or any other variable reaches 4 we count the x and y as a possible move.
And it's not even treating all the cases, if the available spot is between 2 and 2 dots it will not count it. same for 3 and 1 and 1 and 3.
But I don't think the way I started doing it is the best one. I'm pretty sure there is an easier and more optimized way but i can't figure it out.
So my question is: could somebody help me figure out how to find all the possible 5-dot alignments, or tell me if there is a better way of doing it?
Ok, the problem is more difficult than it appears, and a lot of code is required. Everything would have been simpler if you posted all of the necessary code to run it, that is a Minimal, Complete, and Verifiable Example. Anyway, I resorted to putting together a structure for the problem which allows to test it.
The piece which answers your question is the following one:
typedef struct board {
int side_;
char **dots_;
} board;
void board_set_possible_moves(board *b)
{
/* Directions
012
7 3
654 */
static int dr[8] = { -1,-1,-1, 0, 1, 1, 1, 0 };
static int dc[8] = { -1, 0, 1, 1, 1, 0,-1,-1 };
int side_ = b->side_;
char **dots_ = b->dots_;
for (int r = 0; r < side_; ++r) {
for (int c = 0; c < side_; ++c) {
// The place already has a dot
if (dots_[r][c] == 1)
continue;
// Count up to 4 dots in the 8 directions from current position
int ndots[8] = { 0 };
for (int d = 0; d < 8; ++d) {
for (int i = 1; i <= 4; ++i) {
int nr = r + dr[d] * i;
int nc = c + dc[d] * i;
if (nr < 0 || nc < 0 || nr >= side_ || nc >= side_ || dots_[nr][nc] != 1)
break;
++ndots[d];
}
}
// Decide if the position is a valid one
for (int d = 0; d < 4; ++d) {
if (ndots[d] + ndots[d + 4] >= 4)
dots_[r][c] = 2;
}
}
}
}
Note that I defined a square board with a pointer to pointers to chars, one per place. If there is a 0 in one of the places, then there is no dot and the place is not a valid move; if there is a 1, then there is a dot; if there is a 2, then the place has no dot, but it is a valid move. Valid here means that there are at least 4 dots aligned with the current one.
You can model the directions with a number from 0 to 7 (start from NW, move clockwise). Each direction has an associated movement expressed as dr and dc. Moving in every direction I count how many dots are there (up to 4, and stopping as soon as I find a non dot), and later I can sum opposite directions to obtain the total number of aligned points.
Of course these move are not necessarily valid, because we are missing the definition of lines already drawn and so we cannot check for them.
Here you can find a test for the function.
#include <stdio.h>
#include <stdlib.h>
board *board_init(board *b, int side) {
b->side_ = side;
b->dots_ = malloc(side * sizeof(char*));
b->dots_[0] = calloc(side*side, 1);
for (int r = 1; r < side; ++r) {
b->dots_[r] = b->dots_[r - 1] + side;
}
return b;
}
board *board_free(board *b) {
free(b->dots_[0]);
free(b->dots_);
return b;
}
void board_cross(board *b) {
board_init(b, 18);
for (int i = 0; i < 4; ++i) {
b->dots_[4][7 + i] = 1;
b->dots_[7][4 + i] = 1;
b->dots_[7][10 + i] = 1;
b->dots_[10][4 + i] = 1;
b->dots_[10][10 + i] = 1;
b->dots_[13][7 + i] = 1;
b->dots_[4 + i][7] = 1;
b->dots_[4 + i][10] = 1;
b->dots_[7 + i][4] = 1;
b->dots_[7 + i][13] = 1;
b->dots_[10 + i][7] = 1;
b->dots_[10 + i][10] = 1;
}
}
void board_print(const board *b, FILE *f)
{
int side_ = b->side_;
char **dots_ = b->dots_;
for (int r = 0; r < side_; ++r) {
for (int c = 0; c < side_; ++c) {
static char map[] = " oX";
fprintf(f, "%c%s", map[dots_[r][c]], c == side_ - 1 ? "" : " - ");
}
fprintf(f, "\n");
if (r < side_ - 1) {
for (int c = 0; c < side_; ++c) {
fprintf(f, "|%s", c == side_ - 1 ? "" : " ");
}
fprintf(f, "\n");
}
}
}
int main(void)
{
board b;
board_cross(&b);
board_set_possible_moves(&b);
board_print(&b, stdout);
board_free(&b);
return 0;
}

maze generation algorithm in c with DFS

recently i read this topic about generating mazes in c . see here https://www.algosome.com/articles/maze-generation-depth-first.html
and i want to write it in c . here is my code and it's not working right .
#include <stdio.h>
#include <time.h>
#include <stdlib.h>
int check[5][5];
int v[5][5];
int border(int x , int y ){
if(x> -1 && x< 6 && y > -1 && y<6)
return 1;
else
return 0 ;
}
int wall[6][6][6][6];
void dfs ( int x , int y){
srand(time(NULL));
int s = 1/*rand() % 4 ;*/ ;
if(s=1 ){
if(border(x ,y-1)&& check[x][y-1]==0){
check[x][y]=1;
wall[x][y][x+1][y]=1;
dfs(x , y-1);
}
else
return ;
}
else if(s=2){
if(border(x+1 ,y)&&check[x+1][y]==0){
check[x][y]=1;
wall[x+1][y][x+1][y+1]=1;
dfs(x+1 , y);
}
else return ;
}
else if(s=3){
if(border(x ,y+1)&&check[x][y+1]==0){
check[x][y]=1;
wall[x][y+1][x+1][y+1]=1;
dfs(x , y+1);
}
else return ;
}
else if(s=0){
if(border(x-1 ,y)&&check[x-1][y]==0){
check[x][y]=1;
wall[x][y][x][y+1]=1;
dfs(x-1 , y);
}
else return ;
}
return ;
}
int main(){
dfs( 4, 4);
for(int i =0 ; i < 6 ; i++)
for (int j =0 ; j < 6 ; j++)
for ( int h =0 ; h <6 ; h++)
for (int k =0 ; k < 6 ; k ++)
printf("%d \n" , wall[i][j][h][k]);
return 0 ;
}
i invert my table to graph , and i want to show me the coordinates of my walls .
what's the problem ?
You have several errors – programming errors and logic errors – in your code:
When you distiguish between the directions the s=1 and so on should be s == 1. You want a comparison, not an assignment. (Your code is legal C, so there is no error.)
You call srand at the beginning of dfs, which you call recursively. This will make your single (commented) rand call always create the same random number. You should seed the pseudo random number generator only once at the beginning of main.
You can store the paths the way you do, but it is wasteful. There are only four possible paths from each cell, so you don't need an array that allows to create a path between (0,0) and (3,4), for example.
Your code would benefit from using constants or enumerated values instead of the hard-coded 5's and 6's. This will allow you to change the dimensions later easily.
But your principal error is in how you implement the algorithm. You pick one of the for directions at random, then test whether that direction leads to a valid unvisited cell. If so, you recurse. If not, you stop. This will create a single unbranched path through the cells. Note that if you start in a corner cell, you have already a 50% chance of stopping the recursion short.
But you want something else: You want a maze with many branches that leads to every cell in the maze. Therefore, when the first recursion returns, you must try to branch to other cells. The algorithm goes like this:
Make a list of all possible exits.
If there are possible exits:
Pick one exit, create a path to that exit and recurse.
Update the list of possible exits.
Note that you cannot re-use the old list of exits, because the recursion may have rendered some possible exits invalid by visiting the destination cells.
Below is code that creates a maze with the described algorithm. I've used two distinct arrays to describe horizontal and vertical paths:
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
enum {
W = 36, // width of maze
H = 25 // height of maze
};
enum {
North,
East,
South,
West,
NDir
};
char visited[H][W];
char horz[H][W - 1]; // horizontal E-W paths in the maze
char vert[H - 1][W]; // veritcal N-S paths in the maze
/*
* Fill dir with directions to unvisited cells, return count
*/
int adjacent(int dir[], int x, int y)
{
int ndir = 0;
if (y > 0 && visited[y - 1][x] == 0) dir[ndir++] = North;
if (x < W - 1 && visited[y][x + 1] == 0) dir[ndir++] = East;
if (y < H - 1 && visited[y + 1][x] == 0) dir[ndir++] = South;
if (x > 0 && visited[y][x - 1] == 0) dir[ndir++] = West;
return ndir;
}
/*
* Traverse cells depth first and create paths as you go
*/
void dfs(int x, int y)
{
int dir[NDir];
int ndir;
visited[y][x] = 1;
ndir = adjacent(dir, x, y);
while (ndir) {
int pick = rand() % ndir;
switch (dir[pick]) {
case North: vert[y - 1][x] = 1; dfs(x, y - 1); break;
case East: horz[y][x] = 1; dfs(x + 1, y); break;
case South: vert[y][x] = 1; dfs(x, y + 1); break;
case West: horz[y][x - 1] = 1; dfs(x - 1, y); break;
}
ndir = adjacent(dir, x, y);
}
}
/*
* Print a map of the maze
*/
void map(void)
{
int i, j;
for (i = 0; i < W; i++) {
putchar('_');
putchar('_');
}
putchar('\n');
for (j = 0; j < H; j++) {
putchar('|');
for (i = 0; i < W; i++) {
putchar(j < H - 1 && vert[j][i] ? ' ' : '_');
putchar(i < W - 1 && horz[j][i] ? '_' : '|');
}
putchar('\n');
}
}
int main()
{
srand(time(NULL));
dfs(0, 0);
map();
return 0;
}
You can test it here. If you replace the while in dsf with a simple if, you get more or less what you implemented. Note that this creates only a single, usually short path.

CS 50- Pset 1 Mario Program

the problem set asks us to create a half pyramid using hashes. Here is a link to an image of how it should look-
I get the idea and have written the program until printing the spaces (which I have replaced by "_" just so that I can test the first half of it.
However, when I try to run my program, it doesn't go beyond the do-while loop. In other words, it keeps asking me for the height of the pyramid and does not seem to run the for loop at all. I've tried multiple approaches but this problem seems to persist.
Any help would be appreciated!
Below is my code-
# include <cs50.h>
# include <stdio.h>
int main(void)
{
int height;
do
{
printf("Enter the height of the pyramid: ");
height = GetInt();
}
while (height > 0 || height < 24);
for (int rows = 1; rows <= height, rows++)
{
for (int spaces = height - rows; spaces > 0; spaces--)
{
printf("_");
}
}
return 0;
}
Running this program yields the following output-
Enter the height of the pyramid: 11
Enter the height of the pyramid: 1231
Enter the height of the pyramid: aawfaf
Retry: 12
Enter the height of the pyramid:
Your do/while loop condition is incorrect - change:
do {
...
} while (height > 0 || height < 24);
to either:
do {
...
} while (height <= 0 || height >= 24);
or:
do {
...
} while (!(height > 0 && height < 24));
(whichever you consider to be more readable/intuitive).
is this more simple
for(int i=0;i<8;i++) {
for(int j=0;j < (8-i); j++)
{
System.out.print(" ");
}
for(int k=0;k<=(i+1);k++)
{
System.out.print("#");
}
System.out.println();
}

custom string alignment using printf in C

I'm trying to get the following output from the given array
Apples 200 Grapes 900 Bananas Out of stock
Grapefruits 2 Blueberries 100 Orangess Coming soon
Pears 10000
Here's what I came up so far (feels like I'm overdoing it), however, I'm still missing something when padding the columns. I'm open to any suggestions on how to approach this.
#include <stdio.h>
#include <string.h>
#define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0]))
char *fruits[][2] = {
{"Apples", "200"},
{"Grapes", "900"},
{"Bananas", "Out of stock"},
{"Grapefruits", "2"},
{"Blueberries", "100"},
{"Oranges", "Coming soon"},
{"Pears", "10000"},
};
int get_max (int j, int y) {
int n = ARRAY_SIZE(fruits), width = 0, i;
for (i = 0; i < n; i++) {
if (i % j == 0 && strlen(fruits[i][y]) > width) {
width = strlen(fruits[i][y]);
}
}
return width;
}
int main(void) {
int n = ARRAY_SIZE(fruits), i, j;
for (i = 0, j = 1; i < n; i++) {
if (i > 0 && i % 3 == 0) {
printf("\n"); j++;
}
printf("%-*s ", get_max(j, 0), fruits[i][0]);
printf("%-*s ", get_max(j, 1), fruits[i][1]);
}
printf("\n");
return 0;
}
Current output:
Apples 200 Grapes 900 Bananas Out of stock
Grapefruits 2 Blueberries 100 Oranges Coming soon
Pears 10000
You are computing widths wrong. In essence, you want to be able to compute the width of a particular column. Thus, in your get_max function, you should be able to specify a column. We can then pick out the elements from the list based on whether their index mod 3 is equal to the column. This can be accomplished as such:
int get_max (int column, int y) {
...
if (i % 3 == column /* <- change */ && strlen(fruits[i][y]) > width) {
...
}
Then in your main loop, you want to choose the widths of the columns based on what column you are currently in. You can do that by taking the index mod 3:
for (i = 0, j = 1; i < n; i++) {
...
printf("%-*s ", get_max(i % 3 /* change */, 0), fruits[i][0]);
printf("%-*s ", get_max(i % 3 /* change */, 1), fruits[i][1]);
}
This should work as you expect.
I dint try understanding your logic but i think you can space the data using tab with "\t":
printf("%s \t %d","banana", 200);

Resources