I've been trying to do this exercise for a while but i cant seem to find where the problem may lie.
So the exercise goes like this:
We are given a matrix with 1's and 0's with 1 representing islands and 0 representing water
We have to build a code that finds us
The highest(more 1 in y direction)
The widest (more 1 in x direction)
The island with the biggest area
We also have to print the initial coordinates where this island starts(the first 2 are the dimensions of the matrix. the reading is done from a file)
5 6
1 1 0 0 0 0
0 0 1 1 0 0
0 0 1 1 0 1
0 0 0 0 0 1
1 0 1 0 0 1
Here it should print:
Max height 3: coordinates(2,5)
Max width 2: coordinates(0,0) (in case there are many with same width we just print one of
them)
Max area 4:coordinates (1,2)
I have a basic idea on how to do it.
I tried to implement it but i cant seem to understand why its not working. For now im focusing on finding the max height and width. Im sorry in advance for the messy code(i'm a beginner so for now im more focused on solving the problem than making it look pretty)
This is what i have done so far
#include <stdio.h
#include <stdlib.h>
#include <ctype.h>
int main()
{
FILE *file;
file = fopen("file", "r");
int n, m;
int i, j;
fscanf(file, "%d %d", &n, &m);
int v[n][m];
for (i = 0; i < n; i++)
{
for (j = 0; j < m; j++)
{
fscanf(file, "%d", &v[i][j]);
}
}
printf("Original Matrix:\n");
for (i = 0; i < n; i++)
{
for (j = 0; j < m; j++)
{
printf("%d ", v[i][j]);
}
printf("\n");
}
int maxheight = 0;
int height = 0;
int posx;
int posy;
i = 0;
j = 0;
while (i < n && j < m)
{
if (v[i][j] == 1)
{
height++;
i++;
}
else if (v[i][j] != 1)
{
if (maxheight <= height)
{
maxheight = height;
if (maxheight == height)
{
posx = i;
posy = j;
}
}
height = 0;
i++;
}
if (i == n)
{
i = 0;
j++;
height = 0;
}
}
printf("The biggest height =%d in position (%d ,%d)", maxheight, posx, posy);
int width = 0;
int maxwidth = 0;
int posx1;
int posy1;
i = 0;
j = 0;
while (i < n && j < m)
{
if (v[i][j] == 1)
{
width++;
j++;
}
else if (v[i][j] != 1)
{
if (maxwidth <= width)
{
maxwidth = width;
if (maxwidth == width)
{
posx1 = i;
posy1 = j;
}
}
width = 0;
j++;
}
if (j == m)
{
j = 0;
i++;
width = 0;
}
}
printf("\nThe biggest width =%d in position (%d ,%d)", maxwidth, posx1, posy1 - maxwidth);
return 0;
}
Think about the vertical max tests.
In the entire map was 1, codes reports the maxheight as 0.
Code needs to assess maxheight<=height after every height++;, not in the if(v[i][j]!=1) block.
Likewise for width.
Related
so I've been struggling with this example for a good hour now and I can't even begin to process how should I do this.
Write a program that, for given n and m, forms a matrix as described.
The matrix should be m x m, and it's filled "spirally" with it's
beginning in the upper left corner. The first value in the matrix is
the number n. It's repeated until the "edge" of the matrix, at which
point the number increments. After the number 9 goes 0. 0 ≤ n ≤ 9, 0 ≤
m ≤ 9
Some time ago I had made a function to display the numbers 1 to n on an odd-sized grid.
The principle was to start from the center and to shift by ;
x = 1
x box on the right
x box on the bottom
x++
x box on the left
x box at the top
x++
With this simple algorithm, you can easily imagine to maybe start from the center of your problem and decrement your value, it seems easier to start from the center.
Here is the code that illustrates the above solution, to be adapted of course for your problem, it's only a lead.
#define WE 5
void clock(int grid[WE][WE])
{
int count;
int i;
int reach;
int flag;
int tab[2] = {WE / 2, WE / 2}; //x , y
count = 0;
flag = 0;
i = 0;
reach = 1;
grid[tab[1]][tab[0]] = count;
for (int j = 0; j < WE - 1 && grid[0][WE - 1] != pow(WE, 2) - 1; j++)
for (i = 0; i < reach && grid[0][WE - 1] != pow(WE, 2) - 1; i++, reach++)
{
if(flag % 2 == 0)
{
for(int right = 0 ; right < reach ; right++, tab[0]++, count++, flag = 1)
grid[tab[1]][tab[0]] = count;
if(reach < WE - 1)
for(int bottom = 0; bottom < reach; bottom++, count++, tab[1]++)
grid[tab[1]][tab[0]] = count;
}
else
{
for(int left = 0; left < reach; left++, count++, tab[0]--, flag = 0)
grid[tab[1]][tab[0]] = count;
for(int top = 0; top < reach; top++, tab[1]--, count++)
grid[tab[1]][tab[0]] = count;
}
}
}
I finally solved it. If anybody's interested, here's how I did it:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
//Fills the row number "row" with the number n
int fillRow(int m, int n, int arr[m][m], int row)
{
int j;
for(j=0;j<m;j++)
{
if(arr[row][j] == -1 || arr[row][j] == n-1) arr[row][j] = n;
}
}
//Fills the column number "col" with the number n
int fillCol(int m, int n, int arr[m][m], int col)
{
int i;
for(i=0;i<m;i++)
{
if(arr[i][col] == -1 || arr[i][col] == n-1) arr[i][col] = n;
}
}
int main()
{
int n, m, i, j, r=1, c=1, row=-1, col=-1;
scanf("%d %d",&n, &m);
int arr[m][m];
//Fill array with -1 everywhere
for(i=0;i<m;i++)
{
for(j=0;j<m;j++)
{
arr[i][j] = -1;
}
}
//Calculate which row/column to fill (variables row/col)
//Fill row then column then row than column...
for(i=0;i<2*m;i++)
{
if(i%2==0)
{
row = (r%2==0) ? m-r/2 : r/2;
fillRow(m, n, arr, row);
n++;
r++;
}
else if(i%2==1)
{
col = (c%2==0) ? c/2-1 : m-c/2-1;
fillCol(m, n, arr, col);
n++;
c++;
}
}
//If an element is larger than 9, decrease it by 10
//Prints the elements
for(i=0;i<m;i++)
{
for(j=0;j<m;j++)
{
if(arr[i][j]>9) arr[i][j] -=10;
printf("%d ",arr[i][j]);
}
printf("\n");
}
return 0;
}
I want to write a code that gets the integer n from the user and prints numbers in a spiral pattern from 1 to n*n without using arrays.
output for entering 5
input3
output:
1 2 3
8 9 4
7 6 5
do you have any suggestions on how to write this code?
EDIT:
here is the code using arrays:
#include <stdio.h>
int main(){
/*declaration of the variables*/
int i, j, ascendingNumbers;
int leftAndTop, rightAndBottom;
int size;
scanf("%d", &size);
int matrix[size][size];
leftAndTop = 0;
rightAndBottom = size - 1;
ascendingNumbers = 1;
/*filling the array*/
for(i = 1; i <= size/2; i++, leftAndTop++, rightAndBottom--){
/*left to right*/
for(j = leftAndTop; j <= rightAndBottom; j++, ascendingNumbers++){
matrix[leftAndTop][j] = ascendingNumbers;
}
/*top to bottom*/
for(j = leftAndTop + 1; j <= rightAndBottom; j++, ascendingNumbers++){
matrix[j][rightAndBottom] = ascendingNumbers;
}
/*right to left*/
for(j = rightAndBottom-1; j >= leftAndTop; j--, ascendingNumbers++){
matrix[rightAndBottom][j] = ascendingNumbers;
}
/*bottom to top*/
for(j = rightAndBottom - 1; j >= leftAndTop+1; j--, ascendingNumbers++){
matrix[j][leftAndTop] = ascendingNumbers;
}
}
/*fill the center for odd size*/
if(size % 2){
matrix[leftAndTop][j + 1] = ascendingNumbers;
}
/*print*/
for(i = 0; i < size; i++){
for(j = 0; j < size; j++){
printf("%d ", matrix[i][j]);
}
printf("\n");
}
return 0;
}
One solution is to take code that already can fill an array with the spiral pattern, and put it in a nested loop that uses that code to find the number for the current printing position. There are certainly more efficient solutions, but this allows you to transform a solution that works for arrays into one that does not need arrays.
The first program here uses an array to print a spiral pattern of numbers. The second program is a modified version of the first that prints a number when the printing position matches the position in the spiral loop instead of storing it in an array. I'll leave it to you to see if you can modify your existing code to accomplish this.
Using a 2d array:
/* A program that prints a spiral using a 2d array */
#include <stdio.h>
int main(int argc, char *argv[])
{
int size;
if (argc < 2 || (sscanf(argv[1], "%d", &size) != 1) || size < 1) {
fprintf(stderr, "Usage: spiral N [N > 0]\n");
return 1;
}
int arr[size][size];
int num_elems = size * size;
enum Dir { RIGHT, DOWN, LEFT, UP };
int num_directions = 4;
int side_len = size;
int row = 0; // arr row index
int col = 0; // arr column index
int pos = 0; // position in a side
// travel around the spiral to fill the array
enum Dir direction = RIGHT;
for (int i = 0; i < num_elems; i++) {
arr[row][col] = i + 1;
++pos;
if (pos == side_len) { // change direction
direction = (direction + 1) % num_directions;
pos = 0;
// having changed direction, shorten side_len in two cases
if (direction == DOWN || direction == UP) {
--side_len;
}
}
switch (direction) {
case RIGHT:
++col;
break;
case DOWN:
++row;
break;
case LEFT:
--col;
break;
case UP:
--row;
break;
default:
fprintf(stderr, "Unexpected value in switch statement\n");
return 1;
}
}
for (row = 0; row < size; row++) {
for (col = 0; col < size; col++) {
printf("%4d", arr[row][col]);
}
putchar('\n');
}
putchar('\n');
return 0;
}
Using only loops:
/* A program that prints a spiral using loops but no arrays */
#include <stdio.h>
int main(int argc, char *argv[])
{
int size;
if (argc < 2 || (sscanf(argv[1], "%d", &size) != 1) || size < 0) {
fprintf(stderr, "Usage: spiral N [N >= 0]\n");
return 1;
}
int num_elems = size * size;
enum Dir { RIGHT, DOWN, LEFT, UP };
int num_directions = 4;
// loop printing positions: print a row at a time
for (int y = 0; y < size; y++) {
for (int x = 0; x < size; x++) {
int side_len = size; // length of current side
int row = 0; // arr row index
int col = 0; // arr column index
int pos = 0; // position in a side
// travel around spiral until printing number is reached
enum Dir direction = RIGHT;
for (int i = 0; i < num_elems; i++) {
if (row == y && col == x) { // print and escape loop
printf("%4d", i + 1);
break;
}
++pos;
if (pos == side_len) { // change direction
direction = (direction + 1) % num_directions;
pos = 0;
// having changed direction, shorten side_len in two cases
if (direction == DOWN || direction == UP) {
--side_len;
}
}
switch (direction) {
case RIGHT:
++col;
break;
case DOWN:
++row;
break;
case LEFT:
--col;
break;
case UP:
--row;
break;
default:
fprintf(stderr, "Unexpected value in switch statement\n");
return 1;
}
}
}
// newline after row
putchar('\n');
}
// newline after printing all numbers
putchar('\n');
return 0;
}
Here are a couple of sample interactions with the second program:
>$ ./spiral2 3
1 2 3
8 9 4
7 6 5
>$ ./spiral2 6
1 2 3 4 5 6
20 21 22 23 24 7
19 32 33 34 25 8
18 31 36 35 26 9
17 30 29 28 27 10
16 15 14 13 12 11
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");
}
}
I should make new array out of existing one (ex. 1 0 4 5 4 3 1) so that the new one contains digits already in existing array and the number of their appearances.
So, the new one would look like this: 1 2 0 1 4 2 5 1 3 1 (1 appears 2 times, 0 appears 1 time.... 3 appears 1 time; the order in which they appear in first array should be kept in new one also); I know how to count no. of times a value appears in an array, but how do I insert the no.of appearances? (C language)
#include <stdio.h>
#define max 100
int main() {
int b, n, s, i, a[max], j, k;
printf("Enter the number of array elements:\n");
scanf("%d", &n);
if ((n > max) || (n <= 0)) exit();
printf("Enter the array:\n");
for (i = 0; i < n; i++)
scanf("%d", a[i]);
for (i = 0; i < n; i++) {
for (j = i + 1; j < n;) {
if (a[j] == a[i]) {
for (k = j; k < n; k++) {
a[k] = a[k + 1];
}}}}
//in the last 5 rows i've tried to compare elements, and if they are same, to increment the counter, and I've stopped here since I realised I don't know how to do that for every digit/integer that appears in array//
If you know that the existing array consists of digits between 0 and 9, then you can use the index of the array to indicate the value that you are incrementing.
int in[12] = {1,5,2,5,6,5,3,2,1,5,6,3};
int out[10] = {0,0,0,0,0,0,0,0,0,0};
for (int i = 0; i < 12; ++i)
{
++out[ in[i] ];
}
If you provide any code snippet, its easy for the community to help you.
Try this, even you optimize the no.of loops :)
#include <stdio.h>
void func(int in[], int in_length, int *out[], int *out_length) {
int temp[10] = {0}, i = 0, j = 0, value;
//scan the input
for(i=0; i< in_length; ++i) {
value = in[i];
if(value >= 0 && value <= 9) { //hope all the values are single digits
temp[value]++;
}
}
// Find no.of unique digits
int unique_digits = 0;
for(i = 0; i < 10; ++i) {
if(temp[i] > 0)
unique_digits++;
}
// Allocate memory for output
*out_length = 2 * unique_digits ;
printf("digits: %d out_length: %d \n",unique_digits, *out_length );
*out = malloc(2 * unique_digits * sizeof(int));
//Fill the output
for(i = 0, j = 0; i<in_length && j < *out_length; ++i) {
//printf("\n i:%d, j:%d val:%d cout:%d ", i, j, in[i], temp[in[i]] );
if(temp[in[i]] > 0 ) {
(*out)[j] = in[i];
(*out)[j+1] = temp[in[i]];
temp[in[i]] = 0; //Reset the occurrences of this digit, as we already pushed this digit into output
j += 2;
}
}
}
int main(void) {
int input[100] = {1, 0, 4, 5, 4, 3, 1};
int *output = NULL, output_length = 0, i = 0;
func(input, 7, &output, &output_length );
for(i=0; i < output_length; i+=2) {
printf("\n %d : %d ", output[i], output[i+1]);
}
return 0;
}
I am attempting to create a diamond in c with the constraints of only 3 printfs and 3 n\t. this requires me to use loops. I know how to make an upside down triangle and a triangle but cant use that because there are too many printfs. i will attach my code so far. I am aware it does not make a diamond, and some awfully strange shape, but that it what i'm trying to work off and edit to make into a diamond, I just haven't been able to figure it out.
if (type_of_shape == 5)
{
for (i = 0; i < width; i++)
{
for (j = 0;j < ((width - 1) / 2) - i ||(width -1)/2 < i && j + (width-1)/2 < i; j++)
{
printf(" ");
}
for (k = 0;k<width && k < (j*2+1) ; k++)
{
printf("*");
}
printf("\n");
}
}
//int width = 5;
int row, col;
int spaces, stars;
int half, rate;
half = width / 2 + 1;
rate = 1;
for(row = 1; 0 < row && row <= half; row += rate) {
spaces = half - row;
stars = row * 2 -1;
printf("%*s", spaces, "");
for (col = 0; col < stars; col++)
printf("*");
printf("\n");
if(row == half)
rate = -rate;
}
I got it down to a single line which has a single loop, with a single printf statement.
It involved some tricky use of abs.
#include <stdio.h>
#include <stdlib.h>
int main(void) {
int w = 9;
for(int l=0; l < w; ++l) printf("%*.*s\n", abs(w/2 - l)+abs((2*l+1)-(2*l+1>w)*2*w), abs((2*l+1)-(2*l+1>w)*2*w), "**************");
return 0;
}
2 loops (one for, one while).
2 printf statements.
Note:
This works with odd Widths.
An even width produces a diamond with Width+1
My IDEOne code
int main(void)
{
int width = 9;
int layer;
width+=2;
for(layer=0; layer<width/2; ++layer)
{
printf("%*.*s\n", width/2+layer + 1,layer*2 + 1, "**************************");
}
layer--;
while (layer --> 0)
{
printf("%*.*s\n", width/2+layer + 1,layer*2 + 1, "**************************");
}
return 0;
}
Output
Success time: 0 memory: 2168 signal:0
*
***
*****
*******
*********
*******
*****
***
*
Here's a solution with no loops at all. (looping accomplished via recursion), and 3 printf statements:
#include <stdio.h>
void drawDiamond(int width, int stars)
{
static const char* txt = "*****************************";
if (stars == width) {
printf("%*.*s\n",width, width, txt);
return;
}
printf("%*.*s\n", (width+stars)/2, stars, txt);
drawDiamond(width, stars+2);
printf("%*.*s\n", (width+stars)/2, stars, txt);
}
int main(void)
{
drawDiamond(9, 1);
return 0;
}