In data analysis and statistics, a common initial task is classifying numbers based on their sign. HackerRank's Plus-Minus ratio challenge is a standard test of this concept.
Given an array of integers, we need to calculate the ratio of positive values, negative values, and zero values relative to the total number of elements. The challenge requires printing each ratio on a new line, formatted as a decimal with exactly six decimal places.
While iterating and counting values is basic programming, this problem tests your handling of type casting (to avoid integer truncation) and output formatting. We can solve this cleanly in Java using the Stream API for declaration and custom decimal string formats.
To visualize this task, imagine a bag containing 6 candies of different colors:
- 3 Red candies (representing Positive numbers)
- 2 Blue candies (representing Negative numbers)
- 1 Green candy (representing Zero)
- Red Candy Ratio:
3 / 6 = 0.500000(half of the bag is Red). - Blue Candy Ratio:
2 / 6 = 0.333333(one-third of the bag is Blue). - Green Candy Ratio:
1 / 6 = 0.166667(one-sixth of the bag is Green).
3 / 6 yields 0 in integer division). To prevent this, we must cast the counts to decimal values (such as double or float) before dividing.
Technical Strategy
Our Java strategy consists of two main parts:
- Filtering Streams: We use the Stream API to filter elements dynamically:
- Positive count:
arr.stream().filter(n -> n > 0).count() - Negative count:
arr.stream().filter(n -> n < 0).count() - Zero count:
arr.stream().filter(n -> n == 0).count()
- Positive count:
- Decimal Formatting: To satisfy the six-decimal-place requirement, we format the resulting quotient using
String.format("%.6f", quotient). The%.6fformat specifier tells the JVM to print a floating-point number rounded to exactly six decimal places.
Step-by-Step Scenario Trace
Let's trace the algorithm on an array of size N = 6: arr = [-4, 3, -9, 0, 4, 1]:
- Positive Count: The values
3,4, and1are greater than zero. Count is3. Ratio:3.0 / 6.0 = 0.500000. - Negative Count: The values
-4and-9are less than zero. Count is2. Ratio:2.0 / 6.0 = 0.333333. - Zero Count: The value
0is equal to zero. Count is1. Ratio:1.0 / 6.0 = 0.166667.
Java Implementation Code
Below is the complete Java code solving the challenge:
package io.practise.hackerrank;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.List;
import java.util.stream.Stream;
import static java.util.stream.Collectors.toList;
public class PlusMinusRatio {
public static void main(String[] args) throws IOException {
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in));
int n = Integer.parseInt(bufferedReader.readLine().trim());
List<Integer> arr = Stream.of(bufferedReader.readLine().replaceAll("\\s+$", "").split(" "))
.map(Integer::parseInt)
.collect(toList());
plusMinus(arr);
bufferedReader.close();
}
private static void plusMinus(List<Integer> arr) {
double total = arr.size();
double countNegative = arr.stream().filter(element -> element < 0).count();
double countPositive = arr.stream().filter(element -> element > 0).count();
double countZero = arr.stream().filter(element -> element == 0).count();
System.out.println(String.format("%.6f", countPositive / total));
System.out.println(String.format("%.6f", countNegative / total));
System.out.println(String.format("%.6f", countZero / total));
}
}
Conclusion & Complexity Analysis
This solution runs in O(N) linear time complexity (as we inspect each array element to classify its sign) and uses O(1) constant space. Utilizing functional streams keeps the logic concise and readable, making it easy to adapt for more complex classification pipelines.