Recursive Summation Method - java

I am currently working on a recursive summation method in java, this is my code so far however I am running into some issues during runtime with ArrayIndexOutOfBoundsException. This is the completed code to this point.
import java.util.Scanner;
public class Summation {
public static void main(String[] args) {
input();
}
private static void input() {
Scanner scanner = new Scanner(System.in);
System.out.print("Lower bound: ");
int lower = scanner.nextInt();
System.out.print("Upper bound: ");
int upper = scanner.nextInt();
arrayForm(upper, lower);
}
private static void arrayForm(int upper, int lower) {
int b = 0;
int a = Math.abs(lower) + Math.abs(upper);
int array[] = new int[a];
for (int i = 0; i < array.length; i++) {
array[i] = lower + i;
}
summation(array, b);
}
public static int summation(int array[], int b) {
if (b > array.length) {
System.out.println("Cannot continue");
return 0;
} else{
int result = array[b] + summation(array, b + 1);
System.out.println("recursion call: " + b);
System.out.println("sum: " + result);
System.out.println("parameter 1: " + array[b]);
System.out.println("parameter 2: " + array[b + 1]);
return result;
}
}
}

There are two errors in your code:
fix b >= array.length: If i give the bounds 1 to 10 The array has 11 elements. That leads to an index of 0 to 10. If you call array[b] with b = array.length, length is 11 and that's out of bounds.
array.length - 1: Becouse you are calling summation(array, b + 1) the index b must not exceed max-index - 1. E.g. bounds: 1 to 10. So summation(array, 10) calls summation(array, 11) and thats the last element in the array.
so the summation(a,b) function looks like this:
public static int summation(int array[], int b) {
if (b >= array.length - 1) {
System.out.println("Cannot continue");
return 0;
} else {
int result = array[b] + summation(array, b + 1);
System.out.println("recursion call: " + b);
System.out.println("sum: " + result);
System.out.println("parameter 1: " + array[b]);
System.out.println("parameter 2: " + array[b + 1]);
System.out.println();
return result;
}

In the else-part:
System.out.println("parameter 2: " + array[b + 1]);
requires for a valid index:
b + 1 < array.length
b < array.length - 1
But the if-else merely guarantees:
b <= array.length
b < array.length + 1
Hence it should be
if (b >= array.length - 1) { ... } else { ... }
Amd then there is probably an error in the logic if you intended:
sum of lower + (lower + 1) + (lower + 2) + ... + upper
These are (upper - lower + 1) terms of average (upper + lower)/2:
int sum = (upper - lower + 1) * (upper + lower) / 2;
Either one of the factors is even as they differ by 2*lower+1, so integer calculation is okay: integer division by does not loose anything.
Example
sum(7, 9) = (9 - 7 + 1) * (9 + 7) = 3 * 16 = 48

Related

Java: changing the order of lines with while-loop

I am new to programming and I would like to ask what should I do so that the final value of k will appear before the values of a, when I try to put it inside the loop it repeats the statement and when I put it before the loop, its value is 0.
System.out.printf("Input an integer: ");
int a = in.nextInt();
int k = 0;
System.out.print(a);
while(a > 1)
{
if(a % 2 == 0)
a = a / 2;
else
a = 3 * a + 1;
System.out.printf(", " + a);
k++;
}
System.out.println("\nk = " + k);
Output:
Input an integer: 10
10, 5, 16, 8, 4, 2, 1
k = 6
You could try:
System.out.printf("Input an integer: ");
int a = in.nextInt();
int k = 0;
String str_a = "";
System.out.print(a);
while(a > 1)
{
if(a % 2 == 0)
a = a / 2;
else
a = 3 * a + 1;
str_a += ", " + String.valueOf(a);
k++;
}
System.out.println("k = " + k);
System.out.println("a = " + str_a);

Print the number of ways in which you can pay the amount as described

In how many ways, can you pay N dollar with 1 dollar, 2 dollar & 5 dollar denominations, in such a way that
the number of 1 dollar coins are always greater than that of 2 dollar coins and number of 2 dollar coins are always greater than that of 5 dollar coins.
Note: At least one coin should be given from each denomination.
Constraints 1 <= N <= 100
I tried something like this, but am not able to get how to check the constraints
private static void numberOfWays(int number) {
int one = 0, two = 0;
int five = (number - 4) / 5;
if (((number - 5 * five) % 2) == 0)
{
one = 2;
}
else
{
one = 1;
}
two = (number - 5 * five - one) / 2;
System.out.println (one + two + five);
System.out.println (five);
System.out.println (two);
System.out.println (one);}
You could try something like this:
IntStream.rangeClosed(1, 100).forEach(target -> {
final int max1 = (target + 1 - 1) / 1;
final int max2 = (target + 2 - 1) / 2;
final int max5 = (target + 5 - 1) / 5;
IntStream .rangeClosed( 1, max5).forEach(count5 -> {
IntStream .rangeClosed(count5 + 1, max2).forEach(count2 -> {
IntStream.rangeClosed(count2 + 1, max1).forEach(count1 -> {
final int sum = count5*5 + count2*2 + count1*1;
if (sum == target) {
System.out.println("Target.: " + target + " -> " + count5 + "*5$ " + count2 + "*2$ " + count1 + "*1$");
}
});
});
});
System.out.println();
});
...but, as others have pointed out, your constraints make a solution for some amounts impossible.
Here's a variation of this theme, giving a solution for all N...
IntStream.rangeClosed(1, 100).forEach(target -> {
final int max1 = (target + 1 - 1) / 1;
final int max2 = (target + 2 - 1) / 2;
final int max5 = (target + 5 - 1) / 5;
for (int count1= max1; count1 > 0; count1--) {
for (int count2=Math.min(max2, count1 - 1); count2 > 0; count2--) {
for (int count5=Math.min(max5, count2 - 1); count5 > 0; count5--) {
final int sum = count5*5 + count2*2 + count1*1;
if (sum == target) {
System.out.println("Target..............: " + target + " -> " + count5 + "*5$ " + count2 + "*2$ " + count1 + "*1$");
return; // Note.: solution found, exit from Consumer, NOT Method!
}
}
}
}
/*
* Fallback 1: at least one of each denomination...
*/
for (int count1=max1; count1 > 0; count1--) {
for (int count2=max2; count2 > 0; count2--) {
for (int count5=max5; count5 > 0; count5--) {
final int sum = count5*5 + count2*2 + count1*1;
if (sum == target) {
System.out.println("Target (fallback 1).: " + target + " -> " + count5 + "*5$ " + count2 + "*2$ " + count1 + "*1$");
return; // Note.: solution found, exit from Consumer, NOT Method!
}
}
}
}
/*
* Fallback 2: "anything goes"...
*/
for (int count1=max1; count1 >= 0; count1--) {
for (int count2=max2; count2 >= 0; count2--) {
for (int count5=max5; count5 >= 0; count5--) {
final int sum = count5*5 + count2*2 + count1*1;
if (sum == target) {
System.out.println("Target (fallback 2).: " + target + " -> " + count5 + "*5$ " + count2 + "*2$ " + count1 + "*1$");
return; // Note.: solution found, exit from Consumer, NOT Method!
}
}
}
}
System.out.println("Target..............: " + target + " NO Solution possible!");
});
The constraints are interesting.
"At least one coin should be given from each denomination" means that there are no solutions for N < 7.
"The number of 1 dollar coins are always greater than that of 2 dollar coins and number of 2 dollar coins are always greater than that of 5 dollar coins" means that numFives = 1, numTwos = 2, and numOnes = 3 to start, so there are no solutions for N < 12.
This satisfies both constraints.
Knowing that, how do you plan to attack it? Brute force?
It sounds like a variation on the knapsack problem. Maybe you can read about that.
I think simplex method and dynamic programming with constraints is your best bet.

How do i make java output number decreasing order

So far this is my code and I need it to output from 66 down to 11. Right now it does 11 upto 66.
public class ListNumbers {
public static void main(String[] args) {
//define limit
int limit = 66;
System.out.println("Printing Even numbers between 1 and " + limit);
for(int x=11; x <= limit; x++){
if(x != 44 && x != 22){
System.out.print(x + " ");
}
}
}
}
You just need to start from limit and ends when it reaches 11
for(int x = limit; x > 10; x--){
if(x! = 44 && x != 22){
System.out.print(x + " ");
}
}
You start the loop at the upper limit (66) and decrements down to the lower limit (1). Then you check if they are even or odd but only output the even numbers.
int lowerLimit = 1;
int upperLimit = 66;
System.out.println("Printing Even numbers between " + lowerLimit + " and " + upperLimit);
for (int x = upperLimit; x >= lowerLimit; x--)
{
if ((x & 1) == 0)
{
// even
System.out.print(x + " ");
}
else
{
// odd
}
}

Invert last bit

How can I invert the last bit in an int?
int a = 11;
System.out.print(a + " " + Integer.toBinaryString(a)) //11 1011
int b = invertLastBit(a);
System.out.print(b + " " + Integer.toBinaryString(b)); //10 1010
I wrote this:
static int invertLastBit(int i)
{
String s = Integer.toBinaryString(i);
if (s.charAt(s.length()-1) == '0'){
s = s.substring(0,s.length() - 1);
s = s+"1";
}else if (s.charAt(s.length()-1) == '1') {
s = s.substring(0, s.length() - 1);
s = s + "0";
}
return Integer.parseInt(s, 2);
}
But how should I rewrite invertLastBit() ?
You can use bitwise XOR :
int x = 5; // 101
x = x ^ 1; // 100
Using your original example :
int a = 11;
System.out.println (a + " " + Integer.toBinaryString(a)); //11 1011
int b = a^1;
System.out.println (b + " " + Integer.toBinaryString(b)); //10 1010
You don't even have to worry about converting to binary.
If the number if odd, the last bit has to be one, thus, subtract 1 from the number.
Otherwise, if the number is even, the last bit has to be 0, add 1 to the number.
That's all.
static int invertLastBit(int i){
if(i % 2 != 0) { //thanks harold
return i - 1;
} else {
return i + 1;
}
}
It is not difficult to reason about why this works.

Addition of two very long integers

For practice, I am trying to add two very long integers by placing them in arrays and adding the corresponding elements in the arrays. However, when trying to add the carry over, I'm having problems (I.e., the carry over is the 1, that for instance, you add to the tens place when you do 199 + 199 = 398).
When doing 167 + 189 I get the right answer which is 356. However, for this very example though (199 + 199), I'm getting 288 instead of 398. My question is, why do I get an incorrect answer when I do 199 + 199, if the carry over works well when I do 167 + 189?
if (stringNumOneLength == stringNumTwoLength)
{ int answer;
int carryOver = 0;
int answerArray[] = new int[stringNumOneLength + 1];
for (int i = 1; i <= stringNumTwoLength; i = i + 1)
{
answer = Character.getNumericValue(stringNumOne.charAt(stringNumOneLength - i)) + Character.getNumericValue(stringNumTwo.charAt(stringNumTwoLength - i) + carryOver);
System.out.println(answer);
if (answer >= 10)
{
for (int j = 0; j <= 9; j = j + 1)
{
if (10 + j == answer)
{
carryOver = 1;
answer = j;
System.out.println("The carryover is " + carryOver + ".");
}
}
}
else
{
carryOver = 0;
}
answerArray[stringNumOneLength + 1 - i] = answer;
}
System.out.println(Arrays.toString(answerArray));
}
The output is the following:
[1, 9, 9]
[1, 9, 9]
18
The carryover is 1.
8
2
[0, 2, 8, 8]
You're adding the carry to the character rather than to its value:
... + Character.getNumericValue(stringNumTwo.charAt(stringNumTwoLength - i) + carryOver);
You want to move the right parent inside the +.
Note your for loop is unnecessary. This does the same thing:
if (answer >= 10)
{
answer -= 10;
carryOver = 1;
System.out.println("The carryover is 1.");
}
else ...
In case you're interested in an idiomatic solution:
public class Test {
public String add(String a, String b) {
StringBuilder r = new StringBuilder();
int carry = 0;
for (int ia = a.length() - 1, ib = b.length() - 1; ia >= 0 || ib >= 0; ia--, ib--) {
int aDigit = ia < 0 ? 0 : Character.getNumericValue(a.charAt(ia));
int bDigit = ib < 0 ? 0 : Character.getNumericValue(b.charAt(ib));
int sum = carry + aDigit + bDigit;
if (sum >= 10) {
sum -= 10;
carry = 1;
}
else {
carry = 0;
}
r.append(Character.forDigit(sum, 10));
}
if (carry > 0) {
r.append('1');
}
return r.reverse().toString();
}
public void run() {
System.out.println("789 + 89 = " + add("789", "89"));
System.out.println("12 + 128 = " + add("12", "128"));
System.out.println("999 + 999 = " + add("999", "999"));
}
public static void main(String[] args) {
new Test().run();
}
}
The parenthesis on this line:
answer = Character.getNumericValue(stringNumOne.charAt(stringNumOneLength - i)) + Character.getNumericValue(stringNumTwo.charAt(stringNumTwoLength - i) + carryOver);
are wrong. Notice how the + carryOver is within the call to Character.getNumericValue.

Categories

Resources