Skip to content

Commit 697f95f

Browse files
authored
Merge branch 'master' into next_higher_new_algo
2 parents 662e0db + 7cf568c commit 697f95f

15 files changed

+573
-24
lines changed

DIRECTORY.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
* [CountLeadingZeros](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/bitmanipulation/CountLeadingZeros.java)
3232
* [CountSetBits](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/bitmanipulation/CountSetBits.java)
3333
* [FindNthBit](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/bitmanipulation/FindNthBit.java)
34+
* [FirstDifferentBit](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/bitmanipulation/FirstDifferentBit.java)
3435
* [GrayCodeConversion](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/bitmanipulation/GrayCodeConversion.java)
3536
* [HammingDistance](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/bitmanipulation/HammingDistance.java)
3637
* [HigherLowerPowerOfTwo](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/bitmanipulation/HigherLowerPowerOfTwo.java)
@@ -728,6 +729,7 @@
728729
* [CountLeadingZerosTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/bitmanipulation/CountLeadingZerosTest.java)
729730
* [CountSetBitsTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/bitmanipulation/CountSetBitsTest.java)
730731
* [FindNthBitTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/bitmanipulation/FindNthBitTest.java)
732+
* [FirstDifferentBitTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/bitmanipulation/FirstDifferentBitTest.java)
731733
* [GrayCodeConversionTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/bitmanipulation/GrayCodeConversionTest.java)
732734
* [HammingDistanceTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/bitmanipulation/HammingDistanceTest.java)
733735
* [HigherLowerPowerOfTwoTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/bitmanipulation/HigherLowerPowerOfTwoTest.java)
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
package com.thealgorithms.bitmanipulation;
2+
3+
/**
4+
* This class provides a method to find the first differing bit
5+
* between two integers.
6+
*
7+
* Example:
8+
* x = 10 (1010 in binary)
9+
* y = 12 (1100 in binary)
10+
* The first differing bit is at index 1 (0-based)
11+
* So, the output will be 1
12+
*
13+
* @author Hardvan
14+
*/
15+
public final class FirstDifferentBit {
16+
private FirstDifferentBit() {
17+
}
18+
19+
/**
20+
* Identifies the index of the first differing bit between two integers.
21+
* Steps:
22+
* 1. XOR the two integers to get the differing bits
23+
* 2. Find the index of the first set bit in XOR result
24+
*
25+
* @param x the first integer
26+
* @param y the second integer
27+
* @return the index of the first differing bit (0-based)
28+
*/
29+
public static int firstDifferentBit(int x, int y) {
30+
int diff = x ^ y;
31+
return Integer.numberOfTrailingZeros(diff);
32+
}
33+
}
Lines changed: 85 additions & 0 deletions
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+
}
Lines changed: 131 additions & 0 deletions
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+
}
Lines changed: 39 additions & 0 deletions
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

Lines changed: 17 additions & 0 deletions
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

Lines changed: 12 additions & 0 deletions
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

Lines changed: 14 additions & 0 deletions
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
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
package com.thealgorithms.bitmanipulation;
2+
3+
import static org.junit.jupiter.api.Assertions.assertEquals;
4+
5+
import org.junit.jupiter.params.ParameterizedTest;
6+
import org.junit.jupiter.params.provider.CsvSource;
7+
8+
public class FirstDifferentBitTest {
9+
10+
@ParameterizedTest
11+
@CsvSource({"10, 8, 1", "7, 5, 1", "15, 14, 0", "1, 2, 0"})
12+
void testFirstDifferentBit(int x, int y, int expected) {
13+
assertEquals(expected, FirstDifferentBit.firstDifferentBit(x, y));
14+
}
15+
}

0 commit comments

Comments
 (0)