Is there any way to speed up printing arrays? - c

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.

Related

How to Check if Matrix is Circular / Target Matrix?

Enter N (dimension of square matrix) such that N is odd and in interval [1,100]. For entered matrix, check if it is a target matrix: if yes, print YES; if no, print NO.
Target Matrix is a matrix that is organized in concentric circles starting from the centre. Each concentric circle has -1 the value of the previous one. Examples:
and
I've tried approaching this problem by using a while loop to increase the radius which starts at centre increases. inside, I've used two for loops to go through that part and check if the values are according the the rule given above.
I'm not really sure if this is a good approach. Do you have some suggestions?
#include <stdio.h>
#define DIM 100
int main() {
int matrix[DIM][DIM];
int N;
int targetMatrix = 1;
int matrixCenter;
int radius;
do{
printf("Enter N: ");
scanf("%d", &N);
if (N % 2 == 0 || N < 1 || N > 100){
printf("Invalid value of N.\n");
}
} while (N % 2 == 0 || N < 1 || N > 100);
// Matrix Entry
printf("Enter the matrix: ");
int i, j;
for (i = 0; i < N; i++){
for (j = 0; j < N; j++){
scanf("%d", &matrix[i][j]);
}
}
// Value at Center
matrixCenter = matrix[N/2][N/2];
radius = 1;
// (N - 1) / 2 is the distance from center of matrix to its side
while (radius <= (N - 1) / 2)
{
for(i = N/2 - radius; i <= N/2 + radius; i++){
for(j = N/2 - radius; j <= N/2 + radius; j++){
if (i == N/2 && j == N/2) // Center Value
continue;
if (matrix[i][j] != matrixCenter - radius)
targetMatrix = 0;
}
}
if (targetMatrix == 0){
printf("NO: This is not a target matrix"); // If not a target matrix
return 1;
}
radius++;
}
printf("YES: this is a target matrix"); // If it is a target matrix
return 0;
}
Testing shell of submatrix only :
int first = N/2 - radius;
int last = N/2 + radius;
for (int i = first; i <= last;i++) {
// first on last line: increment by one
// other : increment by radius * 2
for (int j = first; j <= last;j += ((i==first)||(i==last) ? 1 :radius*2)) {
// test i,j here
}
}

Drawing filled circle with a matrix in C

I have made a program in C.
What it does or should do is draw a filled circle by displaying values of a matrix.
You can input the values of the radius of the circle, the position of the center of the circle relative to the center of the matrix and the size of the matrix i.e. resolution.
So when it gives values of the cells of the matrix, it checks if the cell (or point) is inside the circle.
For each cell there is a point determined by the variables x and y. When the point is inside the circle, that means that the number that we get by calculating the equation of a circle with the x and y values is less than the radius of the circle squared.
If the point is inside the circle, the program makes the value of the corresponding cell 1. Otherwise it makes it 0.
So in the end it should display the matrix and it should look like a bunch of zeroes and inside there is a filled circle made of ones.
The problem:
The program works, I can type in the values it needs (for example radius is 50, x position is 0, y position is 0 and resolution (matrix size) is 150), but when it is supposed to display the matrix it only prints zeroes.
Is there anything fundamentally wrong with my program? What could cause the problem?
Thanks in advance!
My code:
#include <stdio.h>
int main()
{
float x = 0, y = 0, ypos= 0 , xpos = 0, radius = 0, rsqrd = 0, rcheck = 0;
int matsize = 0, i, j;
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("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];
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
}
y = y-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;
}
You forgot to reset x when decrementing y.
Try this:
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
}
y = y-1;
x -= matsize; // <-- Reset x to start of row
}

Build a simple text square/rectangle using "Xs" and printf

