I have an exercise in Objective-C making use of for, if-else and printf to print a Zig-Zag like this in the console:
Please see image:
I have tried a code with C programming and print a triangle then try to edit this one, but can't do anything more to get my Zig-Zag.
I have solve my problems already. Thank you guys so much.
for (int i = 0; i < 5; i++) {
for(int j = 1; j<= 21; j++ ){
if(j<=9){
if(j - i == 5 || j+ i == 5){
printf("*") ;
}else{
printf(" ");
}
}else{
if(j+i == 13 || j - i == 13 || j + i == 21){
printf("*") ;
}
else{
printf(" ");
}
}
}
printf("\n");
}
OK, attempt 2 based on your updated question. Let's start with the basic structure. Set some consts for the width and height - we will refer to these in multiple places, so consts make for nice easy changes - and create a loop with basic logic to start to get the display you want.
const int numRows = 5;
const int numCols = 21;
for (int row = 0; row < numRows; ++row)
{
for (int col = 0; col < numCols; ++col)
{
if (col == row)
{
printf("X");
}
else
{
printf(" ");
}
}
printf("\n");
}
This gives us:
X
X
X
X
X
which is the wrong way up and only gives us one "downstroke", but it is a good start. Let's use the modulus function to make the pattern repeat. The repeat happens on the 9th character, which suggests we need to use ((numRows - 1) * 2) for our modulus.
const int modulusVal = ((numRows - 1) * 2);
for (int row = 0; row < numRows; ++row)
{
for (int col = 0; col < numCols; ++col)
{
int modCol = (col % modulusVal);
if (modCol == row)
{
printf("X");
}
else
{
printf(" ");
}
}
printf("\n");
}
So now we get:
X X X
X X X
X X X
X X X
X X X
which is starting to get a lot closer to what we want. So, on to the upstrokes. The downstrokes are displayed when modCol is in the range of row, which is 0-4. When modCol is past this range, we bring it back into range by subtracting the number of rows from it.
Then we "invert" it by subtracting it from the highest value that row can be, which is numRows - 1. This means that when modCol is 0 it will become 4, when it is 1 it will become 3, when it is 2 it will be unchanged.
for (int row = 0; row < numRows; ++row)
{
for (int col = 0; col < numCols; ++col)
{
int modCol = (col % modulusVal);
if (modCol >= numRows)
{
modCol -= numRows;
modCol = ((numRows - 1) - modCol);
}
if (modCol == row)
{
printf("X");
}
else
{
printf(" ");
}
}
printf("\n");
}
Now we get:
X X X
X X X
X X X X X
X X X X X
XX XX X
Close, but no cigar. Column 5 is being treated as column 0, but we need it to be treated as column 1. Make this change to fix it:
modCol = ((numRows - 1) - (modCol + 1));
Output:
X X X
X X X X X
X X X X X
X X X X X
X X X
This has the pattern we want, but starts at the top left when we want the bottom left. Easy fix. Invert modCol after it has been calculated in the same we we invert it when it is greater/equal than/to numRows.
for (int row = 0; row < numRows; ++row)
{
for (int col = 0; col < numCols; ++col)
{
int modCol = (col % modulusVal);
if (modCol >= numRows)
{
modCol -= numRows;
modCol = ((numRows - 1) - (modCol + 1));
}
modCol = ((numRows - 1) - modCol);
if (modCol == row)
{
printf("X");
}
else
{
printf(" ");
}
}
printf("\n");
}
Finally we get the output we want:
X X X
X X X X X
X X X X X
X X X X X
X X X
I hope this helps and is reasonably easy to understand.
I'm not familiar with console programming using Objectionable C and you haven't explained exactly what you've tried, what has worked and what has not.
Assuming your problem is the code to choose the appropriate position to display the '+' character and not displaying text at a particular location on the console, here's what I would do:
int currentY = MIN_Y;
int incrementY = 1;
for (int currentX = MIN_X; currentX <= MAX_X; ++currentX)
{
SetCursorPosition(currentX, currentY);
printf("+");
currentY += incrementY;
if (currentY == MAX_Y)
{
incrementY = -1;
}
else if (currentY == MIN_Y)
{
incrementY = 1;
}
}
This assumes you have a function for SetCursor() and consts/defines for MIN/MAX X/Y.
The 'if' statement could be optimised to:
if (currentY == MAX_Y || currentY == MIN_Y)
{
incrementY -= incrementY;
}
but you required the use of the 'else' statement. Hopefully this code is pretty self explanatory and of some use to you.
Related
Hi a have a code like these:
for (int row = 0; row < a.length; row++) {
for (int col = 0; col < a[row].length; col++) {
// Do something with a[row][col];
}
}
But i want to make an operation in a grid (8-neighbours) for every a[row][col] , however when im at the corners i will have problems (i don't know how to check if im in a corner), i was thinking in code a lot of if - conditionals, but i dont know the effective way to do this..
If there is a perse method for do this types of traversal neighbours arrays i would very greatful if you could give me a link, I've spent all day looking for information and I can't find anything.
You can use these arrays which represent the changes in the indexes when you look at the neighbors from a given position:
int dx[] = {-1,0,1,1,1,0,-1,-1};
int dy[] = {-1,-1,-1,0,1,1,1,0};
At position (row, col), dx[i] represents a change in row and dy[i] represents a change in col. You can use each position in the array to look at the neighbors.
Make a helper function that checks if a position is safe:
boolean isValidPosition(int x, int y) {
return 0 <= x && x < a.length && 0 <= y && y < a[x].length;
}
Then iterate over all 8 positions and you will have access to the neighbors via a[row + dx[i]][col + dy[i]].
for (int row = 0; row < a.length; row++) {
for (int col = 0; col < a[row].length; col++) {
for (int i = 0; i < 8; i++) {
if (isValidPosition(row + dx[i], col + dy[i])) {
// Do something with a[row + dx[i]][col + dy[i]];
}
}
}
}
So I have made this program where you can give in the parameters of a circle or a line and it will display said object by drawing an array on the display.
It works by "projecting" a coordinate-system onto an array. (The program also asks you to give the resolution of the array, the number of columns and rows are the same.) Then for every cell of the array it checks if the circle/line intersects the cell. If it does, or it is within a given range, the cell will get a value of 1. If it is out of range, it will be 0. When all the cells have been given a value, the program displays the array. So in the end you will see a circle or line made of ones, the rest of the arrays will show up in zeroes.
The problem is that it takes a relatively long time (7 to 10s) to print the array, while the actual calculations take like no time.
My question is as said in the title, can the process of displaying the array be sped up somehow? Or am I doing something wrong? I am using Code::Blocks as my compiler.
I know that my code is probably very poorly optimized, but I've only started programming like a week ago. So please forgive me if the code is hard to understand.
Thank you in advance!
#include <stdio.h>
#include <stdlib.h>
int main()
{
float x = 0, y = 0, ypos= 0 , xpos = 0, radius = 0, rsqrd = 0, rcheck = 0, thick = 0, grad = 0, offs = 0, lcheck = 0;
int matsize = 0, i, j, branch = 0;
char filled;
printf("\n0 - circle\n1 - line\nDo you want to draw a circle or a line? (0/1) ");
scanf("%d", &branch);
if(branch == 0)
{
printf("Value of radius: ");
scanf("%f", &radius);
printf("Position of circle on the x axis: ");
scanf("%f", &xpos);
printf("Position of circle on the y axis: ");
scanf("%f", &ypos);
printf("Is the circle filled? (y/n) ");
scanf(" %c", &filled);
if(filled == 'n')
{
printf("The thickness of circle: ");
scanf("%f", &thick);
}
if(filled == 'y' || filled == 'n')
{
printf("Resolution: ");
scanf("%d" , &matsize);
printf("\n");
}
rsqrd = radius*radius; //rsqrd is equal to radius squared.
x = -1*(matsize/2); //with this I make sure that the x and y values start from the top right corner of the matrix, so that each x, y value corresponds to the correct cell position (i, j)
y = matsize/2;
int mat[matsize][matsize];
if(filled == 'n')
{
for(i = 0; i < matsize; i++)
{
for(j = 0; j < matsize; j++)
{
rcheck = ((y - ypos)*(y - ypos)) + ((x - xpos)*(x - xpos)); // calculating the equation of the circle with the x and y values taking the offset into account
if(abs(rcheck-rsqrd) <= (thick*thick))
{
mat[i][j] = 1;
}
else
{
mat[i][j] = 0;
}
x = x+1; //stepping the values of x and y so they stay with the corresponding cell
}
x = -1*(matsize/2);
y = y-1;
}
}
if(filled =='y')
{
for(i = 0; i < matsize; i++)
{
for(j = 0; j < matsize; j++)
{
rcheck = ((y - ypos)*(y - ypos)) + ((x - xpos)*(x - xpos)); // calculating the equation of the circle with the x and y values taking the offset into account
if(rcheck <= rsqrd)
{
mat[i][j] = 1;
}
else
{
mat[i][j] = 0;
}
x = x+1; //stepping the values of x and y so they stay with the corresponding cell
}
x = -1*(matsize/2);
y = y-1;
}
}
if(filled == 'y' || filled == 'n')
{
for(i = 0; i < matsize; i++) // displaying the matrix
{ //
for(j = 0; j < matsize; j++) //
{ //
printf("%d ",mat[i][j]); //
} //
printf("\n"); //
} //
}
}
if(branch == 1)
{
printf("Value of gradient: ");
scanf("%f", &grad);
printf("Value of offset: ");
scanf("%f", &offs);
printf("Thickness of line: ");
scanf("%f", &thick);
printf("Resoultion: ");
scanf("%d", &matsize);
x = -1*(matsize/2); //with this I make sure that the x and y values start from the top right corner of the matrix, so that each x, y value corresponds to the correct cell position (i, j)
y = matsize/2;
int mat[matsize][matsize];
for(i = 0; i < matsize; i++)
{
for(j = 0; j < matsize; j++)
{
lcheck = y - (x * grad); // calculating the equation of the circle with the x and y values taking the offset into account
if(abs(lcheck-offs) <= thick)
{
mat[i][j] = 1;
}
else
{
mat[i][j] = 0;
}
x = x+1; //stepping the values of x and y so they stay with the corresponding cell
}
x = -1*(matsize/2);
y = y-1;
}
if(branch == 1)
{
for(i = 0; i < matsize; i++) // displaying the matrix
{ //
for(j = 0; j < matsize; j++)//
{ //
printf("%d ",mat[i][j]);//
} //
printf("\n"); //
} //
}
}
return 0;
}
As I stated in my comment maybe it has something to do with this stack overflow question and answer
After reading a bit, you could also try to buffer your stdout in order to make it faster.
I have created a series of for loops but for some reason, I keep on getting infinitely many #'s as my output. I'm not really sure why this is happening. I am a beginner to programming and I am a little confused. My code is:
for (int i = 0; i < h; i++)
{
for (int x = 0; x < 0; x = -1 * i + (h - 1))
{
printf(" ");
}
for (int y = 0; y < h + 1; y = i + 2)
{
printf("#");
}
printf("\n");
}
The output I'm trying to get is the following:
##\n
###\n
####\n
#####\n
######\n
If someone can help me, I would be extremely grateful :)
Thanks
In the third for loop you have for (int y = 0; y < h + 1; y = i + 2) the increment statement y = i + 2 resets the loop variable y after each run through the body to the same value, and if this value is smaller than h you get an infinite loop.
You could try this:
int h = 7;
for (int i = 0; i < h; i++)
{
int x;
for (x = 0; x < h - i; x++)
{
printf(" ");
}
for (int y = -2; y < i; y++)
{
printf("#");
}
printf("\n");
}
This produces:
##
###
####
#####
######
#######
########
Edit: To shift the triangle of # 1 space to the left the second loop needs to be changed to
for (x = 0; x < h - i - 1; x++)
{
printf(" ");
}
The loop printing the spaces will never execute - you initialise x to 0, then loop while x < 0 which is immediately false.
The loop printing '#' never exits because y is not modified in the loop y = i + 2 will not advance y - it will simply assign it the value 2 indefinitely. You in fact have a similar problem in the previous x loop, bit it never gets that far.
The above can most easily be discovered by using a debugger and stepping the code rather than posting questions on SO.
The pattern can in fact be generated using just a single inner-loop:
for( int i = 0; i < h; i++ )
{
for( int x = 0; x < h + 1; x++ )
{
putchar( x < h - i - 1 ? ' ' : '#' ) ;
}
putchar( '\n' );
}
Or perhaps less "clever":
for( int i = 0; i < h; i++ )
{
for( int x = 0; x < h + 1; x++ )
{
if( x < h - i - 1 )
{
putchar( ' ' ) ;
}
else
{
putchar( '#' ) ;
}
}
putchar( '\n' );
}
This issue is that you don't change the value of your loop variables x and y, so they don't terminate normally. Your program keeps on executing the block of the second for-loop.
Let's have a look at the first for:
for (int x = 0; x < 0; x = -1 * i + (h - 1))
When this is executed, h and i are fixed and you also don't change them in the body of this for-loop. Let's say that h is 10; i is 0.
This means that it starts with x being 0. It does not execute its block because x < 0 is false.
Then the second for:
for (int y = 0; y < h + 1; y = i + 2)
If you work this out you'll find that after the first iteration y will always be 0 + 2 is 2. The loop condition the becomes: 2 < 10 + 1 (again assuming h is 10), which is always true. That means that your loop keeps on spinning forever.
Try this:
for (int i = 0; i < h; i++)
{
for (int x = 0; x < h - i; x++)
{
printf(" ");
}
for (int y = i; y < h; y++)
{
printf("#");
}
printf("\n");
}
I think it has one or two OBOs (Out-By-One mistake), but I'm sure you'll fix that soon enough.
I have made a version of conways game of life in C, using a 2d array which should wrap around the sides. Unfortunately all that happens is the numbers flick back and forth between 1 and 0 with no clear pattern. Here is the code:
#include <stdio.h>
int main(){
int const WIDTH = 100;
int const HEIGHT = 100;
int const CYCLES = 1000;
int grid[HEIGHT][WIDTH];
int temp[HEIGHT][WIDTH];
int row;
int col;
for(row = 0; row < HEIGHT; row++){
for(col = 0; col < WIDTH; col++){
grid[row][col] = 0;
}
}
int i;
int x;
int y;
int neighbours;
for(i = 0; i < CYCLES; i++){
for(row = 0; row < HEIGHT; row++){
for(col = 0; col < WIDTH; col++){
temp[row][col] = 0;
}
}
for(row = 0; row < HEIGHT; row++){
for(col = 0; col < WIDTH; col++){
neighbours = 0;
for(y = -1; y < 2; y++){
for(x = -1; x < 2; x++){
if(x != 0 && y != 0 && grid[(row + y) % HEIGHT][(col + x) % WIDTH] == 1){
neighbours++;
}
}
}
if(grid[row][col] == 1){
if(neighbours < 2 || neighbours > 3){
temp[row][col] = 0;
}else{
temp[row][col] = 1;
}
}else if(grid[row][col] == 0){
if(neighbours == 3){
temp[row][col] = 0;
}else{
temp[row][col] = 1;
}
}
}
}
for(row = 0; row < HEIGHT; row++){
for(col = 0; col < WIDTH; col++){
grid[row][col] = temp[row][col];
printf("%d", grid[row][col]);
}
printf("\n");
}
printf("\n");
}
}
I do notice one problem.
The 4th rule states that a dead cell should become alive again if it has exactly 3 neighbors. Currently, your code does the opposite
else if(grid[row][col] == 0){
if(neighbours == 3){
temp[row][col] = 0;
}else{
temp[row][col] = 1;
}
}
This will leave the cell dead if there are exactly 3 and make it alive when that is not the case. Switch the 1 and the 0 and it should work.
The way you count your neighbors is false (what about -1%HEIGHT for example???). I suppose that you want to use a torus (leftmost column connected to rightmost column and the same for lines), so you need to make special cases for borders. A trick is to use modulus like the following.
Suppose you have a line of length N, then for each x from 0 to N-1, compute mid=x+N, get neighbors as left=mid-1 and right=mid+1, then count neighbors with grid(left%N), grid(mid%N), grid(right%N) (add second dimension the same way of course). So you will catch the torus property without any special cases...
If you want to be sure that it works as expected, I can suggested you to initialize the grid to a well-known GOL pattern (a simple glider for example).
Also verify that the GOL rules are the right ones.
I have a series of if statements that fills an array myArray at a position that depends on the range (multiples of y) in which value x lies in.
I was wondering if there's a simpler way to add off to the correct Array element based on the value of x. x is a function of the current column and row that I iterate over.
for(int i = 0; i< rows; i++)
{
for(int j = 0; j< cols; j++)
{
x = getX(i, j);
if(x < y * 1 && x => 0)
MyArray[0] += off;
if(x < y * 2 && x >= y * 1)
MyArray[1] += off;
if(x < y * 3 && x >= y * 2)
MyArray[2] += off;
if(x < y * 4 && x >= y * 3)
MyArray[3] += off;
if(x < y * 5 && x >= y * 4)
MyArray[4] += off;
}
}
I am assuming that one condition out of the two in each if statement has an '=' (<= or >=). You can then try something like:
int ratio = x/y;
if (ratio >= 0 && ratio < 5)
MyArray[ratio] += off;