How to find out if the largest rectangle contains other rectangles inside - c

It is necessary to create N rectangles using two upper left and bottom right points. Then find the area of the largest rectangle (rectangle with the largest area = biggest rectangle) and determine whether other rectangles are inside the largest one if not, then display the appropriate message.
I've already have code which generates N rectangles and determines the largest area among them, but the main problem is to find out if there are smaller rectangles in the biggest one.
Let's simulate the situation:
Rectangle 1 A - (topLeft.x topLeft.y) , B - (botRight.x botRight.y)
Rectangle 2 C - (topLeft.x topLeft.y) , D - (botRight.x botRight.y)
If a rectangle contains another rectangle, then
A(y)>C(y) && A(x)<C(x) && B(y)<D(y) && B(x)>D(y)
Looks easy, but how to implement this algorithm for 20 rectangles, for instance?
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define N 20
struct Point {
int x;
int y;
};
struct Rectangle {
struct Point topLeft;
struct Point botRight;
int area;
};
int Area(const struct Rectangle* r)
{
int length, breadth;
length = r->botRight.x - r->topLeft.x;
if (length <= 0)
exit(1);
breadth = r->topLeft.y - r->botRight.y;
if (breadth <= 0)
exit(2);
return length * breadth;
}
int genRec(struct Rectangle* rec);
int main(void)
{
srand(time(NULL));
int maxarea = 0;
int maxidx = 0;
struct Rectangle rec[N];
for (int i = 0; i < N; i++) {
printf("\n");
printf("\t----------RECTANGLE %d----------\n", i + 1);
int area = genRec(&rec[i]);
if (area > maxarea) {
maxarea = area;
maxidx = i;
}
}
printf("\n");
printf("\tMaximum area is %d in Rectangle %d\n", maxarea, maxidx + 1);
return 0;
}
void genPair(int* lo, int* hi)
{
while (1) {
*lo = -50 + rand() % 101;
*hi = -50 + rand() % 101;
if (*lo < *hi)
break;
}
}
int genRec(struct Rectangle* rec)
{
genPair(&rec->topLeft.x, &rec->botRight.x);
genPair(&rec->botRight.y, &rec->topLeft.y);
printf("\tTop left point is x = %d y = %d\n",
rec->topLeft.x, rec->topLeft.y);
printf("\tBottom right point is x = %d y = %d\n",
rec->botRight.x, rec->botRight.y);
int area = Area(rec);
printf("\tArea is %d\n", area);
return area;
}

Related

Memory Limit exceedeed. For the Dijkstra algorithm based on the binary heap

