From 9bc6bf3812b137e1e0e44aa71946d8f8c7c94a8b Mon Sep 17 00:00:00 2001
From: Hardik Pawar
Date: Sun, 5 Oct 2025 13:11:59 +0530
Subject: [PATCH 1/7] refactor: Enhance docs, code, add tests in
`SkylineProblem`
---
.../thealgorithms/others/SkylineProblem.java | 220 ++++++++++++------
.../others/SkylineProblemTest.java | 131 +++++++----
2 files changed, 233 insertions(+), 118 deletions(-)
diff --git a/src/main/java/com/thealgorithms/others/SkylineProblem.java b/src/main/java/com/thealgorithms/others/SkylineProblem.java
index e84a5c5b585b..7a807c072177 100644
--- a/src/main/java/com/thealgorithms/others/SkylineProblem.java
+++ b/src/main/java/com/thealgorithms/others/SkylineProblem.java
@@ -1,17 +1,45 @@
+
package com.thealgorithms.others;
import java.util.ArrayList;
+import java.util.List;
+import java.util.Objects;
/**
- * The {@code SkylineProblem} class is used to solve the skyline problem using a
- * divide-and-conquer approach.
- * It reads input for building data, processes it to find the skyline, and
- * prints the skyline.
+ * Skyline Problem
+ *
+ * Solves the classic skyline problem using a divide-and-conquer approach. Given
+ * a list of buildings (each defined by left, height, right),
+ * computes the silhouette (skyline) formed by these buildings when viewed from
+ * a distance.
+ *
+ *
+ * Usage example:
+ *
+ *
+ * SkylineProblem sp = new SkylineProblem();
+ * sp.building = new SkylineProblem.Building[3];
+ * sp.add(1, 10, 5);
+ * sp.add(2, 15, 7);
+ * sp.add(3, 12, 9);
+ * List skyline = sp.findSkyline(0, 2);
+ *
+ *
+ *
+ * This class is not thread-safe.
+ *
*/
public class SkylineProblem {
- Building[] building;
- int count;
+ /**
+ * Array of buildings to process. Must be initialized before use.
+ */
+ public Building[] building;
+
+ /**
+ * Number of buildings added so far.
+ */
+ public int count;
/**
* Adds a building with the given left, height, and right values to the
@@ -20,8 +48,23 @@ public class SkylineProblem {
* @param left The left x-coordinate of the building.
* @param height The height of the building.
* @param right The right x-coordinate of the building.
+ * @throws IllegalArgumentException if left >= right or height < 0
+ * @throws IllegalStateException if building array is not initialized or is
+ * full
*/
public void add(int left, int height, int right) {
+ if (building == null) {
+ throw new IllegalStateException("Building array not initialized");
+ }
+ if (count >= building.length) {
+ throw new IllegalStateException("Building array is full");
+ }
+ if (left >= right) {
+ throw new IllegalArgumentException("Left coordinate must be less than right coordinate");
+ }
+ if (height < 0) {
+ throw new IllegalArgumentException("Height must be non-negative");
+ }
building[count++] = new Building(left, height, right);
}
@@ -29,92 +72,97 @@ public void add(int left, int height, int right) {
* Computes the skyline for a range of buildings using the divide-and-conquer
* strategy.
*
- * @param start The starting index of the buildings to process.
- * @param end The ending index of the buildings to process.
+ * @param start The starting index of the buildings to process (inclusive).
+ * @param end The ending index of the buildings to process (inclusive).
* @return A list of {@link Skyline} objects representing the computed skyline.
+ * @throws IllegalArgumentException if indices are out of bounds or building
+ * array is null
*/
- public ArrayList findSkyline(int start, int end) {
+ public List findSkyline(int start, int end) {
+ if (building == null) {
+ throw new IllegalArgumentException("Building array is not initialized");
+ }
+ if (start < 0 || end >= count || start > end) {
+ throw new IllegalArgumentException("Invalid start or end index");
+ }
// Base case: only one building, return its skyline.
if (start == end) {
- ArrayList list = new ArrayList<>();
+ List list = new ArrayList<>();
list.add(new Skyline(building[start].left, building[start].height));
- list.add(new Skyline(building[end].right, 0)); // Add the end of the building
+ list.add(new Skyline(building[start].right, 0)); // Add the end of the building
return list;
}
int mid = (start + end) / 2;
-
- ArrayList sky1 = this.findSkyline(start, mid); // Find the skyline of the left half
- ArrayList sky2 = this.findSkyline(mid + 1, end); // Find the skyline of the right half
+ List sky1 = this.findSkyline(start, mid); // Find the skyline of the left half
+ List sky2 = this.findSkyline(mid + 1, end); // Find the skyline of the right half
return this.mergeSkyline(sky1, sky2); // Merge the two skylines
}
/**
* Merges two skylines (sky1 and sky2) into one combined skyline.
*
- * @param sky1 The first skyline list.
- * @param sky2 The second skyline list.
+ * @param sky1 The first skyline list. Not modified.
+ * @param sky2 The second skyline list. Not modified.
* @return A list of {@link Skyline} objects representing the merged skyline.
+ * @throws NullPointerException if either argument is null
*/
- public ArrayList mergeSkyline(ArrayList sky1, ArrayList sky2) {
- int currentH1 = 0;
- int currentH2 = 0;
- ArrayList skyline = new ArrayList<>();
- int maxH = 0;
-
- // Merge the two skylines
- while (!sky1.isEmpty() && !sky2.isEmpty()) {
- if (sky1.get(0).coordinates < sky2.get(0).coordinates) {
- int currentX = sky1.get(0).coordinates;
- currentH1 = sky1.get(0).height;
-
- if (currentH1 < currentH2) {
- sky1.remove(0);
- if (maxH != currentH2) {
- skyline.add(new Skyline(currentX, currentH2));
- }
- } else {
- maxH = currentH1;
- sky1.remove(0);
- skyline.add(new Skyline(currentX, currentH1));
- }
- } else {
- int currentX = sky2.get(0).coordinates;
- currentH2 = sky2.get(0).height;
-
- if (currentH2 < currentH1) {
- sky2.remove(0);
- if (maxH != currentH1) {
- skyline.add(new Skyline(currentX, currentH1));
- }
- } else {
- maxH = currentH2;
- sky2.remove(0);
- skyline.add(new Skyline(currentX, currentH2));
- }
+ public List mergeSkyline(List sky1, List sky2) {
+ Objects.requireNonNull(sky1, "sky1 must not be null");
+ Objects.requireNonNull(sky2, "sky2 must not be null");
+ int i = 0, j = 0;
+ int h1 = 0, h2 = 0;
+ int prevHeight = 0;
+ List result = new ArrayList<>();
+ while (i < sky1.size() && j < sky2.size()) {
+ Skyline p1 = sky1.get(i);
+ Skyline p2 = sky2.get(j);
+ int x;
+ if (p1.coordinates < p2.coordinates) {
+ x = p1.coordinates;
+ h1 = p1.height;
+ i++;
+ } else if (p2.coordinates < p1.coordinates) {
+ x = p2.coordinates;
+ h2 = p2.height;
+ j++;
+ } else { // same x
+ x = p1.coordinates;
+ h1 = p1.height;
+ h2 = p2.height;
+ i++;
+ j++;
+ }
+ int maxH = Math.max(h1, h2);
+ if (result.isEmpty() || prevHeight != maxH) {
+ result.add(new Skyline(x, maxH));
+ prevHeight = maxH;
}
}
-
- // Add any remaining points from sky1 or sky2
- while (!sky1.isEmpty()) {
- skyline.add(sky1.get(0));
- sky1.remove(0);
+ // Append remaining points
+ while (i < sky1.size()) {
+ Skyline p = sky1.get(i++);
+ if (result.isEmpty() || result.get(result.size() - 1).height != p.height || result.get(result.size() - 1).coordinates != p.coordinates) {
+ result.add(new Skyline(p.coordinates, p.height));
+ }
}
-
- while (!sky2.isEmpty()) {
- skyline.add(sky2.get(0));
- sky2.remove(0);
+ while (j < sky2.size()) {
+ Skyline p = sky2.get(j++);
+ if (result.isEmpty() || result.get(result.size() - 1).height != p.height || result.get(result.size() - 1).coordinates != p.coordinates) {
+ result.add(new Skyline(p.coordinates, p.height));
+ }
}
-
- return skyline;
+ return result;
}
/**
- * A class representing a point in the skyline with its x-coordinate and height.
+ * Represents a point in the skyline with its x-coordinate and height.
*/
- public class Skyline {
- public int coordinates;
- public int height;
+ public static class Skyline {
+ /** The x-coordinate of the skyline point. */
+ public final int coordinates;
+ /** The height of the skyline at the given coordinate. */
+ public final int height;
/**
* Constructor for the {@code Skyline} class.
@@ -126,16 +174,36 @@ public Skyline(int coordinates, int height) {
this.coordinates = coordinates;
this.height = height;
}
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+ Skyline skyline = (Skyline) o;
+ return coordinates == skyline.coordinates && height == skyline.height;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(coordinates, height);
+ }
+
+ @Override
+ public String toString() {
+ return "(" + coordinates + ", " + height + ")";
+ }
}
/**
- * A class representing a building with its left, height, and right
- * x-coordinates.
+ * Represents a building with its left, height, and right x-coordinates.
*/
- public class Building {
- public int left;
- public int height;
- public int right;
+ public static class Building {
+ /** The left x-coordinate of the building. */
+ public final int left;
+ /** The height of the building. */
+ public final int height;
+ /** The right x-coordinate of the building. */
+ public final int right;
/**
* Constructor for the {@code Building} class.
@@ -149,5 +217,11 @@ public Building(int left, int height, int right) {
this.height = height;
this.right = right;
}
+
+ @Override
+ public String toString() {
+ return "Building{"
+ + "left=" + left + ", height=" + height + ", right=" + right + '}';
+ }
}
}
diff --git a/src/test/java/com/thealgorithms/others/SkylineProblemTest.java b/src/test/java/com/thealgorithms/others/SkylineProblemTest.java
index 1ed5ced709c1..6f5997d9e064 100644
--- a/src/test/java/com/thealgorithms/others/SkylineProblemTest.java
+++ b/src/test/java/com/thealgorithms/others/SkylineProblemTest.java
@@ -1,86 +1,127 @@
package com.thealgorithms.others;
-import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.*;
-import java.util.ArrayList;
+import java.util.*;
import org.junit.jupiter.api.Test;
public class SkylineProblemTest {
@Test
- public void testSingleBuildingSkyline() {
+ void testSingleBuildingSkyline() {
SkylineProblem skylineProblem = new SkylineProblem();
skylineProblem.building = new SkylineProblem.Building[1];
skylineProblem.add(2, 10, 9);
- ArrayList result = skylineProblem.findSkyline(0, 0);
+ List result = skylineProblem.findSkyline(0, 0);
- assertEquals(2, result.get(0).coordinates);
- assertEquals(10, result.get(0).height);
- assertEquals(9, result.get(1).coordinates);
- assertEquals(0, result.get(1).height);
+ assertEquals(List.of(new SkylineProblem.Skyline(2, 10), new SkylineProblem.Skyline(9, 0)), result);
}
@Test
- public void testTwoBuildingsSkyline() {
+ void testTwoBuildingsSkyline() {
SkylineProblem skylineProblem = new SkylineProblem();
skylineProblem.building = new SkylineProblem.Building[2];
skylineProblem.add(1, 11, 5);
skylineProblem.add(2, 6, 7);
- ArrayList result = skylineProblem.findSkyline(0, 1);
+ List result = skylineProblem.findSkyline(0, 1);
// Expected skyline points: (1, 11), (5, 6), (7, 0)
- assertEquals(1, result.get(0).coordinates);
- assertEquals(11, result.get(0).height);
- assertEquals(5, result.get(1).coordinates);
- assertEquals(6, result.get(1).height);
- assertEquals(7, result.get(2).coordinates);
- assertEquals(0, result.get(2).height);
+ assertEquals(List.of(new SkylineProblem.Skyline(1, 11), new SkylineProblem.Skyline(5, 6), new SkylineProblem.Skyline(7, 0)), result);
}
@Test
- public void testMergeSkyline() {
+ void testMergeSkyline() {
+ List sky1 = List.of(new SkylineProblem.Skyline(2, 10), new SkylineProblem.Skyline(9, 0));
+ List sky2 = List.of(new SkylineProblem.Skyline(3, 15), new SkylineProblem.Skyline(7, 0));
SkylineProblem skylineProblem = new SkylineProblem();
- ArrayList sky1 = new ArrayList<>();
- ArrayList sky2 = new ArrayList<>();
-
- sky1.add(skylineProblem.new Skyline(2, 10));
- sky1.add(skylineProblem.new Skyline(9, 0));
-
- sky2.add(skylineProblem.new Skyline(3, 15));
- sky2.add(skylineProblem.new Skyline(7, 0));
-
- ArrayList result = skylineProblem.mergeSkyline(sky1, sky2);
+ List result = skylineProblem.mergeSkyline(sky1, sky2);
// Expected merged skyline: (2, 10), (3, 15), (7, 10), (9, 0)
- assertEquals(2, result.get(0).coordinates);
- assertEquals(10, result.get(0).height);
- assertEquals(3, result.get(1).coordinates);
- assertEquals(15, result.get(1).height);
- assertEquals(7, result.get(2).coordinates);
- assertEquals(10, result.get(2).height);
- assertEquals(9, result.get(3).coordinates);
- assertEquals(0, result.get(3).height);
+ assertEquals(List.of(new SkylineProblem.Skyline(2, 10), new SkylineProblem.Skyline(3, 15), new SkylineProblem.Skyline(7, 10), new SkylineProblem.Skyline(9, 0)), result);
}
@Test
- public void testMultipleBuildingsSkyline() {
+ void testMultipleBuildingsSkyline() {
SkylineProblem skylineProblem = new SkylineProblem();
skylineProblem.building = new SkylineProblem.Building[3];
skylineProblem.add(1, 10, 5);
skylineProblem.add(2, 15, 7);
skylineProblem.add(3, 12, 9);
- ArrayList result = skylineProblem.findSkyline(0, 2);
+ List result = skylineProblem.findSkyline(0, 2);
+
+ assertEquals(List.of(new SkylineProblem.Skyline(1, 10), new SkylineProblem.Skyline(2, 15), new SkylineProblem.Skyline(7, 12), new SkylineProblem.Skyline(9, 0)), result);
+ }
+
+ @Test
+ void testAddBuildingInvalidCases() {
+ SkylineProblem skylineProblem = new SkylineProblem();
+ // Not initialized
+ Exception ex = assertThrows(IllegalStateException.class, () -> skylineProblem.add(1, 2, 3));
+ assertTrue(ex.getMessage().contains("not initialized"));
+
+ skylineProblem.building = new SkylineProblem.Building[1];
+ skylineProblem.add(1, 2, 3);
+ // Array full
+ Exception ex2 = assertThrows(IllegalStateException.class, () -> skylineProblem.add(4, 5, 6));
+ assertTrue(ex2.getMessage().contains("full"));
+
+ // Invalid left >= right
+ SkylineProblem skylineProblem2 = new SkylineProblem();
+ skylineProblem2.building = new SkylineProblem.Building[1];
+ Exception ex3 = assertThrows(IllegalArgumentException.class, () -> skylineProblem2.add(5, 2, 2));
+ assertTrue(ex3.getMessage().contains("Left coordinate"));
+
+ // Invalid height < 0
+ Exception ex4 = assertThrows(IllegalArgumentException.class, () -> skylineProblem2.add(1, -1, 2));
+ assertTrue(ex4.getMessage().contains("Height must be non-negative"));
+ }
+
+ @Test
+ void testFindSkylineInvalidCases() {
+ SkylineProblem skylineProblem = new SkylineProblem();
+ // Not initialized
+ Exception ex = assertThrows(IllegalArgumentException.class, () -> skylineProblem.findSkyline(0, 0));
+ assertTrue(ex.getMessage().contains("not initialized"));
+
+ skylineProblem.building = new SkylineProblem.Building[2];
+ skylineProblem.count = 1;
+ Exception ex2 = assertThrows(IllegalArgumentException.class, () -> skylineProblem.findSkyline(0, 1));
+ assertTrue(ex2.getMessage().contains("Invalid start or end index"));
+ }
+
+ @Test
+ void testMergeSkylineNullCases() {
+ SkylineProblem skylineProblem = new SkylineProblem();
+ Exception ex1 = assertThrows(NullPointerException.class, () -> skylineProblem.mergeSkyline(null, List.of()));
+ Exception ex2 = assertThrows(NullPointerException.class, () -> skylineProblem.mergeSkyline(List.of(), null));
+ assertTrue(ex1.getMessage().contains("sky1"));
+ assertTrue(ex2.getMessage().contains("sky2"));
+ }
+
+ @Test
+ void testSkylineEqualsAndHashCode() {
+ SkylineProblem.Skyline s1 = new SkylineProblem.Skyline(1, 2);
+ SkylineProblem.Skyline s2 = new SkylineProblem.Skyline(1, 2);
+ SkylineProblem.Skyline s3 = new SkylineProblem.Skyline(2, 2);
+ assertEquals(s1, s2);
+ assertEquals(s1.hashCode(), s2.hashCode());
+ assertNotEquals(s1, s3);
+ assertNotEquals(null, s1);
+ assertNotEquals("string", s1);
+ }
- assertEquals(1, result.get(0).coordinates);
- assertEquals(10, result.get(0).height);
- assertEquals(2, result.get(1).coordinates);
- assertEquals(15, result.get(1).height);
- assertEquals(7, result.get(2).coordinates);
- assertEquals(12, result.get(2).height);
- assertEquals(9, result.get(3).coordinates);
- assertEquals(0, result.get(3).height);
+ @Test
+ void testSkylineToString() {
+ SkylineProblem.Skyline s = new SkylineProblem.Skyline(5, 10);
+ assertEquals("(5, 10)", s.toString());
+ }
+
+ @Test
+ void testBuildingToString() {
+ SkylineProblem.Building b = new SkylineProblem.Building(1, 2, 3);
+ assertEquals("Building{left=1, height=2, right=3}", b.toString());
}
}
From a2ba20f702467a5bdcc4d83b7328a33715023890 Mon Sep 17 00:00:00 2001
From: Hardik Pawar
Date: Sun, 5 Oct 2025 13:17:29 +0530
Subject: [PATCH 2/7] Fix lint
---
.../thealgorithms/others/SkylineProblem.java | 14 +++++++----
.../others/SkylineProblemTest.java | 23 +++++++++++++++----
2 files changed, 28 insertions(+), 9 deletions(-)
diff --git a/src/main/java/com/thealgorithms/others/SkylineProblem.java b/src/main/java/com/thealgorithms/others/SkylineProblem.java
index 7a807c072177..1d060be58863 100644
--- a/src/main/java/com/thealgorithms/others/SkylineProblem.java
+++ b/src/main/java/com/thealgorithms/others/SkylineProblem.java
@@ -110,8 +110,10 @@ public List findSkyline(int start, int end) {
public List mergeSkyline(List sky1, List sky2) {
Objects.requireNonNull(sky1, "sky1 must not be null");
Objects.requireNonNull(sky2, "sky2 must not be null");
- int i = 0, j = 0;
- int h1 = 0, h2 = 0;
+ int i = 0;
+ int j = 0;
+ int h1 = 0;
+ int h2 = 0;
int prevHeight = 0;
List result = new ArrayList<>();
while (i < sky1.size() && j < sky2.size()) {
@@ -177,8 +179,12 @@ public Skyline(int coordinates, int height) {
@Override
public boolean equals(Object o) {
- if (this == o) return true;
- if (o == null || getClass() != o.getClass()) return false;
+ if (this == o) {
+ return true;
+ }
+ if (o == null || getClass() != o.getClass()) {
+ return false;
+ }
Skyline skyline = (Skyline) o;
return coordinates == skyline.coordinates && height == skyline.height;
}
diff --git a/src/test/java/com/thealgorithms/others/SkylineProblemTest.java b/src/test/java/com/thealgorithms/others/SkylineProblemTest.java
index 6f5997d9e064..fddca17e3892 100644
--- a/src/test/java/com/thealgorithms/others/SkylineProblemTest.java
+++ b/src/test/java/com/thealgorithms/others/SkylineProblemTest.java
@@ -1,11 +1,14 @@
package com.thealgorithms.others;
-import static org.junit.jupiter.api.Assertions.*;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotEquals;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.junit.jupiter.api.Assertions.assertTrue;
-import java.util.*;
+import java.util.List;
import org.junit.jupiter.api.Test;
-public class SkylineProblemTest {
+class SkylineProblemTest {
@Test
void testSingleBuildingSkyline() {
@@ -95,8 +98,18 @@ void testFindSkylineInvalidCases() {
@Test
void testMergeSkylineNullCases() {
SkylineProblem skylineProblem = new SkylineProblem();
- Exception ex1 = assertThrows(NullPointerException.class, () -> skylineProblem.mergeSkyline(null, List.of()));
- Exception ex2 = assertThrows(NullPointerException.class, () -> skylineProblem.mergeSkyline(List.of(), null));
+ Exception ex1 = assertThrows(NullPointerException.class, new org.junit.jupiter.api.function.Executable() {
+ @Override
+ public void execute() {
+ skylineProblem.mergeSkyline(null, List.of());
+ }
+ });
+ Exception ex2 = assertThrows(NullPointerException.class, new org.junit.jupiter.api.function.Executable() {
+ @Override
+ public void execute() {
+ skylineProblem.mergeSkyline(List.of(), null);
+ }
+ });
assertTrue(ex1.getMessage().contains("sky1"));
assertTrue(ex2.getMessage().contains("sky2"));
}
From 311158ed62287042b595249576353aa523c67fb7 Mon Sep 17 00:00:00 2001
From: Hardik Pawar
Date: Sun, 5 Oct 2025 13:25:58 +0530
Subject: [PATCH 3/7] Fix
---
.../thealgorithms/others/SkylineProblem.java | 16 +++++++++++-
.../others/SkylineProblemTest.java | 26 ++++++-------------
2 files changed, 23 insertions(+), 19 deletions(-)
diff --git a/src/main/java/com/thealgorithms/others/SkylineProblem.java b/src/main/java/com/thealgorithms/others/SkylineProblem.java
index 1d060be58863..470d861664ad 100644
--- a/src/main/java/com/thealgorithms/others/SkylineProblem.java
+++ b/src/main/java/com/thealgorithms/others/SkylineProblem.java
@@ -34,13 +34,27 @@ public class SkylineProblem {
/**
* Array of buildings to process. Must be initialized before use.
*/
- public Building[] building;
+ private Building[] building;
/**
* Number of buildings added so far.
*/
public int count;
+ /**
+ * Sets the building array to the specified size.
+ *
+ * @param size The size of the building array.
+ * @throws IllegalArgumentException if size is negative
+ */
+ public void setBuilding(int size) {
+ if (size < 0) {
+ throw new IllegalArgumentException("Size must be non-negative");
+ }
+ this.building = new Building[size];
+ this.count = 0;
+ }
+
/**
* Adds a building with the given left, height, and right values to the
* buildings list.
diff --git a/src/test/java/com/thealgorithms/others/SkylineProblemTest.java b/src/test/java/com/thealgorithms/others/SkylineProblemTest.java
index fddca17e3892..3112d769debf 100644
--- a/src/test/java/com/thealgorithms/others/SkylineProblemTest.java
+++ b/src/test/java/com/thealgorithms/others/SkylineProblemTest.java
@@ -13,7 +13,7 @@ class SkylineProblemTest {
@Test
void testSingleBuildingSkyline() {
SkylineProblem skylineProblem = new SkylineProblem();
- skylineProblem.building = new SkylineProblem.Building[1];
+ skylineProblem.setBuilding(1);
skylineProblem.add(2, 10, 9);
List result = skylineProblem.findSkyline(0, 0);
@@ -24,7 +24,7 @@ void testSingleBuildingSkyline() {
@Test
void testTwoBuildingsSkyline() {
SkylineProblem skylineProblem = new SkylineProblem();
- skylineProblem.building = new SkylineProblem.Building[2];
+ skylineProblem.setBuilding(2);
skylineProblem.add(1, 11, 5);
skylineProblem.add(2, 6, 7);
@@ -48,7 +48,7 @@ void testMergeSkyline() {
@Test
void testMultipleBuildingsSkyline() {
SkylineProblem skylineProblem = new SkylineProblem();
- skylineProblem.building = new SkylineProblem.Building[3];
+ skylineProblem.setBuilding(3);
skylineProblem.add(1, 10, 5);
skylineProblem.add(2, 15, 7);
skylineProblem.add(3, 12, 9);
@@ -65,7 +65,7 @@ void testAddBuildingInvalidCases() {
Exception ex = assertThrows(IllegalStateException.class, () -> skylineProblem.add(1, 2, 3));
assertTrue(ex.getMessage().contains("not initialized"));
- skylineProblem.building = new SkylineProblem.Building[1];
+ skylineProblem.setBuilding(1);
skylineProblem.add(1, 2, 3);
// Array full
Exception ex2 = assertThrows(IllegalStateException.class, () -> skylineProblem.add(4, 5, 6));
@@ -73,7 +73,7 @@ void testAddBuildingInvalidCases() {
// Invalid left >= right
SkylineProblem skylineProblem2 = new SkylineProblem();
- skylineProblem2.building = new SkylineProblem.Building[1];
+ skylineProblem2.setBuilding(1);
Exception ex3 = assertThrows(IllegalArgumentException.class, () -> skylineProblem2.add(5, 2, 2));
assertTrue(ex3.getMessage().contains("Left coordinate"));
@@ -89,7 +89,7 @@ void testFindSkylineInvalidCases() {
Exception ex = assertThrows(IllegalArgumentException.class, () -> skylineProblem.findSkyline(0, 0));
assertTrue(ex.getMessage().contains("not initialized"));
- skylineProblem.building = new SkylineProblem.Building[2];
+ skylineProblem.setBuilding(2);
skylineProblem.count = 1;
Exception ex2 = assertThrows(IllegalArgumentException.class, () -> skylineProblem.findSkyline(0, 1));
assertTrue(ex2.getMessage().contains("Invalid start or end index"));
@@ -98,18 +98,8 @@ void testFindSkylineInvalidCases() {
@Test
void testMergeSkylineNullCases() {
SkylineProblem skylineProblem = new SkylineProblem();
- Exception ex1 = assertThrows(NullPointerException.class, new org.junit.jupiter.api.function.Executable() {
- @Override
- public void execute() {
- skylineProblem.mergeSkyline(null, List.of());
- }
- });
- Exception ex2 = assertThrows(NullPointerException.class, new org.junit.jupiter.api.function.Executable() {
- @Override
- public void execute() {
- skylineProblem.mergeSkyline(List.of(), null);
- }
- });
+ Exception ex1 = assertThrows(NullPointerException.class, () -> skylineProblem.mergeSkyline(null, List.of()));
+ Exception ex2 = assertThrows(NullPointerException.class, () -> skylineProblem.mergeSkyline(List.of(), null));
assertTrue(ex1.getMessage().contains("sky1"));
assertTrue(ex2.getMessage().contains("sky2"));
}
From f9e42d92525b2454b00a020df6260186f59e897a Mon Sep 17 00:00:00 2001
From: Hardik Pawar
Date: Sun, 5 Oct 2025 13:31:27 +0530
Subject: [PATCH 4/7] Fix
---
.../bloomfilter/BloomFilter.java | 61 +++++++++++++++----
1 file changed, 48 insertions(+), 13 deletions(-)
diff --git a/src/main/java/com/thealgorithms/datastructures/bloomfilter/BloomFilter.java b/src/main/java/com/thealgorithms/datastructures/bloomfilter/BloomFilter.java
index d60b95110fc2..674047bdbbb6 100644
--- a/src/main/java/com/thealgorithms/datastructures/bloomfilter/BloomFilter.java
+++ b/src/main/java/com/thealgorithms/datastructures/bloomfilter/BloomFilter.java
@@ -1,18 +1,20 @@
package com.thealgorithms.datastructures.bloomfilter;
+import java.util.Arrays;
import java.util.BitSet;
/**
* A generic BloomFilter implementation for probabilistic membership checking.
*
- * Bloom filters are space-efficient data structures that provide a fast way to test whether an
- * element is a member of a set. They may produce false positives, indicating an element is
+ * Bloom filters are space-efficient data structures that provide a fast way to
+ * test whether an
+ * element is a member of a set. They may produce false positives, indicating an
+ * element is
* in the set when it is not, but they will never produce false negatives.
*
*
* @param The type of elements to be stored in the Bloom filter.
*/
-@SuppressWarnings("rawtypes")
public class BloomFilter {
private final int numberOfHashFunctions;
@@ -20,11 +22,14 @@ public class BloomFilter {
private final Hash[] hashFunctions;
/**
- * Constructs a BloomFilter with a specified number of hash functions and bit array size.
+ * Constructs a BloomFilter with a specified number of hash functions and bit
+ * array size.
*
* @param numberOfHashFunctions the number of hash functions to use
- * @param bitArraySize the size of the bit array, which determines the capacity of the filter
- * @throws IllegalArgumentException if numberOfHashFunctions or bitArraySize is less than 1
+ * @param bitArraySize the size of the bit array, which determines the
+ * capacity of the filter
+ * @throws IllegalArgumentException if numberOfHashFunctions or bitArraySize is
+ * less than 1
*/
@SuppressWarnings("unchecked")
public BloomFilter(int numberOfHashFunctions, int bitArraySize) {
@@ -38,7 +43,8 @@ public BloomFilter(int numberOfHashFunctions, int bitArraySize) {
}
/**
- * Initializes the hash functions with unique indices to ensure different hashing.
+ * Initializes the hash functions with unique indices to ensure different
+ * hashing.
*/
private void initializeHashFunctions() {
for (int i = 0; i < numberOfHashFunctions; i++) {
@@ -49,7 +55,8 @@ private void initializeHashFunctions() {
/**
* Inserts an element into the Bloom filter.
*
- * This method hashes the element using all defined hash functions and sets the corresponding
+ * This method hashes the element using all defined hash functions and sets the
+ * corresponding
* bits in the bit array.
*
*
@@ -65,13 +72,16 @@ public void insert(T key) {
/**
* Checks if an element might be in the Bloom filter.
*
- * This method checks the bits at the positions computed by each hash function. If any of these
- * bits are not set, the element is definitely not in the filter. If all bits are set, the element
+ * This method checks the bits at the positions computed by each hash function.
+ * If any of these
+ * bits are not set, the element is definitely not in the filter. If all bits
+ * are set, the element
* might be in the filter.
*
*
* @param key the element to check for membership in the Bloom filter
- * @return {@code true} if the element might be in the Bloom filter, {@code false} if it is definitely not
+ * @return {@code true} if the element might be in the Bloom filter,
+ * {@code false} if it is definitely not
*/
public boolean contains(T key) {
for (Hash hash : hashFunctions) {
@@ -86,7 +96,8 @@ public boolean contains(T key) {
/**
* Inner class representing a hash function used by the Bloom filter.
*
- * Each instance of this class represents a different hash function based on its index.
+ * Each instance of this class represents a different hash function based on its
+ * index.
*
*
* @param The type of elements to be hashed.
@@ -109,13 +120,37 @@ private static class Hash {
*
* The hash value is calculated by multiplying the index of the hash function
* with the ASCII sum of the string representation of the key.
+ * For array types, the content of the array is used instead of the default
+ * toString.
*
*
* @param key the element to hash
* @return the computed hash value
*/
public int compute(T key) {
- return index * asciiString(String.valueOf(key));
+ String keyString;
+ if (key instanceof Object[] objectArray) {
+ keyString = Arrays.deepToString(objectArray);
+ } else if (key instanceof int[] intArray) {
+ keyString = Arrays.toString(intArray);
+ } else if (key instanceof long[] longArray) {
+ keyString = Arrays.toString(longArray);
+ } else if (key instanceof double[] doubleArray) {
+ keyString = Arrays.toString(doubleArray);
+ } else if (key instanceof float[] floatArray) {
+ keyString = Arrays.toString(floatArray);
+ } else if (key instanceof boolean[] booleanArray) {
+ keyString = Arrays.toString(booleanArray);
+ } else if (key instanceof byte[] byteArray) {
+ keyString = Arrays.toString(byteArray);
+ } else if (key instanceof char[] charArray) {
+ keyString = Arrays.toString(charArray);
+ } else if (key instanceof short[] shortArray) {
+ keyString = Arrays.toString(shortArray);
+ } else {
+ keyString = String.valueOf(key);
+ }
+ return index * asciiString(keyString);
}
/**
From a72dec9aa681ed7a97312c2c35f6a24cc74140cc Mon Sep 17 00:00:00 2001
From: Hardik Pawar
Date: Sun, 5 Oct 2025 14:46:45 +0530
Subject: [PATCH 5/7] Fix
---
.../thealgorithms/datastructures/bloomfilter/BloomFilter.java | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/main/java/com/thealgorithms/datastructures/bloomfilter/BloomFilter.java b/src/main/java/com/thealgorithms/datastructures/bloomfilter/BloomFilter.java
index 674047bdbbb6..98df154d4589 100644
--- a/src/main/java/com/thealgorithms/datastructures/bloomfilter/BloomFilter.java
+++ b/src/main/java/com/thealgorithms/datastructures/bloomfilter/BloomFilter.java
@@ -38,7 +38,7 @@ public BloomFilter(int numberOfHashFunctions, int bitArraySize) {
}
this.numberOfHashFunctions = numberOfHashFunctions;
this.bitArray = new BitSet(bitArraySize);
- this.hashFunctions = new Hash[numberOfHashFunctions];
+ this.hashFunctions = (Hash[]) new Hash>[numberOfHashFunctions];
initializeHashFunctions();
}
From 63fd91ded7141df2b8537c102011cf2b127dacef Mon Sep 17 00:00:00 2001
From: Hardik Pawar
Date: Sun, 12 Oct 2025 11:21:02 +0530
Subject: [PATCH 6/7] Fix reviews
---
.../bloomfilter/BloomFilter.java | 34 +++++++------------
.../thealgorithms/others/SkylineProblem.java | 1 -
2 files changed, 12 insertions(+), 23 deletions(-)
diff --git a/src/main/java/com/thealgorithms/datastructures/bloomfilter/BloomFilter.java b/src/main/java/com/thealgorithms/datastructures/bloomfilter/BloomFilter.java
index 98df154d4589..610937950c16 100644
--- a/src/main/java/com/thealgorithms/datastructures/bloomfilter/BloomFilter.java
+++ b/src/main/java/com/thealgorithms/datastructures/bloomfilter/BloomFilter.java
@@ -128,28 +128,18 @@ private static class Hash {
* @return the computed hash value
*/
public int compute(T key) {
- String keyString;
- if (key instanceof Object[] objectArray) {
- keyString = Arrays.deepToString(objectArray);
- } else if (key instanceof int[] intArray) {
- keyString = Arrays.toString(intArray);
- } else if (key instanceof long[] longArray) {
- keyString = Arrays.toString(longArray);
- } else if (key instanceof double[] doubleArray) {
- keyString = Arrays.toString(doubleArray);
- } else if (key instanceof float[] floatArray) {
- keyString = Arrays.toString(floatArray);
- } else if (key instanceof boolean[] booleanArray) {
- keyString = Arrays.toString(booleanArray);
- } else if (key instanceof byte[] byteArray) {
- keyString = Arrays.toString(byteArray);
- } else if (key instanceof char[] charArray) {
- keyString = Arrays.toString(charArray);
- } else if (key instanceof short[] shortArray) {
- keyString = Arrays.toString(shortArray);
- } else {
- keyString = String.valueOf(key);
- }
+ String keyString = switch (key) {
+ case Object[] arr -> Arrays.deepToString(arr);
+ case int[] arr -> Arrays.toString(arr);
+ case long[] arr -> Arrays.toString(arr);
+ case double[] arr -> Arrays.toString(arr);
+ case float[] arr -> Arrays.toString(arr);
+ case boolean[] arr -> Arrays.toString(arr);
+ case byte[] arr -> Arrays.toString(arr);
+ case char[] arr -> Arrays.toString(arr);
+ case short[] arr -> Arrays.toString(arr);
+ case null, default -> String.valueOf(key);
+ };
return index * asciiString(keyString);
}
diff --git a/src/main/java/com/thealgorithms/others/SkylineProblem.java b/src/main/java/com/thealgorithms/others/SkylineProblem.java
index 470d861664ad..d9e2a8cc2547 100644
--- a/src/main/java/com/thealgorithms/others/SkylineProblem.java
+++ b/src/main/java/com/thealgorithms/others/SkylineProblem.java
@@ -1,4 +1,3 @@
-
package com.thealgorithms.others;
import java.util.ArrayList;
From 582908b3105b9699a031502813e8a31575738254 Mon Sep 17 00:00:00 2001
From: Hardik Pawar
Date: Sun, 12 Oct 2025 11:21:26 +0530
Subject: [PATCH 7/7] Lint
---
.../datastructures/bloomfilter/BloomFilter.java | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/src/main/java/com/thealgorithms/datastructures/bloomfilter/BloomFilter.java b/src/main/java/com/thealgorithms/datastructures/bloomfilter/BloomFilter.java
index 610937950c16..8c4204e1239f 100644
--- a/src/main/java/com/thealgorithms/datastructures/bloomfilter/BloomFilter.java
+++ b/src/main/java/com/thealgorithms/datastructures/bloomfilter/BloomFilter.java
@@ -156,9 +156,9 @@ public int compute(T key) {
private int asciiString(String word) {
int sum = 0;
for (char c : word.toCharArray()) {
- sum += c;
- }
- return sum;
+ sum += c;
+ }
+ return sum;
+ }
}
}
-}