Drawing an X with C with ONLY While-loops & If-Statements - c

An assignment we have been given is to draw an X in C using only while loops and if statements (maths and expressions are allowed).
I have only done the first half of the X in code, as the other half is just the reverse.
The challenging part is the middle dashes (-), as I'm struggling to find a way to make them count backward by 2 through while loops.
Am I overthinking this way too much? If so, what would be a better approach to this problem?
This is my first time learning C and we are not allowed for loops or anything beyond a basic level.
Thanks for reading!
int size, fLine, rowCounter, tempSize;
printf("Enter size: ");
scanf("%d", &size);
// The split will half the size of the X to run 2 seperate while loops
// One loop for the top half and another for the lower half.
int split = ((size - 1) / 2);
int row = 1;
// Top half of the X
while (row <= split) {
// Condition to print out the top and bottom line of the X
if ((row == 1) || (row == size)) {
printf("*");
// tempSize will allow for the counter to decrease without
// affecting the size variable
tempSize = size;
// Will add the middle dashes on the top line
while ((tempSize - 2) > 0) {
printf("-");
tempSize--;
}
printf("*\n");
row++;
} else {
// The dashes before the first asterisks
// rowCounter allows the row number to be decreased in the
// while loop
rowCounter = row - 1;
while (rowCounter > 0) {
printf("-");
rowCounter--;
}
printf("*");
// Will add size + (row * -2) dashes into the middle
// **This section is the subject of the question!**
rowCounter = row * 2;
tempSize = rowCounter - size; // 2 - 5 = -3
while (tempSize < (size - 1)) {
printf("-");
tempSize++;
}
printf("*");
// Will add the final dashes. Exactly the same as the first
// while loop
rowCounter = row - 1;
while (rowCounter > 1) {
printf("-");
rowCounter--;
}
printf("-\n");
row++;
} //Yet to add the middle line and the bottom half!
}
return 0;
}
Expected Result:
Enter Size: 5
*---*
-*-*-
--*--
-*-*-
*---*
Actual Result:
Enter Size: 5
*---*
-*-----*-
I want the middle values to count BACKWARD so 9, 7, 5, 3, 1, etc., instead of upwards by 2.

i have a much easier solution
#include <stdio.h>
int size, i=0, j=0;
printf("Please Enter a Odd Size: \n")
scanf(%d, &size);
while(size%2==0)
{
printf("Only Odd size is ok \n");
printf("Please Enter a Odd Size: \n")
scanf(%d, &size);
}
while(i<size)
{
j=0;
while(j<size)
{
if(j == i || i == (size-1)-j)
{
printf("!");
}
else
{
printf("-");
}
j++;
}
printf("\n\n");
i++;
}
the output is:
!---!
-!-!-
--!--
-!-!-
!---!

I messed around a little:
#include <stdio.h>
int main()
{
int size = 5;
if( size % 2 == 1 )
{
fprintf( stdout, "now drawing\n");
int lineCount = 0;
int lastPost = size - 1;
while( lineCount < size )
{
int rowCount = 0;
while( rowCount < size )
{
if( ( rowCount == lineCount )
|| ( rowCount == lastPost ) )
{
fprintf( stdout, "X");
}
else
{
fprintf( stdout, ".");
}
++rowCount;
}
fprintf( stdout, "\n");
--lastPost;
++lineCount;
}
}
else
{
fprintf( stderr, "size must be odd!\n");
}
return 0;
}

Related

connect 4 (4-in-a-row) , place a mark on the board, c program

I made a connect 4 game where the player can choose the number of rows and columns.
this is my function to put the player's mark on the board:
void get_and_check_place_on_the_board (char player_sign, char board[][25], int columns_number, int rows_number, int place_on_board)
{
int column_chosen;
while (place_on_board[0] == -1)
{
do {
printf(game_messages[MSG_GET_COLUMN]);
scanf("%d", &column_chosen);
} while (column_chosen <= 0 && column_chosen > columns_number);
for (int i = rows_number - 1; i >= 0; i--)
{
if (board[i][column_chosen - 1] == ' ')
{
board[i][column_chosen - 1] = player_sign;
place_on_board[0] = i;
place_on_board[1] = column_chosen - 1;
return;
}
}
printf("column full");
}
}
player_sign is "R" or "Y", the player decide the rows and columns number (not more than 25), and the place_on_board is an array, initialized to {-1, -1}.
The compiler says that: "subscripted value is neither array nor pointer nor vector", and that: "parameter 'place_on_board' set but not used"
what can i do?