trying to implement a Dijkstra algorithm for my homework.
Faced the "Memory Limit exceedeed" error.
Please tell me what I'm doing wrong.
Memory limit: 8 Mb
Statement You are to write a program that receives a weighted directed graph and finds all distances from fixed vertex S to all
other vertices. Distance from S to some vertex W is the minimal length
of path going from S to W. Length of path is the sum of weights of its
arcs.
Input file contains two integers N, M and S. Vertices are numbered
with integer numbers from 1 to N. S is the number of source vertex. M
is the number of arcs. Each of next M lines contain three integers —
numbers of starting and ending vertices of some arc and its weight
respectively. All weights are positive. There is at most one arc
connecting two vertices in every direction.
Output file must contain N numbers. Each I-th number is the distance
from vertex S to vertex I. If some vertices are not reachable from S,
corresponding numbers must be −1.
Constraints 1 ≤ N, M ≤ 100000 All weights are less or equal 1000.
Sample test:
5 3 1
1 2 5
1 3 7
3 4 10
Out: 0 5 7 17 -1
My programm:
#include <stdio.h>
#include <stdlib.h>
#define INF 100001
typedef enum {max, min} Heap_type;
typedef struct {
Heap_type type;
int *data, size;
} Heap;
Heap init_heap(Heap_type type, int size){
Heap * heap = (Heap*)malloc(sizeof(Heap));
if (heap!=NULL)
{
heap->data = (int *) malloc(size * sizeof(int));
heap->type = type;
heap->size = 0;
}
return *heap;
}
void swap(int *a, int *b){
int tmp = *a;
*a = *b;
*b = tmp;
}
void sift_up(Heap *heap, int id){
heap->size++;
while(heap->type == max ? (heap->data[id] > heap->data[(id - 1) / 2]) : (heap->data[id] < heap->data[(id - 1) / 2])){
swap(&(heap->data[id]), &(heap->data[(id - 1) / 2]));
id = (id - 1) / 2;
}
}
void sift_down(Heap *heap, int id){
int child_l, child_r, child_tmp;
while(2 * id + 1 < heap->size){
child_l = 2 * id + 1;
child_r = 2 * id + 2;
child_tmp = child_l;
if(child_r < heap->size)
if(heap->type == max ? heap->data[child_r] > heap->data[child_l] : heap->data[child_r] < heap->data[child_l])
child_tmp = child_r;
if(heap->type == max ? heap->data[id] >= heap->data[child_tmp] : heap->data[id] <= heap->data[child_tmp])
break;
swap(&(heap->data[id]), &(heap->data[child_tmp]));
id = child_tmp;
}
}
void push(Heap *heap, int num){
heap->data[heap->size] = num;
sift_up(heap, heap->size);
}
int get_root(Heap *heap){
int root = heap->data[0];
heap->size--;
heap->data[0] = heap->data[heap->size];
sift_down(heap, 0);
return root;
}
void fast_dijkstra(int s, int *d, int n, int m, int **W, Heap pq){
for (int i = 0; i<n; i++)
d[i] = INF;
d[s] = 0;
push(&pq, s);
while (pq.size){
int v = get_root(&pq);
for(int u = 0; u<n; ++u) {
if (W[v][u] && (d[v] + W[v][u]) < d[u]) {
d[u] = d[v] + W[v][u];
push(&pq, u);
}
}
}
}
int main() {
FILE *inp = fopen("input.txt", "r"),
*out = fopen("output.txt", "w");
int N, M, S;
fscanf(inp, "%d %d %d", &N, &M, &S);
S -= 1;
int **W = (int **)malloc(N*sizeof(int *));
for(int i = 0; i < N; i++) {
W[i] = (int *)calloc(N, sizeof(int));
}
for (int _=M; _; _--){
int from, to, path;
fscanf(inp,"%d %d %d", &from, &to, &path);
W[from - 1][to - 1] = path;
}
Heap pq = init_heap(min,N);
int d[N];
fast_dijkstra(S, d, N, M, W, pq);
for (int i = 0; i<N; ++i)
fprintf(out, "%d ", d[i] != INF ? d[i] : -1);
return 0;
}

Small Triangles, Large Triangles code not working

