Adding integers in Range not working for negative numbers - java

I am trying to do this exercise:
Write a program that asks the user for N and M and adds up the
integers between N and M using the formula
SUM(N to M) = SUM( 1 to M ) - SUM( 1 to N-1 )
I can get this to work for positive numbers but not negative numbers.
static int method2(int n, int m) {
int sum = 0;
int sum2 = 0;
for (int i = 1; i <= m; i++) {
sum = sum + i;
}
for (int i = 1; i <= n - 1; i++) {
sum2 = sum2 + i;
}
System.out.println("sum: " + sum + ", sum2: " + sum2);
return sum = sum - sum2;
}
e.g.
using n = -1, m = 1 returns sum = 1.
Using n = -5, m = 5 returns sum = 15.
Using n = 5, m = -5 returns sum = -10.
These should all return 0.
e.g.
Using n = -2, m = 3, returns sum = 6.
Using n = -2, m = 4, returns sum = 10.
The problem is with for (int i = 1; i <= n - 1; i++), specifically i <= n - 1 because when n-1 <= 0 this will not run. I just can't think of a way around it.

Your formula
SUM(N to M) = SUM( 1 to M ) - SUM( 1 to N-1 )
Doesn't really make sense for negative values. If you give that up you can make your program simpler. We very often start for loops at 0 or 1 but that doesn't have to be the case. You could instead start your loop at a n which might be negative:
static int method2(int n, int m) {
int sum = 0;
for (int i = n; i <= m; i++) {
sum = sum + i;
}
System.out.println("sum: " + sum);
return sum;
}

You could always check before if n < 0.
And then do another reverse loop for negative numbers.
e.g.
int sum = 0;
if(m < 0){
for(int i = 0; i >= m; i--) {
sum += i;
}
} else {
for (int i = 1; i <= m; i++) {
sum += i;
}
}