I am trying to build a square/rectangle using "Xs" on a 1:1 scale with the length and width, but the logic seems to be not perfect
void draw (float x, float y) {
int i, j;
int length = (int)x + 0;
int width = (int)y + 0;
for (i = 1; i < length; i++) {
for (j = 1; j < width; j++) {
if (((i = 1) || (i = length)) && ((j = 1) || (j = width))) {
printf("x");
} else {
printf(" ");
}
}
printf("\n");
}
}
The problem is that the loop iterates endlessly printing x's everywhere. I'm expecting Xs to be printed out in either a square or rectangular shape (depending on the length or width).
I see 3 flaws in your logic.
you mix = (assignment) with == comparison.
This is why your loop never ends: you always reset i to 1 with your if (((i = 1) || (i = length)) &...
you're not going far enough with your variables:
if i < length, then you'll never have it reach length and print the bottom line of X's
you can't draw a rectangle because your && in the test (((i = 1) || (i = length)) && ((j = 1) || (j = width))) is too restrictive. It can't work if width different from length.
You must learn the logic by yourself using tutorials:
Here such questions will be discarded by sometime-sad people. But as a welcome, here it is (you can replace y in the second case by x, but I thought it would help you understand):
#include <stdio.h>
#include <string.h>
void draw (float x, float y)
{
int i,j;
int length = (int)x + 0;
int width = (int)y + 0;
for(i=1; i<=length; i++) {
for(j=1;j<=width;j++) {
if(((i==1)||(i==length))) {
printf("x");
} else {
if (((j==1)||(j==width))) {
printf("y");
} else {
printf(" ");
}
}
}
printf("\n");
}
}

Need to find Max, Min, Avg number in Array - no size declared

So I have this array, I need to find the Min, Max, and Average. I have figured out how to get the Max, my code looks right for the minimum but it does not work so I must be missing something. I also need to find the average of the numbers entered. Everything I can find on this only works when you have the size of the array set. I have a max size set for the array but it does not get filled by user input. I have been staring and testing on this for days and still cant figure it out.
I know for the average I need something like (with added declartions at the top), but I cannot figure out how to get it to work:
for (i = 0; i < numOfGrades; i++) {
sum += grades[i];
}
avg = (double) sum / numOfGrades;
Here is the rest of my code:
#include <stdio.h>
int main(){
int grades [100];
int i = 0;
int small, big, input;
printf("Enter a series of grades. When done, enter any number above 100.\n\n");
while (i <= 100) { //while loop to set maximum for array
printf("Enter grade:");
if (scanf("%d", &input) == 1) {
if (input >= 0 && input <=100) {
grades[i] = input; //if good, add to array
i++;
}
else {
printf("\n\nExiting entry.\n");
printf("\n\nGrades entered:\n\n");
i = i - 1;
break; //exiting loop
}
}
}
int x, y;
for (x = 0; x <= i; x++) {
printf("Grade: %d\n", grades[x]); //print array
}
big = small = grades[0];
for (y = 0; y < i; y++) {
if (grades[y] > big) {
big = grades[y];
}
else if (grades[y] < small) {
small = grades[y];
}
}
printf("Highest number : %d\n", big);
printf("Smallest number: %d\n", small);
return 0;
}
Here you do the right thing:
for (x = 0; x <= i; x++) {
Because x <= i will take you from 0 to the value of i. Then in your min/max loop you do this:
for (y = 0; y < i; y++) {
So you are going from 0 to to i-1. You have 2 options:
Make the above loop correct with y <= i.
Dont decrement i in the while loop (Dont do this i = i - 1;) That way, i represents the number of numbers entered, instead of number of numbers entered -1 (you will need to fix the x <= i to x < i).
Here is a live example. http://ideone.com/ZEaDue
To calculate the average, you are doing the right thing, you can re-use i though:
int sum = 0, avg = 0;
for (y = 0; y < i; y++) {
sum += grades[y];
}
avg = (double) sum / i;
printf("Avg: %d\n", avg);
Actually you do have the number of grades
if (scanf("%d", &input) == 1) {
if (input >= 0 && input <=100) {
grades[i] = input; //if good, add to array
i++;
}
else {
numOfGrades=i;
printf("\n\nExiting entry.\n");
printf("\n\nGrades entered:\n\n");
i = i - 1;
break; //exiting loop
}
As for the minimum, your logic should be like this:
for (y = 0; y < numOfEdges; y++) {
if (grades[y] > big) {
big = grades[y];
}
if (grades[y] < small) {
small = grades[y];
}
}
The else statement I removed should do the trick. Also I would always use
for(int var = 0; var < numOfEdges; var++) in any of the loop constructs. It's easyer to follow the logic this way: You have counted the number of edges (numOfEdges), but your loop goes only to numOfEdges-1 since you start with index 0.

C Chomp questions?

I'm trying to create the game Chomp. I am halfway through but pretty stuck.
The game will have 5 different functions. Pointers and structs are not allowed.
This is how far I have come and I have been struggeling with a few problems for a while, but I can't figure out how to solve them by myself so I thought I could get some help here.
BUGS
a) If you first input 2 2 and then input 2 1 it will say that the position already has been eaten, even though it's a perfectly valid position to eat. Instead of checking if the position is != 'O' I should check if it is == 'O', but that won't work either because in the check_move() loop the row and col will not always be an O...
b) If you input a position that is not inside the matrix (i.e. 20 20) you will get two lines of errors. I don't understand why. Of course I only want to display one error, not two.
c) If you input a position that has already been eaten you will get the error "Already been eaten!" several times due to the loop that is looping through the print several times.
QUESTION
a) What is the best way to alternate between Player 1 and Player 2? I thought about an int that will increase by +1 every time a player makes a valid move. Then I will check if the value of the int is odd or even. Odd = Player 1 and even = Player 2 or vice verca. But that won't work because I'm not allowed to have any more global variables than I currently has. And I'm only allowed to return one value from one function (check_move()).
#include <stdio.h>
int height = 4;
int width = 10;
char matrix[4][10];
void initialize()
{
for(int row = 0; row < height; row++)
for(int col = 0; col < width; col++)
matrix[row][col] = 'O';
}
void print_board()
{
printf("\n\n");
for(int row = 0; row < height; row++)
{
for(int col = 0; col < width; col++)
{
printf("%c", matrix[row][col]);
}
printf("\n");
}
printf("\n\n");
}
void get_move(int player, int input[])
{
printf("Player %d, make your move: ", player);
scanf("%d %d", &input[0], &input[1]);
}
int check_move(int position[])
{
int row = position[0];
int col = position[1];
int status = 1;
if(row <= height && col <= width)
{
for(row; row <= height; row++)
{
for(col; col <= width; col++)
{
// Checks if position already has been eaten
if(matrix[row-1][col-1] != 'O')
{
printf("Already eaten!\n");
status = 0;
}
}
}
}
else if(row >= height || col >= width)
{
printf("Your move must be inside the matrix!\n");
status = 0;
}
return status;
}
void update_board(int x, int y)
{
for(int xi = x; xi <= 10; ++xi)
{
for(int yi = y; yi <= 10; ++yi)
matrix[xi-1][yi-1] = ' ';
}
}
int main(void)
{
int player = 1;
int position[2];
initialize();
print_board();
while(1){
get_move(player, position);
check_move(position);
while(check_move(position) != 1)
{
printf("Try again!\n\n");
get_move(player, position);
}
update_board(position[0], position[1]);
print_board();
}
getchar();
getchar();
getchar();
return 0;
}
Bug a and c:
Your check_move function is wrong, you should only test if the position played is eaten or not, the status of the other positions are not relevant:
int check_move(int pos[])
{
if(pos[0] < 1 || pos[0] > height || pos[1] < 1 || pos[1] > width)
{
printf("Your move must be inside the matrix!\n");
return 0;
}
if(matrix[ pos[0] - 1 ][ pos[1] - 1 ] != 'O' ) {
printf("Already eaten!\n");
return 0;
}
return 1;
}
Bug b:
You get the error message twice because you're calling check_move twice in your main:
check_move(position);
while(check_move(position) != 1)
Just remove the useless first call to check_move().
Question a:
You can switch between players by updating the variable player inside your main :
player = (player + 1) % maxNumberOfPlayer;
This will go from 0 to maxNumberOfPlayer - 1, so you may use printf("Player %d, make your move: ", player + 1); for a more user-friendly output. Also, if maxNumberOfPlayer = 2, player = (player + 1) % 2; is equivalent to player = !player.
In main, inside your while loop just add:
player = !player;
Which will toggle player between 0 and 1.

Resources