Skip to content

Commit d694ded

Browse files
authored
Merge branch 'master' into sliding_window_new_algo
2 parents 6aae707 + 7cf568c commit d694ded

12 files changed

+523
-24
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
package com.thealgorithms.geometry;
2+
3+
import java.util.ArrayList;
4+
import java.util.Collection;
5+
import java.util.List;
6+
7+
/**
8+
* Class to represent the Midpoint Circle Algorithm.
9+
* This algorithm calculates points on the circumference of a circle
10+
* using integer arithmetic for efficient computation.
11+
*/
12+
public final class MidpointCircle {
13+
14+
private MidpointCircle() {
15+
// Private Constructor to prevent instantiation.
16+
}
17+
18+
/**
19+
* Generates points on the circumference of a circle using the midpoint circle algorithm.
20+
*
21+
* @param centerX The x-coordinate of the circle's center.
22+
* @param centerY The y-coordinate of the circle's center.
23+
* @param radius The radius of the circle.
24+
* @return A list of points on the circle, each represented as an int[] with 2 elements [x, y].
25+
*/
26+
public static List<int[]> generateCirclePoints(int centerX, int centerY, int radius) {
27+
List<int[]> points = new ArrayList<>();
28+
29+
// Special case for radius 0, only the center point should be added.
30+
if (radius == 0) {
31+
points.add(new int[] {centerX, centerY});
32+
return points;
33+
}
34+
35+
// Start at (radius, 0)
36+
int x = radius;
37+
int y = 0;
38+
39+
// Decision parameter
40+
int p = 1 - radius;
41+
42+
// Add the initial points in all octants
43+
addSymmetricPoints(points, centerX, centerY, x, y);
44+
45+
// Iterate while x > y
46+
while (x > y) {
47+
y++;
48+
49+
if (p <= 0) {
50+
// Midpoint is inside or on the circle
51+
p = p + 2 * y + 1;
52+
} else {
53+
// Midpoint is outside the circle
54+
x--;
55+
p = p + 2 * y - 2 * x + 1;
56+
}
57+
58+
// Add points for this (x, y)
59+
addSymmetricPoints(points, centerX, centerY, x, y);
60+
}
61+
62+
return points;
63+
}
64+
65+
/**
66+
* Adds the symmetric points in all octants of the circle based on the current x and y values.
67+
*
68+
* @param points The list to which symmetric points will be added.
69+
* @param centerX The x-coordinate of the circle's center.
70+
* @param centerY The y-coordinate of the circle's center.
71+
* @param x The current x-coordinate on the circumference.
72+
* @param y The current y-coordinate on the circumference.
73+
*/
74+
private static void addSymmetricPoints(Collection<int[]> points, int centerX, int centerY, int x, int y) {
75+
// Octant symmetry points
76+
points.add(new int[] {centerX + x, centerY + y});
77+
points.add(new int[] {centerX - x, centerY + y});
78+
points.add(new int[] {centerX + x, centerY - y});
79+
points.add(new int[] {centerX - x, centerY - y});
80+
points.add(new int[] {centerX + y, centerY + x});
81+
points.add(new int[] {centerX - y, centerY + x});
82+
points.add(new int[] {centerX + y, centerY - x});
83+
points.add(new int[] {centerX - y, centerY - x});
84+
}
85+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
package com.thealgorithms.geometry;
2+
3+
import java.util.ArrayList;
4+
import java.util.Collection;
5+
import java.util.List;
6+
7+
/**
8+
* The MidpointEllipse class implements the Midpoint Ellipse Drawing Algorithm.
9+
* This algorithm efficiently computes the points on an ellipse by dividing it into two regions
10+
* and using decision parameters to determine the next point to plot.
11+
*/
12+
public final class MidpointEllipse {
13+
14+
private MidpointEllipse() {
15+
// Private constructor to prevent instantiation
16+
}
17+
18+
/**
19+
* Draws an ellipse using the Midpoint Ellipse Algorithm.
20+
*
21+
* @param centerX the x-coordinate of the center of the ellipse
22+
* @param centerY the y-coordinate of the center of the ellipse
23+
* @param a the length of the semi-major axis (horizontal radius)
24+
* @param b the length of the semi-minor axis (vertical radius)
25+
* @return a list of points (represented as int arrays) that form the ellipse
26+
*/
27+
public static List<int[]> drawEllipse(int centerX, int centerY, int a, int b) {
28+
List<int[]> points = new ArrayList<>();
29+
30+
// Handle degenerate cases with early returns
31+
if (a == 0 && b == 0) {
32+
points.add(new int[] {centerX, centerY}); // Only the center point
33+
return points;
34+
}
35+
36+
if (a == 0) {
37+
// Semi-major axis is zero, create a vertical line
38+
for (int y = centerY - b; y <= centerY + b; y++) {
39+
points.add(new int[] {centerX, y});
40+
}
41+
return points; // Early return
42+
}
43+
44+
if (b == 0) {
45+
// Semi-minor axis is zero, create a horizontal line
46+
for (int x = centerX - a; x <= centerX + a; x++) {
47+
points.add(new int[] {x, centerY});
48+
}
49+
return points; // Early return
50+
}
51+
52+
// Normal case: Non-degenerate ellipse
53+
computeEllipsePoints(points, centerX, centerY, a, b);
54+
55+
return points; // Return all calculated points of the ellipse
56+
}
57+
58+
/**
59+
* Computes points of a non-degenerate ellipse using the Midpoint Ellipse Algorithm.
60+
*
61+
* @param points the list to which points will be added
62+
* @param centerX the x-coordinate of the center of the ellipse
63+
* @param centerY the y-coordinate of the center of the ellipse
64+
* @param a the length of the semi-major axis (horizontal radius)
65+
* @param b the length of the semi-minor axis (vertical radius)
66+
*/
67+
private static void computeEllipsePoints(Collection<int[]> points, int centerX, int centerY, int a, int b) {
68+
int x = 0; // Initial x-coordinate
69+
int y = b; // Initial y-coordinate
70+
71+
// Region 1: Initial decision parameter
72+
double d1 = (b * b) - (a * a * b) + (0.25 * a * a); // Decision variable for region 1
73+
double dx = 2.0 * b * b * x; // Change in x
74+
double dy = 2.0 * a * a * y; // Change in y
75+
76+
// Region 1: When the slope is less than 1
77+
while (dx < dy) {
78+
addEllipsePoints(points, centerX, centerY, x, y);
79+
80+
// Update decision parameter and variables
81+
if (d1 < 0) {
82+
x++;
83+
dx += (2 * b * b); // Update x change
84+
d1 += dx + (b * b); // Update decision parameter
85+
} else {
86+
x++;
87+
y--;
88+
dx += (2 * b * b); // Update x change
89+
dy -= (2 * a * a); // Update y change
90+
d1 += dx - dy + (b * b); // Update decision parameter
91+
}
92+
}
93+
94+
// Region 2: Initial decision parameter for the second region
95+
double d2 = b * b * (x + 0.5) * (x + 0.5) + a * a * (y - 1) * (y - 1) - a * a * b * b;
96+
97+
// Region 2: When the slope is greater than or equal to 1
98+
while (y >= 0) {
99+
addEllipsePoints(points, centerX, centerY, x, y);
100+
101+
// Update decision parameter and variables
102+
if (d2 > 0) {
103+
y--;
104+
dy -= (2 * a * a); // Update y change
105+
d2 += (a * a) - dy; // Update decision parameter
106+
} else {
107+
y--;
108+
x++;
109+
dx += (2 * b * b); // Update x change
110+
dy -= (2 * a * a); // Update y change
111+
d2 += dx - dy + (a * a); // Update decision parameter
112+
}
113+
}
114+
}
115+
116+
/**
117+
* Adds points for all four quadrants of the ellipse based on symmetry.
118+
*
119+
* @param points the list to which points will be added
120+
* @param centerX the x-coordinate of the center of the ellipse
121+
* @param centerY the y-coordinate of the center of the ellipse
122+
* @param x the x-coordinate relative to the center
123+
* @param y the y-coordinate relative to the center
124+
*/
125+
private static void addEllipsePoints(Collection<int[]> points, int centerX, int centerY, int x, int y) {
126+
points.add(new int[] {centerX + x, centerY + y});
127+
points.add(new int[] {centerX - x, centerY + y});
128+
points.add(new int[] {centerX + x, centerY - y});
129+
points.add(new int[] {centerX - x, centerY - y});
130+
}
131+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
package com.thealgorithms.maths;
2+
3+
/**
4+
* Calculate Catalan Numbers
5+
*/
6+
public final class CatalanNumbers {
7+
private CatalanNumbers() {
8+
}
9+
10+
/**
11+
* Calculate the nth Catalan number using a recursive formula.
12+
*
13+
* @param n the index of the Catalan number to compute
14+
* @return the nth Catalan number
15+
*/
16+
public static long catalan(final int n) {
17+
if (n < 0) {
18+
throw new IllegalArgumentException("Index must be non-negative");
19+
}
20+
return factorial(2 * n) / (factorial(n + 1) * factorial(n));
21+
}
22+
23+
/**
24+
* Calculate the factorial of a number.
25+
*
26+
* @param n the number to compute the factorial for
27+
* @return the factorial of n
28+
*/
29+
private static long factorial(final int n) {
30+
if (n == 0 || n == 1) {
31+
return 1;
32+
}
33+
long result = 1;
34+
for (int i = 2; i <= n; i++) {
35+
result *= i;
36+
}
37+
return result;
38+
}
39+
}

src/main/java/com/thealgorithms/maths/FindKthNumber.java

+17
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
package com.thealgorithms.maths;
22

3+
import java.util.Collections;
4+
import java.util.PriorityQueue;
35
import java.util.Random;
46

57
/**
@@ -62,4 +64,19 @@ private static void swap(int[] array, int i, int j) {
6264
array[i] = array[j];
6365
array[j] = temp;
6466
}
67+
68+
public static int findKthMaxUsingHeap(int[] array, int k) {
69+
if (k <= 0 || k > array.length) {
70+
throw new IllegalArgumentException("k must be between 1 and the size of the array");
71+
}
72+
PriorityQueue<Integer> maxHeap = new PriorityQueue<>(Collections.reverseOrder()); // using max-heap to store numbers.
73+
for (int num : array) {
74+
maxHeap.add(num);
75+
}
76+
while (k > 1) {
77+
maxHeap.poll(); // removing max number from heap
78+
k--;
79+
}
80+
return maxHeap.peek();
81+
}
6582
}

src/main/java/com/thealgorithms/maths/PerfectSquare.java

+12
Original file line numberDiff line numberDiff line change
@@ -18,4 +18,16 @@ public static boolean isPerfectSquare(final int number) {
1818
final int sqrt = (int) Math.sqrt(number);
1919
return sqrt * sqrt == number;
2020
}
21+
22+
/**
23+
* Check if a number is perfect square or not
24+
*
25+
* @param number number to be checked
26+
* @return {@code true} if {@code number} is perfect square, otherwise
27+
* {@code false}
28+
*/
29+
public static boolean isPerfectSquareUsingPow(long number) {
30+
long a = (long) Math.pow(number, 1.0 / 2);
31+
return a * a == number;
32+
}
2133
}

src/main/java/com/thealgorithms/maths/PronicNumber.java

+14
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,9 @@ private PronicNumber() {
2121
* @return true if input number is a pronic number, false otherwise
2222
*/
2323
static boolean isPronic(int inputNumber) {
24+
if (inputNumber == 0) {
25+
return true;
26+
}
2427
// Iterating from 0 to input_number
2528
for (int i = 0; i <= inputNumber; i++) {
2629
// Checking if product of i and (i+1) is equals input_number
@@ -34,4 +37,15 @@ static boolean isPronic(int inputNumber) {
3437
// equals input_number
3538
return false;
3639
}
40+
41+
/**
42+
* This method checks if the given number is pronic number or non-pronic number using square root of number for finding divisors
43+
*
44+
* @param number Integer value which is to be checked if is a pronic number or not
45+
* @return true if input number is a pronic number, false otherwise
46+
*/
47+
public static boolean isPronicNumber(int number) {
48+
int squareRoot = (int) Math.sqrt(number); // finding just smaller divisor of the number than its square root.
49+
return squareRoot * (squareRoot + 1) == number;
50+
}
3751
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
package com.thealgorithms.geometry;
2+
3+
import static org.junit.jupiter.api.Assertions.assertTrue;
4+
5+
import java.util.List;
6+
import org.junit.jupiter.api.Test;
7+
import org.junit.jupiter.params.ParameterizedTest;
8+
import org.junit.jupiter.params.provider.CsvSource;
9+
10+
/**
11+
* Test class for the {@code MidpointCircle} class
12+
*/
13+
class MidpointCircleTest {
14+
15+
/**
16+
* Parameterized test to check the generated points for different circles.
17+
* The points are checked based on the expected center and radius.
18+
*
19+
* @param centerX The x-coordinate of the circle's center.
20+
* @param centerY The y-coordinate of the circle's center.
21+
* @param radius The radius of the circle.
22+
*/
23+
@ParameterizedTest
24+
@CsvSource({
25+
"0, 0, 3", // Circle centered at (0, 0) with radius 3
26+
"10, 10, 2" // Circle centered at (10, 10) with radius 2
27+
})
28+
void
29+
testGenerateCirclePoints(int centerX, int centerY, int radius) {
30+
List<int[]> points = MidpointCircle.generateCirclePoints(centerX, centerY, radius);
31+
32+
// Ensure that all points satisfy the circle equation (x - centerX)^2 + (y - centerY)^2 = radius^2
33+
for (int[] point : points) {
34+
int x = point[0];
35+
int y = point[1];
36+
37+
int dx = x - centerX;
38+
int dy = y - centerY;
39+
int distanceSquared = dx * dx + dy * dy;
40+
41+
assertTrue(Math.abs(distanceSquared - radius * radius) <= 1, "Point (" + x + ", " + y + ") does not satisfy the circle equation.");
42+
}
43+
}
44+
45+
/**
46+
* Test to ensure the algorithm generates points for a zero-radius circle.
47+
*/
48+
@Test
49+
void testZeroRadiusCircle() {
50+
List<int[]> points = MidpointCircle.generateCirclePoints(0, 0, 0);
51+
52+
// A zero-radius circle should only have one point: (0, 0)
53+
assertTrue(points.size() == 1 && points.get(0)[0] == 0 && points.get(0)[1] == 0, "Zero-radius circle did not generate the correct point.");
54+
}
55+
}

0 commit comments

Comments
 (0)