If you really have to use that formula you could use instead of:
for (int i = 1; i <= m; i++) {
the following code which changes the index either by 1 or by -1
for (int i = 1; i <= m; i+=(int)Math.signum(m-1+0.1)) {
(added 0.1 such that in case m is 1 the result is positive and not 0)
Ofc you should do the same for n.

Related

Implement fibonacci using recursion without using java.bignumber

I am trying to implement the Fibonacci sequence without using the BigInteger Class import, hence I rewrite my own add method, and I spent two days on it, But I don't know why the answer of the first 6 numbers is correct and the rest of the answers are the reverse of the correct one(eg. n = 7, my answer: 31 the correct one: 13; n = 15, my answer = 016, correct one= 610), and when n becomes greater, the answer gets totally wrong(not even the reversed of the correct one. This happened when n >= 25).
Any advice would be appreciated!
The following is my output:
The 0th Fibonacci number is :
0
The 1th Fibonacci number is :
1
The 2th Fibonacci number is :
1
The 3th Fibonacci number is :
2
The 4th Fibonacci number is :
3
The 5th Fibonacci number is :
5
The 6th Fibonacci number is :
8
The 7th Fibonacci number is :
31
The 8th Fibonacci number is :
12
The 9th Fibonacci number is :
43
The 10th Fibonacci number is :
55
The 11th Fibonacci number is :
98
The 12th Fibonacci number is :
441
The 13th Fibonacci number is :
332
The 14th Fibonacci number is :
773
The 15th Fibonacci number is :
016
The 16th Fibonacci number is :
789
The 17th Fibonacci number is :
7951
The 18th Fibonacci number is :
4852
The 19th Fibonacci number is :
1814
The 20th Fibonacci number is :
5676
The 21th Fibonacci number is :
64901
The 22th Fibonacci number is :
11771
The 23th Fibonacci number is :
75682
The 24th Fibonacci number is :
86364
The 25th Fibonacci number is :
52047
The 26th Fibonacci number is :
393021
The 27th Fibonacci number is :
814491
The 28th Fibonacci number is :
118413
The 29th Fibonacci number is :
922905
The 30th Fibonacci number is :
040428
And the following is my code:
package com.example.helloworld;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
public class Fibonacci_Recursive{
public static void main(String[] args) {
long start = System.nanoTime();
long time = 0L;
for(int i = 0; time <= 60L; i++)
{
Fibonacci_Recursive fr = new Fibonacci_Recursive(i);
time = ((System.nanoTime() - start) / 1000_000_000);
}
}
private Fibonacci_Recursive(int n){
System.out.println("The " + n + "th Fibonacci number is :");
if (n <= 1){
System.out.println(n);
}
else {
int[] finalResult = getF(n);
String st = "";
for (int i = 0; i < finalResult.length; i++){
st = finalResult[i] + st;
}
System.out.println(st);
}
}
private int[] getF(int n){
int[] head = new int[1];
if (n <= 1) {
head[0] = n;
return head;
}
return add(getF(n - 1), getF(n - 2));
}
private int[] add(int[] s1, int[] s2){
int carrier = 0;
ArrayList<Integer> result = new ArrayList<>();
int[] array1 = s1;
int[] array2 = s2;
array1 = reverseGeneralArray(array1);
array2 = reverseGeneralArray(array2);
int min = array2.length;
int min2 = array1.length;
if(min2 > min) {
for (int i = 0; i < min; i++) {
int x = array1[i] + array2[i];
result.add((x + carrier) % 10);
carrier = x / 10;
}
for (int j = 0; j <= min2 - min - 1; j++) {
int index = min;
result.add((array1[index] + carrier) % 10);
carrier = (array1[index] + carrier) / 10;
index++;
}
if (carrier > 0) {
result.add(carrier);
}
Collections.reverse(result);
return convertIntegers(result);
}
else if(min2 < min)
{
for(int i = 0; i < min2; i ++){
int x = array1[i] + array2[i];
result.add((x + carrier) % 10);
carrier = x / 10;
}
for(int j = 0; j <= min - min2 - 1; j++){
int index = min2;
result.add((array2[index] + carrier) % 10);
carrier = (array2[index] + carrier) / 10;
index++;
}
if (carrier > 0) {
result.add(carrier);
}
Collections.reverse(result);
return convertIntegers(result);
}else {
for (int i = 0; i < min; i++) {
int x = array1[i] + array2[i];
result.add((x + carrier) % 10);
carrier = x / 10;
}
if (carrier > 0) {
result.add(carrier);
}
Collections.reverse(result);
return convertIntegers(result);
}
}
private static int[] convertIntegers(ArrayList<Integer> integers)
{
int[] ret = new int[integers.size()];
for (int i=0; i < integers.size(); i++)
{
ret[i] = integers.get(i);
}
return ret;
}
private int[] reverseGeneralArray(int[] x){
int[] newX = new int[x.length];
for(int i = 0; i < x.length; i++){
newX[i] = x[x.length - i -1];
}
return newX;
}
}
You miss building the result, you concatenate wrong (reverse) way String st from the int[] finalResult:
private Fibonacci_Recursive(int n) {
...
for (int i = 0; i < finalResult.length; i++) {
//Replaced st = finalResult[i] + st by
st = st + finalResult[i];
}
...
}
Extra: Consider, when concatenating strings in a loop, since concatenation copies the whole string, to use StringBuilder:
StringBuilder st = new StringBuilder();
for (int i = 0; i < finalResult.length; i++) {
st.append(finalResult[i]);
}
Update: Starting from 25, an error becomes evident: the carrier is not right when the sum of two digits is equal to 10 (74025 instead of 75025). The bug is at the add method,where the carrier should be calculated as:
carrier = (x + carrier) / 10;
i.e.: you have to take into account previous carrier.

Running sum of an ArrayList with 2 possible operations

I am trying to create a program insert two possible operations (* and +) in between inputed numbers and keep track of the total. The program simply reads from left to right so therefor do not apply BEDMAS
For instance if I inputed: 1 2 3
The output would be 1 + 2 + 3 -> Sum = 6
Or output would be 1 + 2 * 3 -> Sum = 9
Or output would be 1 * 2 + 3 -> Sum = 5
Etc
I am having difficulty because my program continues to try to numbers.remove() from an empty ArrayList(numbers).
public static void calculate(ArrayList<Integer> numbers, int target){
ArrayList<Integer> temp_array = new ArrayList<Integer>(numbers);
int sum = 0;
int n = (numbers.size() - 1);
System.out.println("This is where we calcutale L");
for (int i = 0; i < Math.pow(2, n); i++) {
String bin = Integer.toBinaryString(i);
while (bin.length() < n)
bin = "0" + bin;
char[] chars = bin.toCharArray();
char[] charArray = new char[n];
while(charArrayCount < Math.pow(2,n)){
for (int j = 0; j < chars.length; j++) {
charArray[j] = chars[j] == '0' ? '+' : '*';
}
for(char c : charArray){
int current = numbers.get(0);
if (c == '+'){
sum = sum + current;
}
numbers.remove(0);
System.out.println(sum);
}
numbers = temp_array;
sum = 0;
}
}
}

Find Number Equal to the sum of factorial of each of its digits eg:145

Find Number Equal to the sum of factorial of each of its digits eg:145
From 1 to 200
I tried this :
public static void main(String[] args) {
int i = 0, x = 0, temp, temp1, digit = 0, factorial = 1, sum = 0;
System.out.println("Special Numbers from 1 to 10,000 -:");
for (i = 1; i <= 200; i++) {
temp = i;
temp1 = i;
while (temp > 0) {
digit = temp % 10;
factorial = 1;
for (x = 1; x <= digit; x++) {
factorial *= x;//factorial of digit
}
sum += factorial;//sum of factorial of a all the digits of the number
temp = temp / 10;
}
if (sum == temp1) {
System.out.println(temp1);
}
}
}
So if i put i=145 it works but othervise i get the wrong output.
You forgot to make sum 0, so you only get the correct result for the first number you try. The line sum = 0; should go before while(temp>0){.
Your sum variable is declared outside the for block.
Each time you calculate a factorial sum get added to the previous sum and hence 1! + 4! + 5! will never be 145 in this case.
Try initializing it inside the loop to 0.
You need to initialize sum inside the for loop.
for(i=1;i<=200;i++){
sum = 0; //<--include this
temp = i;
temp1 = i;
while(temp>0){
digit = temp%10;
factorial =1;
for(x = 1;x<=digit;x++){
factorial*=x;//factorial of digit
}
sum+=factorial; //sum of factorial
temp = temp/10;
}
if(sum == temp1){
System.out.println(temp1);
}
}

Find Number of combinations possible

There are two letters "X" and "Y". A String of length N needs to be formed using those two letters.
How many number of combinations that can be possible where N should start with "Y" and no two or more consecutive "X" will be there?
Consider N = 7:
I approached the solution in the following manner:
My Solution:
[No. of combinations that start with letter "Y"] -[No:of combinations containing two consecutive X(n-1 possibilities) + No: of Combinations containing 3 consecutive X(n-1 possibilities)+.....]
=Math.pow(2,N-1)-[(N-2)(N-1)/2];
The problem is with the part I'm subtracting. Where I'm missing the elements which contains two consecutive "X" and total of 3 Xs in the String. Similarly 2 consecutive and total of 4 Xs.
I want to find a generic formula for finding no of Strings that are possible where no 'R' or more consecutive "X" will occur.
Please help me to find the solution for this.
For R = 1, similar to Fibonacci.
F(0) = F(1) = 1
F(N) = F(N-1) + F(N-2)
Best solution in Java.
static int func(int n) {
if (n < 1) return 0; // as you required, F(0) = 0
int n1 = 1, n2 = 1; // however, for F(2..) we must have F(0) = 1
for (int i = 2; i <= n; i++) {
int n0 = n1 + n2;
n2 = n1;
n1 = n0;
}
return n1;
}
To generalize the solution for R as the number of consecutive 'X' characters allowed, you would simply sum R + 1 previous elements in the sequence. As we have seen, for R = 1 the formula is F(N) = F(N-1) + F(N-2); now for R = 2 the formula is F(N) = F(N-1) + F(N-2) + F(N-3).
Thus we derive a function which takes any N and R.
static int func(int n, int r) {
if (n < 1) return 0; // as you required, F(0) = 0
if (n == 1 || r < 1) return 1;
int[] a = new int[r + 1];
a[r] = a[r-1] = 1; // however, for F(2..) we must have F(0) = 1
for (int i = 2; i <= n; i++) {
int x = a[0];
for (int j = 1; j <= r; j++) {
x += a[j];
a[j-1] = a[j];
}
a[r] = x;
}
return a[r];
}

Count zeros in the series of N numbers - Java

i want to count the number of zeros in a N-range of numbers starting from 0.
If the N is 100 means,then the range should starts from 0 to 100 then and the count should be 12.
Below code works till some 10^6
private static int calcZeros(String input){
int count = 0;
int n = Integer.parseInt(input);
for(int i = 0;i<=n;i++){
count += String.valueOf(i).replaceAll("[a-zA-Z_1-9]","").trim().length();
}
return count;
}
If the N exceeds 10^6, it hangs,Obiviously, for loop runs for long duration.
My Question here is ,this is right approach to find the zeros count?
Suggest me some fastest way to do the count.
This is (semi)combinatoric problem.
For example imagine 4-digit number :
We start to find all numbers with one zero.
At first position (from left to right), you can use numbers from 1-9, then 1-9, then 1-9 and then there will be 0, so there is no other option.
its 9*9*9 possibilities.
And that zero can be in three positions.
Then we have to find all 4-digit numbers with two zeroes.
We can use Binomial coefficient where (n k) in our case will be : n=number of digits - 1, k = number of zeroes and then you multiply it by 9*9, because thats all possibilities of other numbers.
I have to go now, so I cant finish it for any possible number, but for given number of digits, this shold be working :
public static void main(String[] args) {
System.out.println(numberZeroes(2));
}
public static int numberZeroes(int digits) {
int result = 0;
for (int i = 1; i <= digits - 1; i++) {
result += binomial(digits - 1, i) * Math.pow(9, digits - i);
}
return result+1;
}
public static int binomial(final int N, final int K) {
BigInteger ret = BigInteger.ONE;
for (int k = 0; k < K; k++) {
ret = ret.multiply(BigInteger.valueOf(N - k))
.divide(BigInteger.valueOf(k + 1));
}
return ret.intValue();
}
Instead of using strings and regex, it would be a lot faster to keep dividing by 10 - for example:
int i = 96;
int firstDigit = i / 10;
int secondDigit = i - firstDigit * 10;
For arbitrarily large numbers, you just need to replace that by a while loop.
This algorithm calculates the number of zeros until 1000000000 in 20 seconds. I hope it helps.
int count = 0;
int n = 1000000000;
for (int i = 0; i <= n; i++) {
int m= i;
do {
if (m % 10 == 0)
++count;
m = m / 10;
} while (m > 0);
}
System.out.println("count = " + count);
try this
int n = 1000000;
int count = 0 ;
Pattern pattern = Pattern.compile("0+");
for(int i = 0; i <= n ; i++ ) {
Matcher m = pattern.matcher(String.valueOf(i));
while (m.find()) {
count += m.group().length();
}
}
System.out.println(count);

Categories