Specific dice to reroll in C

I am working on a game of Yahtzee and one part of the game is the user can choose which dice out of 5 they wish to re-roll. I don't really know how to approach this besides writing a ton of if if-else statements, but there has to be a more efficient way to re-roll the specific die/ dice. I wrote out a snippet of what I am trying to accomplish, its not exactly like this in my actual code, but hopefully it is enough to answer the question :)
#include<stdio.h>
int main(void)
{
int die1 = 0, die2 = 0, die3 = 0, die4 = 0, die5 = 0;
int *ptr_die1 = &die1, *ptr_die2 = &die2, *ptr_die3 = &die3, *ptr_die4 = &die4, *ptr_die5 = &die5;
int choice = 0;
int die[5] = { 0 };
for (int i = 0; i < 5; i++)
{
die[i] = rand() % 6 + 1;
}
printf("Die[1] = %d\n", die[0]);
printf("Die[2] = %d\n", die[1]);
printf("Die[3] = %d\n", die[2]);
printf("Die[4] = %d\n", die[3]);
printf("Die[5] = %d\n", die[4]);
choice = printf("Please select which die to reroll\n");
scanf("%d", &choice);
printf("%d\n", choice);
for (int i = 0; i < 5; i++)
{
die[choice-1] = rand() % 6 + 1;
}
printf("Die[1] = %d\n", die[0]);
printf("Die[2] = %d\n", die[1]);
printf("Die[3] = %d\n", die[2]);
printf("Die[4] = %d\n", die[3]);
printf("Die[5] = %d\n", die[4]);
return 0;
}
after this I am really lost on how to change the die because the user could want to change just 1, or all 5 or any combination in between...
You have way too many variables that are not really needed.
int main(int argc, char **argv)
{
int i;
int choice;
int dices[5];
srand(time(NULL));
while(1){
for (i = 0; i < 5; i++)
dices[i] = rand() % 6 + 1;
choice = printf("Please select which die to reroll (or enter 0 to quit)");
scanf("%d", &choice);
if (choice == 0) // end the game
break;
if (choice < 1 || choice > 5 ){ // make sure that input is valid
fprintf(stderr, "error, input should be between 1 to 5 (inclusive)\n");
return -1;
}
printf("dice shows: %d", dices[choice-1]);
}
return 0;
}
You need to ask the user for the ending it, e.g. "Enter 0 to end the game". Otherwise it would be an infinite loop.
You could have the user input a comma-separatd list of die, instead of a single integer, which it looks like you're doing now. Then just parse the input, check that you have between 1 and 5 valid integers less than 6, and index into each die.
Or you could do like kaylum suggested and loop until the user inputs a special string indicating they're done, or prompt for 1, 2, ... 5 and ask for a yes or no answer to each.
Just use an array of int values to represent the set of dice:
#define DICE_COUNT 6
void rollDice(int* diceArray, size_t diceIndex) {
assert( 0 <= diceIndex && diceIndex < DICE_COUNT );
diceArray[ diceIndex ] = rand() % 6 + 1;
}
int main(int argc, char* argv[]) {
// Seed the RNG:
srand( (unsigned)time(&t) );
int dice[DICE_COUNT];
for(size_t i = 0; i < DICE_COUNT; i++) {
rollDice( dice, i );
}
while( true ) {
printf("Please select which die to reroll. Enter -2 to quit. (%d to %d inclusive)", 1, DICE_COUNT);
int selection = -1;
scanf("%d", &selection);
if( selection == -2 ) break;
if( 1 <= selection && selection <= DICE_COUNT ) {
selection--; // convert from 1-6 to 0-5.
rollDice( dice, selection );
}
}
return EXIT_SUCCESS;
}
I don't see any if..else statements in your code above. I will say, in this chunk of code:
for (int i = 0; i < 5; i++)
{
die[choice-1] = rand() % 6 + 1;
}
You don't need the for loop. You are not using the index, and rand() should work the first time through. I know rand() isn't the best written function, but if you seed it first, it should give you a pseudo-random number.
#include <time.h>
...
/* initialize random seed: */
srand ( time(NULL) );
...
die[choice-1] = rand() % 6 + 1;
Hope this was helpful, if you are still even working on that project!

end loop based on input from user