So, I had been trying to write the code for the Small Triangles, Large Triangles problem of C in Hackerrank. Before, I state what problem I'm facing, I'll attach the question-
I only wrote the sort_by_area, swap and area functions here. The rest of it was given and unchangeable. The code I've written is getting executed properly but the structures aren't getting sorted correctly. Here is the expected output & my output-
I just cannot figure out why it is getting such weirdly swapped. If anyone could help, would mean a lot.
My code is-
#include <stdlib.h>
#include <math.h>
struct triangle
{
int a;
int b;
int c;
};
typedef struct triangle triangle;
void sort_by_area(triangle* tr, int n) {
int i, j, swapped;
for (i = 0; i < n-1; i++)
{
swapped = 0;
for (j = 0; j < n-i-1; j++)
{
if (area(tr[j].a, tr[j].b, tr[j].c) > area(tr[j+1].a, tr[j+1].b, tr[j+1].c))
{
swap(&tr[j], &tr[j+1]);
swapped = 1;
}
}
if (swapped == 0)
break;
}
}
void swap(struct triangle **xp, struct triangle **yp)
{
struct triangle *temp = *xp;
*xp = *yp;
*yp = temp;
}
int area(int a, int b, int c){
int p=(a+b+c)/2;
int q=p*(p-a)*(p-b)*(p-c);
return sqrt(q);
}
int main()
{
int n;
scanf("%d", &n);
triangle *tr = malloc(n * sizeof(triangle));
for (int i = 0; i < n; i++) {
scanf("%d%d%d", &tr[i].a, &tr[i].b, &tr[i].c);
}
sort_by_area(tr, n);
for (int i = 0; i < n; i++) {
printf("%d %d %d\n", tr[i].a, tr[i].b, tr[i].c);
}
return 0;
}```
Enable all warnings
This quickly led to swap() swapping pointers and not data.
// Corrected - swap data
void swap(struct triangle *xp, struct triangle *yp) {
struct triangle temp = *xp;
*xp = *yp;
*yp = temp;
}
Function order
Move area(), swap() definitions before calling them.
Area
(int) sqrt(q) may return the same value for different qs.
Example: (int) sqrt(100), (int) sqrt(110), (int) sqrt(120)
All return 10. Sorting will not certainly sort according to area.
Simple return the square of the area. Mathematically, sorting by area squared same as area.
int area_squared(int a, int b, int c){
int p=(a+b+c)/2;
int q=p*(p-a)*(p-b)*(p-c);
// return sqrt(q);
return q;
}
Although one could code using double, let us stay with integers.
Watch out for a+b+c as odd as odd/2 forms a truncated quotient.
Perhaps return the square of the area, scaled each side by 2?
int area_squared2(int a, int b, int c){
a *= 2; b *= 2; c *= 2;
// a+b+c is certianly even
int p=(a+b+c)/2;
int q=p*(p-a)*(p-b)*(p-c);
return q;
}
A remaining concern is int overflow. Consider long long math.
long long area_squared2LL(int a, int b, int c){
long long aa = a * 2LL;
long long bb = b * 2LL;
long long cc = c * 2LL;
long long pp = (aa+bb+cc)/2;
long long qq = pp*(pp-aa)*(pp-bb)*(pp-cc);
return qq;
}
Tip: Allocate by referenced data, not type
Easier to code right, review and maintain.
// triangle *tr = malloc(n * sizeof(triangle));
triangle *tr = malloc(sizeof *tr * n);
if (tr == NULL) {
// use tr
...
free(tr);
tr = NULL;
}

No Output - The program doesn't give any output

I am learning data structures. I tried to write a function rotate(arr[], d, n) that rotates arr[] of size n by d elements.
By rotate I mean shifting the elements in an array.
The program doesn't give any error, rather it hangs a bit but it doesn't run.
Here's the code: -
#include <stdio.h>
int rotate(int arr[], int d, int n, int dir)
{
int temp, i;
while (d)
{
if (dir)
{
// for left shift
// First element will always get replaced in a rotation.
temp = arr[0];
for (i = 0; i < n - 1; i++)
// for left shifting the second element next to its original position.
arr[i] = arr[i + 1];
// Putting the temp value in the last position.
arr[n - 1] = temp;
}
else
{
// for right shift
// Last element will always get replaced in a rotation.
temp = arr[n - 1];
for (i = n - 1; i > 0; i--)
// for right shifting the second last element to the last position.
arr[i] = arr[i - 1];
// Putting the temp value in the first position
arr[0] = temp;
}
d--;
}
// Print the shifted array
for (i = 0; i < n; i++)
{
printf("%d, ", arr[i]);
}
}
The program only runs when I don't take inputs from the user.
int main()
{
int n;
int arr[n];
int dir;
int d;
printf("Enter the size of the array: \n");
scanf("%d", &n);
printf("Enter the elements of the array: \n");
for (int i = 1; i <= n; i++)
{
printf("Enter element %d", i);
scanf("%d", &arr[i]);
}
printf("Enter the position: \n");
scanf("%d", &d);
printf("Enter the direction: \n");
// 0: Right Direction and 1: Left Direction
scanf("%d", &dir);
// Before shifting the array
for (int i = 1; i <= n; i++)
{
printf("%d, ", arr[i]);
}
// After shifting the array
rotate(arr, d, n, dir);
return 0;
}
You might want to do int arr[n] after scanf("%d", &n); because n is not initialized when you do int arr[n]. Also array indexing in C starts from 0 so for (int i = 1; i <= n; i++) will be for (int i = 0; i < n; i++).
This is not a proper answer, so do not accept it as the correct answer. It is just a possible implementation for educational purposes.
Here is a way to rotate the array so that each element is moved only once (except that the first element of a "group" is moved via a temporary variable).
The rotation amount is specified as an integer with positive values rotating right and negative values rotating left. It converts this amount into a number in the range 0 to n-1 which is the index of the element that will be copied to element 0. It then divides the array into one or more interleaved groups of the same size such that successive elements in each group are separated by the rotation amount in a circular fashion, and rotates the elements within each group. (The number of groups is the greatest common divisor of n and the rotation amount, and the number of elements in each group is the total number of elements divided by the number of groups.)
#include <limits.h>
#include <stddef.h>
static size_t rotate_modulus(int d, size_t n);
static size_t gcd_size(size_t a, size_t b);
/* Rotate arr[] of length n right by d, or left by -d. */
void rotate(int arr[], int d, size_t n)
{
size_t md = rotate_modulus(d, n); /* Get offset in range 0 to n-1. */
if (md)
{
/* Rotation needed. */
/* Divide into interleaved groups and rotate each group. */
size_t num_groups = gcd_size(n, md);
size_t group_size = n / num_groups;
size_t group;
for (group = 0; group < num_groups; group++)
{
size_t a = group; /* Index of first element in group. */
size_t i;
/* Rotate elements in group. */
int temp = arr[a]; /* Get first element. */
for (i = 0; i < group_size - 1; i++)
{
/* Get index of next element in group. */
size_t b = (a + md);
if (a >= n - md)
{
b -= n; /* Index wraps around. */
}
arr[a] = arr[b]; /* Move an element. */
a = b; /* Advance to next index. */
}
arr[a] = temp; /* Move first element to last element. */
}
}
}
/*
* Get modulus for rotation of n elements.
*
* d is the amount to rotate right; negative d rotates left by -d.
*
* For zero n, the return value is 0.
*
* For non-zero n, the return value is n - s, where s is d plus an
* integer multiple of n such that s is in the range 1 to n, and the
* return value is in the range 0 to n - 1.
*/
static size_t rotate_modulus(int d, size_t n)
{
size_t md;
if (n < 2)
{
/* No rotation needed if n < 2. */
md = 0;
}
else if (d >= 0)
{
/* Non-negative d will rotate right. */
md = d % n;
if (md)
{
md = n - md;
}
}
else
{
/* Negative d will rotate left. */
/* -d would overflow if d == INT_MIN && INT_MIN == -INT_MAX - 1. */
int fix_overflow = (d < -INT_MAX);
md = -(d + fix_overflow) % n;
if (fix_overflow)
{
if (++md == n)
{
md = 0;
}
}
}
return md;
}
/*
* If both a and b are non-zero, return the greatest common divisor of a and b.
* Otherwise, return 0.
*/
static size_t gcd_size(size_t a, size_t b)
{
if (b == 0)
{
a = 0;
}
else
{
do
{
size_t t = b;
b = a % b;
a = t;
}
while (b);
}
return a;
}

Closest pair of four points c program

I need to find closest pair of four points C program. This code for three points. I need this solution for four point.
I tried this. This solution for three input.
When I entering the three points then I will get the closest but I need the closest point of four points.
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
struct Point
{
int x, y ;
};
double getDistanceAB(struct Point a, struct Point b)
{
double distanceAB;
distanceAB = sqrt((a.x - b.x) * (a.x - b.x) + (a.y-b.y) *(a.y-b.y));
return distanceAB;
}
double getDistanceBC(struct Point b, struct Point c)
{
double distanceBC;
distanceBC = sqrt((b.x - c.x) * (b.x - c.x) + (b.y-c.y) *(b.y-c.y));
return distanceBC;
}
double getDistanceAC(struct Point a, struct Point c)
{
double distanceAC;
distanceAC = sqrt((a.x - c.x) * (a.x - c.x) + (a.y-c.y) *(a.y-c.y));
return distanceAC;
}
int main()
{
struct Point a, b, c;
printf("Enter coordinate of points a: ");
scanf("%d %d", &a.x, &a.y);
printf("Enter coordinate of points b: ");
scanf("%d %d", &b.x, &b.y);
printf("Enter coordinate of points c: ");
scanf("%d %d", &c.x, &c.y);
if((getDistanceAB(a,b))>(getDistanceBC(b,c)) && (getDistanceAB(a,b))>(getDistanceBC(a,c)))
{
printf("Point A and B are closest.");
}
else if((getDistanceBC(b,c))>(getDistanceAC(a,c)) && (getDistanceBC(b,c))>(getDistanceAC(a,b)))
{
printf("Point B and C are closest.");
}
else if((getDistanceBC(a,c))>(getDistanceAC(a,b)) && (getDistanceBC(a,c))>(getDistanceAC(b,c)))
{
printf("Point A and C are closest.");
}
else
{
printf("All point are same.");
}
}
First, change this:
double getDistanceAB(struct Point a, struct Point b)
{
double distanceAB;
distanceAB = sqrt((a.x - b.x) * (a.x - b.x) + (a.y-b.y) *(a.y-b.y));
return distanceAB;
}
double getDistanceBC(struct Point b, struct Point c)
{
double distanceBC;
distanceBC = sqrt((b.x - c.x) * (b.x - c.x) + (b.y-c.y) *(b.y-c.y));
return distanceBC;
}
double getDistanceAC(struct Point a, struct Point c)
{
double distanceAC;
distanceAC = sqrt((a.x - c.x) * (a.x - c.x) + (a.y-c.y) *(a.y-c.y));
return distanceAC;
}
to just this:
double getDistance(struct Point a, struct Point b)
{
double distance;
distance = sqrt((a.x - b.x) * (a.x - b.x) + (a.y-b.y) * (a.y-b.y));
return distance;
}
One of the main points of functions is that you don't have to repeat code.
Now all you have to do is create your four points by adding one more scan for the fourth point and add that to the decision tree.
Keep in mind this for the decision tree that you made... If you check if point 'a' is not the closest using the same logic you used in your original post, you don't have to compare point 'a' again.
I would reduce the number of functions to just double getDistance(struct Point p, struct Point o)
and keep your points in a list so you can allow the program to run through the points dynamically instead of programming each condition.
Once you have your points in a list, you can run a loop that checks each pair in the list for their distance and check that against the currently shortest distance; and if the distance of the pair checked is closer you change the currently shortest distance to the checked pair and which pair of points have that distance.
That way you can expand it to work for arbitrarily large number of points.
I'm not used to the syntax of C, but for the checking of points in the list you'll need a double for loop, in which the first goes through each point in the list, and the second checks the distance from/to that first point to all points later in the list.
for i = 0, i++, length(listOfPoints) {
for j = i+1, j++, length(listOfPoints) {
getDistance(listOfPoints[i], listOfPoints[j]
}
}
Hope this helps some.
This is how I'd solve that,
#include <stdio.h>
typedef struct
{
int x;
int y;
} Point;
int square(int x) { return x * x; }
int distanceSq(Point *a, Point *b)
{
return square(a->x - b->x) + square(a->y - b->y);
}
int main(int argc, char const *argv[])
{
int n = 4;
Point a[4];
for (int i = 0; i < n; i++)
{
printf("Enter Point %d <as x y>: ", i + 1);
scanf("%d %d", &a[i].x, &a[i].y);
}
int distance = __INT_MAX__;
int p1 = -1, p2 = -1;
for (int i = 0; i < n - 1; i++)
for (int j = i + 1; j < n; j++)
{
int current = distanceSq(&a[i], &a[j]);
if (current < distance)
{
p1 = i;
p2 = j;
distance = current;
}
}
printf("The closest points are [%d %d] and [%d %d]", a[p1].x, a[p1].y, a[p2].x, a[p2].y);
return 0;
}
Note:
This can be extended for n number of points
Gives us the first pair closest points
we do not need to take square roots since if the square is large the square root will be proportionally large( in case of a large number(n) of points it might save computation time)
Here you go, a solution for any number of points.
Just change MAX_POINTS to anything you might need.
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <stdbool.h>
#define MAX_POINTS (4U)
struct Point
{
int x;
int y;
};
struct PointPair
{
struct Point a;
struct Point b;
};
double getDistance(const struct PointPair pair)
{
return sqrt((pair.a.x - pair.b.x) * (pair.a.x - pair.b.x) +
(pair.a.y - pair.b.y) * (pair.a.y - pair.b.y));
}
void readPoints(struct Point points[const])
{
for (unsigned i = 0; i < MAX_POINTS; i++)
{
printf("Enter coordinate of point %u: ", i);
scanf("%d %d", &(points[i].x), &(points[i].y));
}
}
bool checkForShorterDistance(const struct PointPair pair, double *const p_minDistance)
{
double tempDistance = getDistance(pair);
if (tempDistance < *p_minDistance)
{
*p_minDistance = tempDistance;
return true;
}
return false;
}
struct PointPair getClosestPair(const struct Point points[const])
{
struct PointPair result =
{
.a = points[0],
.b = points[1]
};
double minDistance = getDistance(result);
struct PointPair tempPair;
unsigned i, j;
for (i = 0; i < MAX_POINTS; i++)
{
tempPair.a = points[i];
for (j = 0; j < MAX_POINTS; j++)
{
if (i == j)
{
continue;
}
tempPair.b = points[j];
if (checkForShorterDistance(tempPair, &minDistance))
{
result = tempPair;
}
}
}
return result;
}
int main(void)
{
struct Point points[MAX_POINTS];
readPoints(points);
struct PointPair pair = getClosestPair(points);
printf("Closest pair is (%d, %d) and (%d, %d)\n",
pair.a.x,
pair.a.y,
pair.b.x,
pair.b.y);
return 0;
}

Print the Cantor Set using recursion in C

I'm trying to print the Cantor Set to the console using 'x', but I'm stuck at the 2nd recursion which no matter what I do, just doesn't execute.
The Idea is to first initialize the matrix using clearP() so I don't have to worry about the whitespaces. After that I load the array with 'x' chars using the depth as a [y] value.
To remove the middle segment on each line I use secondLength and smallerLength. Now the reason to use 2 recursive calls is, that for example on depth 1 it removes the middle part once, on depth 2 twice, on depth 3 four times and so on. However I just can't get the 2nd recursion to execute, which is why my output looks like this.
Any advice where I'm making mistakes?
#include <stdio.h>
#include <math.h>
#define WIDTH 27
#define HEIGHT (int)(cbrt(WIDTH)+1)
void clearP(char p[WIDTH][HEIGHT]){
int x, y;
for(x = 0; x<WIDTH; x++){
for (y=0;y<HEIGHT;y++){
p[x][y] = ' ';
}
}
}
void printP(char p[WIDTH][HEIGHT]){
int x, y;
for(y = 0; y<HEIGHT; y++){
for (x=0;x<WIDTH;x++){
printf("%c",p[x][y]);
}
printf("\n");
}
}
void cantor(char p[WIDTH][HEIGHT],int start,int end, int depth){
int smallerLength = end / 3;
int secondStart = start + (smallerLength * 2);
for (int x = start; x<end ; x++){
p[x][depth] = 'x';
}
if (depth == HEIGHT){
return;
}
cantor(p, start, smallerLength, depth+1);
cantor(p, secondStart, smallerLength, depth+1);
}
int main(){
char canvas[WIDTH][HEIGHT];
clearP(canvas);
cantor(canvas, 0, WIDTH, 0);
printP(canvas);
}
I think you got your height and width mixed up in print.
try this
void printP(char p[WIDTH][HEIGHT]){
int x, y;
for(x = 0; x<HEIGHT; x++){
for (y=0;y<WIDTH;y++){
printf("%c",p[x][y]);
}
printf("\n");
}
}
A point in [0, 1] is in the Cantor set if it's ternary representation doesn't contain any 1's (that is, only 0's and 2's). This observation allows you to output the d-level representation by looking at the first d digits of the fractional part of i/n in base 3, without needing arrays.
#include <stdio.h>
void cantor(int n, int d) {
for (int i = 0; i < n; i++) {
int in = 1;
int x = i;
for (int j = 0; j < d; j++) {
in = in && !(3*x >= n && 3*x < 2*n);
x = (3*x)%n;
}
putchar(in ? 'x' : ' ');
}
putchar('\n');
}
int main(int argc, char *argv[]) {
for (int d = 0; d < 5; d++) {
cantor(81, d);
}
return 0;
}

Resources