I have an array of numbers, now I have to find sum of elements by generating all the possible subarrays of the given array and applying some conditions.
The condition is for each subarray get the minimum and also find the total of elements in it and multiply both (minimum * total). Finally, add all these multiplied values for all subarrays.
Here is the problem statement:
Find the sum of all possible sub-arrays using the below formula:
Sum(left, right) = (min of arr[i]) * (∑ arr[i]), where i ranges from
left to right.
Example:
Array = [2,3,2,1]
The sub arrays are: [start_index, end_index]
[0,0] subarray = [2], min is 2 and total of items = 2. min * total = 2*2=4
[0,1] subarray = [2,3], min is 2 and total of items = 5. min * total = 2*5=10
[0,2] subarray = [2,3,2], min is 2 and total of items = 7. min * total = 2*7=14
[0,3] subarray = [2,3,2,1], min is 1 and total of items = 8. min * total = 1*8=8
[1,1] subarray = [3], min is 3 and total of items = 3. min * total = 3*3 = 9
[1,2] subarray = [3,2], min is 2 and total of items = 5. min * total = 2*5 = 10
[1,3] subarray = [3,2,1], min is 1 and total of items = 6. min * total = 1*6 = 6
[2,2] subarray = [2], min is 2 and total of items = 2. min * total = 2*2 = 4
[2,3] subarray = [2,1], min is 1 and total of items = 3. min * total = 1*3 = 3
[3,3] subarray = [1], min is 1 and total of items = 1. min * total = 1*1 = 1
Total = 4 + 10 + 14 + 8 + 9 + 10+ 6 + 4 + 3 + 1 = 69
So the answer is 69 in this case.
Constraints:
Each array element is in range 1 to 10^9. Array size 1 to 10^5. Return response in modulo 10^9+7
This is the code I tried.
public static int process(List<Integer> list) {
int n = list.size();
int mod = 7 + 1000_000_000;
long result = 0;
for (int i = 0; i < n; i++) {
long total = 0;
int min = list.get(i);
for (int j = i; j < n; j++) {
int p = list.get(j);
total = (total + p) % mod;
min = Math.min(min, p);
result = (result + (min * total) % mod) % mod;
}
}
return (int) result;
}
I want to reduce the time complexity of this algorithm?
What can be a better approach to solve this task?
Update:
David Eisenstat has given a great answer, but Im finding it to difficult to understand and come with a Java program, can someone provide a java solution for the approach or provide a pseudo code so i can come up with a program.
As user1984 observes, we can't achieve o(n²) by doing constant work for each sub-array. Here's how we get to O(n).
The sub-array minimum is the hardest factor to deal with, so we factor it out. Assume that the elements are pairwise distinct to avoid double counting in the math below (the code won't change). Letting A range over sub-arrays and x over elements,
sum_{A} [(sum_{y in A} y) (min A)] =
sum_{x} [x sum_{A such that min(A) = x} (sum_{y in A} y)].
Focusing on sum_{A | min(A) = x} (sum_{y in A} y) first, the picture is that we have a sub-array like
a b x c d e
where the element to the left of a (if it exists) is less than x, the element to the right of e (if it exists) is less than x, and all of the elements shown are greater than x. We want to sum over all sub-sub-arrays containing x.
a b x
b x
x
a b x c
b x c
x c
a b x c d
b x c d
x c d
a b x c d e
b x c d e
x c d e
We still don't have time to sum over these sub-sub-arrays, but fortunately there's a pattern. Here are the number of times each element appears in a sub-sub-array.
a: 4 = 1 * 4 appearances
b: 8 = 2 * 4 appearances
x: 12 = 3 * 4 appearances
c: 9 = 3 * 3 appearances
d: 6 = 3 * 2 appearances
e: 3 = 3 * 1 appearances
This insight reduces the processing time for one sub-array to O(n), but there are still n sub-arrays, so we need two more ideas.
Now is the right time to figure out what the sub-arrays look like. The first sub-array is the whole array. We split this array at the minimum element and recursively investigate the left sub-array and the right separately.
This recursive structure is captured by the labeled binary tree where
The in-order traversal is the array elements in order;
Every node has a label less than its children. (I'm still assuming distinct elements. In practice what we can do is to declare the array index to be a tiebreaker.)
This is called a treap, and it can be constructed in linear time by an algorithm with a family resemblance to precedence parsing. For the array [3,1,4,5,9,2,6], for example, see below.
1
/ \
3 2
/ \
4 6
\
5
\
9
The final piece is being able to aggregate the sum patterns above. Specifically, we want to implement an API that might look like this in C++:
class ArraySummary {
public:
// Constructs an object with underlying array [x].
ArraySummary(int x);
// Returns an object representing the concatenation of the underlying arrays.
ArraySummary Concatenate(ArraySummary that);
// Returns the sum over i of (i+1)*array[i].
int WeirdSum();
};
The point of this interface is that we don't actually need to store the whole array to implement WeirdSum(). If we store
The length length of the underlying array,
The usual sum sum of the underlying array,
The weird sum weird_sum of the underlying array;
then we can implement the constructor as
length = 1;
sum = x;
weird_sum = x;
and Concatenate() as
length = length1 + length2;
sum = sum1 + sum2;
weird_sum = weird_sum1 + weird_sum2 + length1 * sum2;
We need two of these, one in each direction. Then it's just a depth-first traversal (actually if you implement precedence parsing, it's just bottom-up).
Your current solution has time complexity O(n^2), assuming that list.get is O(1). There are exactly 1 + 2 + ... + n-1 + n operations which can be expressed as n * (n + 1)/2, hence O(n^2).
Interestingly, n * (n + 1)/2 is the number of sub arrays that you can get from an array of length n, as defined in your question and evident from your code.
This implies that you are doing one operation per sub array and this is the requird minimum operations for this task, since you need to look at least once at each sub array.
My conclusion is that it isn't possible to reduce the time complexity of this task, unless there is some mathematical formula that helps to do so.
This doesn't necessary mean that there aren't ways to optimize the code, but that would need testing and may be language specific. Regardless, it wouldn't change the time complexity in terms of n where n is the length of the input array.
Appreciate any input on my logic. I'm learning myself.
The answer provided by David Eisenstat is very efficient with complexity of O(n).
I would like to share another approach, that although it has time complexity of O(n^2), it may be more simple and may be easier for some (me included) to fully understand.
Algorithm
initiate two dimensional array of size matrix[n][n], each cell will hold pair of Integers <sum, min>. we will denote for each Matrix[i, j] the first element of the pair as Matrix[i, j].sum and the second as Matrix[i, j].min
Initiate the diagonal of the matrix as follows:
for i in [0, n-1]:
Matrix[i][i] = <arr[i], arr[i]>
for i in [0, n-1]:
for j in[i, n-1]:
Matrix[i, j] = <
Matrix[i - 1, j].sum + arr[i, j],
Min(Matrix[i - 1, j].min, arr[i, j])
>
Calculate the result:
result = 0
for i in [0, n-1]:
for j in[i, n-1]:
result += Matrix[i, j].sum * Matrix[i, j].min
Time Complexity Analysis
Step 1: initiating two dimensional array ofsize [n,n] will take in theory O(n^2) as it may require to initiate all indices to 0, but if we skip the initialization of each cell and just allocate the memory this could take O(1)
Step 2 : Here we iterate from 0 to n-1 doing constant work each iteration and therefore the time complexity is O(n)
Step 3: Here we iterate over half of the matrix cells(all that are right of the diagonal), doing constant work each iteration, and therefore the time complexity is O((n - 1) + (n - 2) + .... + (1) + (0)) = O(n^2)
Step 4: Similar analysis to step 3, O(n^2)
In total we get O(n^2)
Explanation for solution
This is simple example of Dynamic programming approach.
Let's define sub[i, j] as the subarray between index i and j while 0 =< i, j <= n-1
Then:
Matrix[i, j].sum = sum x in sub[i, j]
Matrix[i, j].min = min x in sub[i, j]
Why?
for sub[i,i] it's obvious that:
sum x in sub[i, i] = arr[i]
min x in sub[i, i] = arr[i]
Just like we calculate in step 2.
Convince yourself that:
sum sub[i,j] = sum sub[i-1,j] + arr[i, j]
min sub[i,j] = Min(min sub[i-1,j], arr[i, j])
This explains step 3.
In Step 4 we just sums up everything to get the required result.
It can be with the O(n) solution.
Intuition
First of all, we want to achieve all subarrays like this.
a1 a2 a3 min b1 b2 b3 where min is minimum. We will use a monotonic increasing stack to achieve it. In every iteration, if the stack's top value is greater than the next element, we will pop the stack and calculate the sum until the condition is not met.
Secondly, we want to figure out how to calculate the total sum if we have an a1 a2 a3 min b1 b2 b3 subarray. Here, we will use a prefix of prefix sum.
Prefix Sum
At first, we need the prefix sum. Assume that p indicates prefix sum, we want to achieve p1 p2 p3 p4 p5 p6 p7. Our prefix sum will be like this;
p1: a1
p2: a1 + a2
p3: a1 + a2 + a3
.
p6 : a1 + a2 + a3 + min + b1 + b2
p7: a1 + a2 + a3 + min + b1 + b2 + b3
Within prefix sum now we can calculate the sum of between two indexes. The sum of (start, end] is pend - pstart. If start: 1 and end: 3 that means p3 - p1 = (a1 + a2 + a3) - (a1) = a2 + a3.
Prefix of Prefix Sum
How can we calculate all possible subarray sums that include our min value?
We separate this calculation to the left side and right side.
The left side included min will be a1 a2 a3 min.
The right side included min will be min b1 b2 b3.
For example, some of the possible sums can be:
a1 + a2 + a3 + min
a1 + a2 + a3 + min + b1
a3 + min + b1 + b2 + b3
min + b1 + b2 + b3
We need to find all the [bj, ai] sums. Where i means all the left side indexes and j means all the right side indexes. Now We need to use the prefix of prefix sum. It will give us all possible sums between two indexes. Let's say P. It will be sum(Pj) - sum(Pi).
Now, how do we calculate our sum(Pj) - sum(Pi)?
So Pj is P7 - P4. It is the right side possible sum.
Same way Pi is P4 - P1. It is the left side possible sum.
How many combinations for sum(Pj) are there?
leftSize * (P7 - P4). Same way for sum(Pi) it will be rightSize * (P4 - P1).
Final equation to calculate subarray [a1 a2 a3 min b1 b2 b3] is: min * ((leftSize * (P7 - P4)) - (rightSize * (P4 - P1))).
Algorithm
public static int process(List<Integer> list) {
int n = list.size();
int mod = (int) 1e9 + 7;
int[] preSum = new int[n + 2];
Deque<Integer> stack = new ArrayDeque<>();
int pre = 0;
int result = 0;
for (int i = 0; i <= n; i++) {
int num = i < n ? list.get(i) : 0;
// current prefix sum
pre = (pre + num) % mod;
// prefix of prefix sum array
preSum[i + 1] = (preSum[i] + pre) % mod;
while (!stack.isEmpty() && list.get(stack.peek()) > num) {
int mid = stack.pop();
int left = stack.isEmpty() ? -1 : stack.peek();
int lSize = mid - left;
int rSize = i - mid;
long lSum = left < 0 ? preSum[mid] : preSum[mid] - preSum[left];
long rSum = preSum[i] - preSum[mid];
result = (int) (result + (list.get(mid) * ((rSum * lSize - lSum * rSize) % mod)) % mod) % mod;
}
stack.push(i);
}
return (result + mod) % mod;
}
Time complexity: O(n)
Space complexity: O(n)
References
Thanks to #lee215 for one pass solution.
Thanks to #forAc for the explanation of the final equation.
https://leetcode.com/problems/sum-of-total-strength-of-wizards/discuss/2061985/JavaC%2B%2BPython-One-Pass-Solution
I am trying to add numbers but keep it within a range. If it oversteps or understeps the boundary it will circle back to the other boundary.
Examples:
Min: 10
Max: 50
20 + 10 = 30
20 + 30 = 50 (or 0 idrk)
20 + 31 = 1
40 + 20 = 10
40 + 70 = 10
40 - 10 = 30
10 - 30 = 30
10 - 20 = 40
10 - 70 = 40
I am looking for two functions, one to add, one to subtract. I don't really care which language but python or java is preferred. Thanks for any help!
# define the range
start = 0
end = 93
# this function accepts positive and negative numbers in x
def mover(current_place, x):
locate = current_place + x
locate = locate % (end-start) # if x > the range
if locate > end:
locate = locate - end
if locate < start:
locate = locate + end
return locate
if __name__ == "__main__":
current_place = 50
print(current_place) #50
current_place = mover(current_place, 10)
print(current_place) #60
current_place = mover(current_place, -20)
print(current_place) #40
current_place = mover(current_place, -50)
print(current_place) #83
current_place = mover(current_place, 220)
print(current_place) #24
I'm afraid we have to add more specific information to your question:
is the boundary inclusive or exclusive?
are we talking abount only interger numbers or floating numbers?
If you want to use your routine as library function for many purposes, it's maybe a good idea to define one end as inclusive and the other as exclusive.
The following (incomplete) Java program shows the direction of solution as well as the problem with boundaries: whenever the boundary is hit, it flips to other end of your value frame:
public class FramedAddSub {
int min;
int max;
int value;
public FramedAddSub(int min, int max, int value) {
this.min = min;
this.max = max;
this.value = value;
}
public FramedAddSub add(int toAdd) {
final int diff = max - min;
if (toAdd >= 0) {
// step 1: norm to zero
value -= min;
// step 2: rest of division
value = (value + toAdd) % diff;
// step 3: re-norm to old offset
value += min;
} else {
// step 1: norm to zero from other end
value -= max;
// step 2:
value = (value + toAdd) % diff;
// step 3: re-norm back
value += max;
}
return this;
}
public static void main(String[] args) {
FramedAddSub test = new FramedAddSub(20, 50, 20);
System.out.println("start: " + test.value);
test.add(10);
System.out.println("+10: " + test.value);
test.add(20);
System.out.println("+20: " + test.value);
test.add(1);
System.out.println("+1: " + test.value);
test.add(30);
System.out.println("+30 should just turn around circle: " + test.value);
test.add(-1);
System.out.println("-1: " + test.value);
test.add(-1);
System.out.println("-1: " + test.value);
test.add(-30);
System.out.println("-30 should just turn around circle: " + test.value);
}
}
Try this in python:
ans = abs(a + b) % 50
You need to pass a and b as negative numbers, if you want to do a substraction.
I had the same problem and I use this solution for integers.
( ( (X ± Y) - MaximumValue ) % ( MaximumValue - MinimumValue ) ) + MinimumValue
% : modulo/reminder operator
Update:
The expression above works perfectly on Excel, but according to Microsoft it calculates the modulo like this
MOD(n, d) = n - d*INT(n/d)
Combine this two we got
((X+Y)-Mx)-(Mx-Mn)*Math.floor(((X+Y)-Mx)/(Mx-Mn))+Mn
Mx: MaximumValue
Mn: MinimumValue
This question already has answers here:
Differences between System.out.println() and return in Java
(4 answers)
Closed 3 years ago.
I have to write a method int sumBeyond(int k) to find the least n such that the sum of the natural numbers smaller than n exceeds k.
However, when I try to test the method it doesn't return any value.
public static int sumBeyond(int k){
int i=1;
int sum=0;
while(i<k){
sum=sum+i;
i=i+1;
}
return sum;
}
I tried calling the function this way, in the main method:
sumBeyond(100);
int sum100 = sumBeyond(100);
System.out.println("Sum is " + sum100);
Then small improvements:
public static int sumBeyond(int k) {
int i = 1;
int sum = 0;
while (i < k) {
sum += i;
++i;
}
return sum;
}
public static int sumBeyond(int k) {
int sum = 0;
for (int i = 1; i < k; ++i) {
sum += i;
}
return sum;
}
public static int sumBeyond(int k) {
// return (k - 1) * (1 + k - 1) / 2;
return (k - 1) * k / 2;
}
To solve the problem stated:
Find n such that sum upto n-1 >= k' where k' is k - 1.
Sum upto n-1 is (n - 1) * n / 2 >= k'
So we get:
x² - x - 2k'
------------ >= 0
2
Solution for = 0:
a = 1/2
b = -1/2
c = -2k'
_________
-b +/- V b² - 4ac
x = ------------------
2a
x = 1/2 +/- sqrt(1/4 + 4k'/4) =
= 1/2 +/- 1/2 . sqrt(1 + 4k')
Positive x
x = 1/2 + 1/2 . sqrt(4k' + 1)
public static int sumBeyond(int k) {
double x = (Math.sqrt(4 * (k-1) + 1) + 1) / 2;
return (int) Math.ceil(x);
}
The solution should be given the math as comment.
If I got your question right, you want to find the least n such that the sum of the natural numbers smaller than n exceeds k and thus, you shouldn't return the sum itself, because it is not n but needs to be calculated in order to find the smallest n.
You can do it the following way:
public static int sumBeyond(int k) {
int n = 0;
int sum = 0;
for (int i = 0; i < k; i++) {
// provide an intermediate sum (the one before this step) for logging purpose
int intermediateSum = sum;
// sum up
sum += i;
// set the return value to the current "natural number"
n = i;
// print some detailed debug log
System.out.println("sum:\t" + sum +
" (" + intermediateSum + " + " + i + ")\t——>\tn = " + n);
// exit the loop if the sum is greater than k
if (sum >= k) {
break;
}
}
return n + 1;
}
Calling it in a main like this
public static void main(String[] args) {
int k = 100;
System.out.println("The least n" +
+ "such that the sum of the natural numbers smaller than n exceeds "
+ k + " is " + sumBeyond(k));
}
will print
sum: 0 (0 + 0) ——> n = 0
sum: 1 (0 + 1) ——> n = 1
sum: 3 (1 + 2) ——> n = 2
sum: 6 (3 + 3) ——> n = 3
sum: 10 (6 + 4) ——> n = 4
sum: 15 (10 + 5) ——> n = 5
sum: 21 (15 + 6) ——> n = 6
sum: 28 (21 + 7) ——> n = 7
sum: 36 (28 + 8) ——> n = 8
sum: 45 (36 + 9) ——> n = 9
sum: 55 (45 + 10) ——> n = 10
sum: 66 (55 + 11) ——> n = 11
sum: 78 (66 + 12) ——> n = 12
sum: 91 (78 + 13) ——> n = 13
sum: 105 (91 + 14) ——> n = 14
The least n such that the sum of the natural numbers smaller than n exceeds 100 is 15
I really hope I got this right, still not sure...
Oh, and if 0 is not a natural number, start iterating at 1.
So as has been noted above, the issue was not that your method was not returning something, but that you were doing nothing with what was returned. Also, as noted above, you were focused on finding the sum, but that is not actually what the question asked.
I am sympathetic to your use of a while loop here since it may not execute at all and since you don't know a priori how many times it will run. So I rewrote it to check the right things and adapted the main from deHaar to exercise it. That allowed me to hand check the answers, because some of the cases of equality and need for "numbers less than" rather than "numbers less than or equal to" were subtle.
The math teacher in me really likes the quadratic formula approach from Joop Eggen; it's just harder to get right (and indeed, if I were going to do it, I would end up testing that it's consistent with what I have here).
public class ShadesOfLittleGauss {
public static int sumBeyond(int k) {
int i = 1; //have summed (trivially) all natural numbers less than 1 so far
int sum = 0;
while (sum <= k) { //needs to exceed, so <=
sum = sum + i;
i = i + 1;
}
return i;
}
public static void main(String[] args) {
for (int k = -1; k < 10; k++) {
System.out.println("The least number " +
"such that the sum of the natural numbers smaller than n exceeds " +
k + " is " + sumBeyond(k));
}
}
}
output (you can hand check these are correct as stated):
The least number such that the sum of the natural numbers smaller than n exceeds -1 is 1
The least number such that the sum of the natural numbers smaller than n exceeds 0 is 2
The least number such that the sum of the natural numbers smaller than n exceeds 1 is 3
The least number such that the sum of the natural numbers smaller than n exceeds 2 is 3
The least number such that the sum of the natural numbers smaller than n exceeds 3 is 4
The least number such that the sum of the natural numbers smaller than n exceeds 4 is 4
The least number such that the sum of the natural numbers smaller than n exceeds 5 is 4
The least number such that the sum of the natural numbers smaller than n exceeds 6 is 5
The least number such that the sum of the natural numbers smaller than n exceeds 7 is 5
The least number such that the sum of the natural numbers smaller than n exceeds 8 is 5
The least number such that the sum of the natural numbers smaller than n exceeds 9 is 5
UPDATE: I did solve the quadratic and came up with the following which agrees with the simpler approach.
public static int sumBeyond2(int k) {
if (k < 0) { //do not take squareroots of negatives
return 1;
}
double x = -1.0 / 2 + Math.sqrt(1 + 8 * k) / 2; //from solving quadratic inequality n(n+1)/2.0 > k
if (Math.abs(Math.round(x) - x) < 0.0000001) { //special case, it is an integer, so ceil won't reliably add 1
return 1 + 1 + (int) Math.round(x);
}
return 1 + (int) Math.ceil(x); //adding 1 because of wording, integers less than, ceil because needs to exceed k
}
I have a mathematical formula and had a hard time to understand this and converted in to Java code.
[Attached Image is the formula I have to solve]
I have written some code and it is not helping much. In the formula I have value for C and P and need to find N.
Below is the code I have used
public static Double sigmaSum(int c, int n, Double p){
Double sum = 0.00;
for(int i=0; i<c; i++){
for(int j=i; j<n;j++){
sum += ((Math.pow(p, j)) * (Math.pow((1-p), (n-j))));
}
I have a corresponding excel formula but I don't know how to convert it into java.
Option Explicit
Dim intLTPD, intCL, intC, intCalcF, intK, intComboNum, intComboDen1, intI, intJ, intComboDen2, intCombo, intL As Integer
Dim lngSampleSize As Long
Sub macBinSampPlan()
'
intLTPD = (Range("B1") / 100)
intCL = Range("B2") / 100
'intC = Int(Range("B3"))
Cells.Range("A6").Select
intCombo = 0
intCalcF = 0
intI = 0
intJ = 0
For intC = 0 To 10
For intI = 1 To 10000
For intJ = 0 To intC
If intI >= intJ Then
intCombo = Application.WorksheetFunction.Combin(intI, intJ)
intCalcF = intCalcF + (intCombo * (Application.WorksheetFunction.Power(intLTPD, intJ)) * (Application.WorksheetFunction.Power((1 - intLTPD), (intI - intJ))))
Else
Exit For
End If
Next intJ
If (intCalcF - (1 - intCL)) / intCalcF <= intLTPD Then
lngSampleSize = intI
Exit For
Else
intCombo = 0
intCalcF = 0
End If
Next intI
ActiveCell = intC
ActiveCell.Offset(0, 1).Range("A1").Select
ActiveCell = lngSampleSize + 1
ActiveCell.Offset(1, -1).Range("A1").Select
Next intC
End Sub
I am working on this around a week and not able to get it resolved.It should be a great help if some body can solve this. Thanks in advance.
Vivek
The way your implement your binomial seems to be wrong. According to your formula, the code should rather be:
public static Double sigmaSum(int c, int n, Double p){
Double sum = 0.00;
for(int i=0; i<c; i++){
sum += ((CombinatoricsUtils.binomialCoefficientDouble(n,i)) * (Math.pow(p, i)) * (Math.pow((1-p), (n-i))));
}
}
I have not tested the code yet.
I am using the following code, it generates numbers randomly but the problem is, I am not able to figure out why does not it generate the number 1
int ran, g, d, col, ran2;
double y = 1000 * (Double.parseDouble(t2.getText()));
int x = (int) y;
d = Integer.parseInt(anum.getText());
double c = 10;
int prevrandom = Integer.parseInt(lnum.getText());
lnum.setText("");
lnum.setVisible(true);
for (g = 0; g==0;) {
d = Integer.parseInt(anum.getText());
ran = (int) (Math.random() * (c)); // Random Number Creation Starts
if (ran > (c / 10)) {
g = 1;
ran2 = ((int) (Math.random() * 10)) % 2;
if (ran2 == 1) {
ran = ran * (-1);
}
d = d + ran;
if (d < 0) {
ran = ran * (-1);
d = d + (2 * ran);
}
int a = d - ran;
if(prevrandom==ran){
g=0;
}
if(g==1){
lnum.setText("" + ran);
}
}
}
I call this function(button) from somewhere. The problem comes when the sum ('a') becomes 4, according to my conditions it shouldn't allow any number other than 'one' and thus it goes into infinite loop.
I am talking about ran variable. Which I get after multiplying Math.random with 10^x where x is a positive integer.
Here ran2 is a number with value 1 or 0. As I multiply Math.Random with 10 which gives a 1 digit number and I mod it with 2.
THis is a 14 year old boy new to java. it would be greatful of people out here to help rather than discourage.
Look at the Javadoc:
Returns a double value with a positive sign, greater than or equal to
0.0 and less than 1.0. Returned values are chosen pseudorandomly with (approximately) uniform distribution from that range.
If you need integer random numbers, you might be better off with java.util.Random. To generate a random integer in the range a..b (inclusively), you can use
Random random=new Random();
int rnd=a+random.nextInt(b-a+1);
The problem lies in the code
if (ran > (c / 10)) {
The random number gets created which is even equal to one; but here due to the sign '>' it gets rejected.
Use '>=' instead.
ran = (int) (Math.random() * (c)); where c is from 10 to 10^x
This can be 1 as follows.
int c = 1000;
for (int i = 0; i < 1000; i++) {
int count = 0;
int ran;
do {
ran = (int) (Math.random() * (c)); // where c is from 10 to 10^x
count++;
} while (ran != 1);
System.out.println("count: " + count);
}
prints sometime like
count: 1756
count: 86
count: 839
count: 542
count: 365
....
count: 37
count: 2100
count: 825
count: 728
count: 1444
count: 1943
It returns 1 a thousand time in less than a second.