My program accepts a number from the user to determine the length of a sequence being recorded. How would i take that number and also let it determine the number of times this loop is performed. While(true) obviously does not allow the loop to end at all.
thanks in advance
here is the function to synthesise sound from midi input
void midisound (int note)
{
int velocity;
int playingNote = -1;
float frequency;
while(true)
{
note = aserveGetNote();
velocity = aserveGetVelocity();
if(velocity > 0)
{
frequency = 440 * pow(2, (note-69) / 12.0);
aserveOscillator(0, frequency, 1.0, 0);
playingNote = note;
}
else if(note == playingNote)
{
aserveOscillator(0, 0, 0, 0);
}
}
}
---here is where function ^ is called in the program----
if (reclayer == 1)
{
//open first text file for layer 1 to be written to
textFilePointer = fopen("recording1.txt", "w+");
if(textFilePointer == NULL)
{
printf("Error Opening File!");
}
else
{
//function call to write notes and vel data
notetofile(input, seqlen, reclayer);
printf("Would you like to record a second layer or re-record? (y or n)\n");
scanf(" %c", &choice2);
}
}
Use a for loop.
for ( i = 0; i < note; i++ ) {
// Your code here
}
This will execute 'note' number of times.
Use can use the scanf() function to input a user number from the console:
void midisound (int note) {
int input;
int velocity;
int playingNote = -1;
float frequency;
printf("Enter integer number of times to loop: ");
scanf("%d", &input);
while(input > 0) {
input = input - 1;
note = aserveGetNote();
velocity = aserveGetVelocity();
if(velocity > 0) {
frequency = 440 * pow(2, (note-69) / 12.0);
aserveOscillator(0, frequency, 1.0, 0);
playingNote = note;
} else if(note == playingNote) {
aserveOscillator(0, 0, 0, 0);
}
}
}
In that first get the number input from the user number of time loop will be run the use following
for ( i=0 ; i < max ; i++ )
First assign a variable which holds the number of times you want to repeat it. For example , let us take int n = 5;. ( You can also make the user input the value of n ( as that is what you have asked ) by calling scanf( "%d " , &n ); and then do the rest )
int n ;
scanf( "%d " , &n );
You can use this as common for all of my below cases
Then, just add a simple for loop, such as
int i;
for ( i = 0 ; i < n ; i++ )
{
// The code that you want to repeat
}
That should do the trick.
In case you want to use a while loop, then as before, let n be the number of times the loop must execute. Then
int i=0;
while ( i < n )
{
// Your code
i++;
}
You can also use the while ( true ) loop as well, but you will just have to give a condition and use break;. Let us take an example as above.
int i=0;
while ( true )
{
// your code
i++;
if ( i == n )
break;
}
These are just many of the different possibilities. You can even come up with your own condition if you try.
Happy coding .... 8-)

Find number of paths in a 2d binary array (C)

I have been asked this question during an interview, and have been struggling to find an elegant solution (in C), Problem statement:
You are given a two-dimensional array with M rows and N columns.
You are initially positioned at (0,0) which is the top-left cell in
the array.
You are allowed to move either right or downwards.
The array is filled with 1′s and 0′s. A 1 indicates that you can move
through that cell, a 0 indicates that you cannot move through the
cell.
Write a function in C ‘numberOfPaths’ which takes in the above two dimensional array, return the number of valid paths from the top-left cell to the bottom-right cell (i.e. [0,0] to [M-1,N-1]).
Edit: forgot to mention that the requirement is for a recursive solution
help would be greatly appreciated!
Thanks
If you are looking for a recursive solution you can use DFS.
DFS (array, x, y)
{
if (array [x][y]==0 || x>M || y>N){
return;
}
if (x==M && y==N){
count++;
return;
}
DFS (array, x, y+1);
DFS (array, x+1, y);
}
The number of paths to a given point is just the number of paths to the point above, plus the number of paths to the point to the left. So, the pseudo-code would roughly be:
num_paths[0][0] = 1;
for (x = 0; x < M; ++x)
for (y = 0; y < N; ++y)
if (!allowed_through[x][y])
num_paths[x][y] = 0;
else
num_paths[x][y] = num_paths[x-1][y] + num_paths[x][y-1];
You need special cases for x=0 and y=0, but otherwise, I think that should do.
#include <stdio.h>
int count=0;
int maxrows = 10;
int maxcols = 10;
int M, N;
void DFS (int array[][10], int x, int y)
{
int r, c;
/* process element at input row and column */
if (array [x][y]==0 || x>M || y>N){
/* no path forward; return */
return;
}
if (x==M-1 && y==N-1){
/* found path; increment count */
count++;
return;
}
/* recurse: to matrix starting from same row, next column */
r = x;
c = y +1;
if (c < N-1) {
DFS (array, r,c);
} else {
/* if last column - check to see */
/* if rest of rows in last column allow for a path */
int tr = r;
while ( tr <= M-1) {
if (array[tr][c] == 1) {
tr++;
}
else {
return;
}
}
/* reached last node - path exists! */
count++;
}
/* recurse: to matrix starting from next row, same column */
r = x+1;
c = y;
if (r < M-1) {
DFS (array, r,c);
} else {
/* if last row - check to see */
/* if rest of columns in last row allow for a path */
int tc = c;
while ( tc <= N-1) {
if (array[r][tc] == 1) {
tc++;
} else {
return;
}
}
/* reached last node - path exists! */
count++;
}
}
int main () {
int i, j;
scanf("%d %d",&M,&N);
int a[10][10] = {};
int row, col;
for(i=0;i<M;i++)
for(j=0;j<N;j++)
scanf("%d", &a[i][j]);
if ((M > maxrows) || (N > maxcols)) {
printf("max of 10 rows and 10 cols allowed for input\n");
return (-1);
};
/* print input matrix */
for(row=0;row<M;row++) {
for(col=0;col<N;col++){
printf("%d ",a[row][col]);
}
printf(" EOR\n");
}
DFS(a,0,0);
printf("number of paths is %d\n", count);
return 0;
}
Try this function its a preliminary step before printing all the paths.
If the size of the vector Out is 0 then the # of paths are 0, but if size(Out) > 0 then the size of vector Nodes + 1 are the total number of paths from top left to bottom right.
#include <iostream>
#include <vector>
using namespace std;
typedef vector<pair<int,int> > vPii;
bool pathTL2BR( int Arr2D[][4], vPii &Out, vPii &Nodes,
int _x,int _y, int _M, int _N)
{
bool out1 = false;
bool out2 = false;
if( Arr2D[_x][_y] == 1 )
{
if( _y+1 < _N )
out1 = pathTL2BR( Arr2D, Out, Nodes, _x, _y+1, _M, _N);
if( _x+1 < _M )
out2 = pathTL2BR( Arr2D, Out, Nodes, _x+1, _y, _M, _N);
if( (out1 || out2) ||
( (_x == (_M-1)) && (_y == (_N-1)) ) )
{
if(out1 && out2)
Nodes.push_back( make_pair(_x,_y ) );
Out.push_back( make_pair(_x,_y ) );
return true;
}
else
return false;
}
else
return false;
}
// Driver program to test above function
int main()
{
int Arr2D[][4] = {
{1,1,1,1},
{0,1,0,1},
{0,1,0,1},
{0,1,0,1}
};
vPii Out;
vPii Nodes;
vector<vPii> Output;
pathTL2BR( Arr2D, Out, Nodes, 0, 0, 4, 4);
return 0;
}
This is a python solution, I have put explanations in the comments.
def find_num_paths(arr_2D, i, j):
# i,j is the start point and you have to travel all the way back to 0,0
if i == j and i == 0:
return 1 # you have reached the start point
if i < 0 or j < 0 or arr_2D[i][j] == 0: # out of range or no path from that point
return 0
if arr_2D[i][j] == 1:
return find_num_paths(arr_2D, i, j-1) + find_num_paths(arr_2D, i-1, j) + find_num_paths(arr_2D, i-1, j-1) # you could go one step above, to the left or diagonally up.

How can I do this again? in C

#define G 10
int main(){
int grid[G][G],c,x;
for(c=1;c<=5;c++){
for(x=1;x<=5;x++){
if(c+x<=5)
grid[c][x]=+1;
else if(c+x>=7)
grid[c][x]=-1;
else
grid[c][x]=0;
printf("%2d\t ",grid[c][x]);
}
printf("\n");
}
getch();
return 0;
}
its output is
Which is what I really wanted to do but now I need to make it look like
and now I don't have any idea on how to do it, it's hurting my head now
I would do it like this
for(c=0; c<5; c++) { /* arrays start at 0, not 1. */
for(x=0; x<5; x++) { /* arrays start at 0, not 1. */
if (c == x) { /* looking at your output, the 0's occur when c == x */
grid[c][x] = 0;
} else if (c > x) { /* the -1 when c > x */
grid[c][x] = -1;
} else { /* obviously c > x */
grid[c][x] = 1;
}
/* nothing else changed */
printf("%2d\t ",grid[c][x]);
}
printf("\n");
}
It's quite simple, you have three distinct cases:
if both c and x are equal, your grid shows zero
if x is greater than c, your grid shows 1
else (ie, when x is less than c), your grid shows -1
Basically, we've written the if-else structure you need in your loop to get the desired output:
if (c == x) grid[c][x] = 0;
else if (x > c) grid[c][x] = 1;
else grid[c][x] = -1;
Thus, the full code looks like this:
#include <stdio.h>
#define G 10
int main()
{
int grid[G][G],c,x;
for(c=0;c<5;++c)
{//zero indexed
for(x=0;x<5;++x)
{//perhaps change 5 with G, or another macro or some int
if(c == x) grid[c][x] = 0;
else if (c < x) grid[c][x] = 1;//1 is fine, the + is not required
else grid[c][x] = -1;
printf("%2d\t ",grid[c][x]);
}
printf("\n");
}
return 0;
}
Which as you can see on this codepad works just fine.
note:
As I said, the + in +1 is optional. I'd even advise against it. If I happen to come across a statement like some_int = +1; I might assume that it's a bug, and it was supposed to read some_int += 1;, which is a different thing all together.
The major diagonal of matrix is collection of elements that meet row==column condition. Plus we know that row and column elements above(right from) diagonal meet row<column, and below ones row>column condition. And here is how to make that matrix and while making we will show them :
#define G 5
int grid[G][G], row, column;
for (row =0; row < G; row++) {
for (column =0; column < G; column++) {
if (row<column)
grid[row][column] = 1;
else if (row>column)
grid[row][column] = -1;
else
grid[row][column] = 0;
printf("%2d\t ", grid[row][column]);
}
printf("\n");
}
And here is output:
0 1 1 1 1
-1 0 1 1 1
-1 -1 0 1 1
-1 -1 -1 0 1
-1 -1 -1 -1 0
And Here is what was your problem.
You chose minor (secondary) diagonal isntead of main
Your index handling done manually .Like you calculated conditions manually. It is not good
And here is how you should do for minor diagonal without calculating condition manually
#define G 5
int grid[G][G], row, column ;
for(row=0;row<G;row++){
for(column=0;column< G;column++){
if(row+column<G-1)
grid[row][column]=1;
else if(row+column>G-1)
grid[row][column]=-1;
else /*minor diagonal meet row==(G-1)-column //G-1 cause index begins from 0*/
grid[row][column]=0;
printf("%2d\t ",grid[row][column]);
}
printf("\n");
}
Now Swap the first and last columns of your matrix then second and second last. Thats it
#include <stdio.h>
#define G 10
int i,j;
int grid[G][G];
int main() {
for(i=0; i<G; i++) {
for(j=0; j<G; j++) {
if(i==j) grid[i][j]=0;
else if(i<j) grid[i][j]=1;
else if(i>j) grid[i][j]=-1;
printf("%2d\t", grid[i][j]);
}
printf("\n");
}
return 0;
}
you can modify your program as below :
1,for(c=1;c<=5;c++) -->for(c=5;c>=1;c--)
2, grid[c][x]=+1; --> grid[c][x]=-1;
3, grid[c][x]=1; --> grid[c][x]=+1;
#define G 10
int main(){
int grid[G][G],c,x;
for(c=5;c>=1;c--){
for(x=1;x<=5;x++){
if(c+x<=5)
grid[c][x]=-1;
else if(c+x>=7)
grid[c][x]= 1;
else
grid[c][x]=0;
printf("%2d\t ",grid[c][x]);
}
printf("\n");
}
getch();
return 0;
}
You need to create a 2D matrix, where the matrix is diagonally zero, upper triangle would be 1, and lower triangle would be -1.
So,
if **row == column** , then assign 0 to diagonal. (**grid[row][column] = 0**)
else if , **row < column**, then assign 1 to upper triangle. (*grid[row][column*] = 1)
else, **row > column**, then assign -1 to lower triangle. (*grid[row][column] = -1*)

Resources