int n is the number it will start from, int m is the number of multiples it will display.
its printing out the correct number of multiples but the multiples are not in the correct
order. For multiples(2, 5) it would print out 2, 4, 8, 16, 32. I understand why it is doing
that because it gets called with n+n. But I can't figure out how to add n correctly so it
displays 2, 4, 6, 8, 10, 12. I've tried with setting variable to n but it doesn't add right.
any help appreciated thNks! code below
public static void multiples(int n, int m)
{
if(m == 0){return;}
else{
System.out.print(n + ", ");
multiples(n + n, m - 1);}
}
}
You can print things in the correct order without adding any additional arguments by multiplying by m and doing the printing after the recursive call:
public static void multiples(int n, int m) {
if(m > 0) {
multiples(n, m - 1);
System.out.print((n * m) + ", ");
}
}
If you also want to lose the spurious trailing comma:
public static void multiples(int n, int m) {
if(m > 0) {
multiples(n, m - 1);
if(m > 1) {
System.out.print(", " + (n * m));
} else {
System.out.print(n);
}
}
}
Yet another option would be to return the values generated. That gives you more flexibility — you can then print them or use them in any subsequent operations as you see fit.
public static ArrayList<Integer> multiples(int n, int m) {
if(m > 0) {
ArrayList<Integer> result = multiples(n, m - 1);
result.add(n * m);
return result;
} else {
return new ArrayList<Integer>();
}
}
You can also send an initial value of 'n' as a parameter.
public static void multiples(int n, int m, int increment) {
if(m == 0) {
return;
} else {
System.out.print(n + ", ");
multiples(n + increment, m - 1, increment);
}
}
Actually, the method exactly does what it should do: print out the multiples. In your example the multiples are 2, 2 times 2 = 4, 2 times 2 times 2 = 8, 2 times 2 times 2 times 2 = 16, 2 times 2 times 2 times 2 times 2 = 32.
If you want to print out additions, it might be something like:
public static void multiplesHelper(int n, int m, int increment) {
if(m == 0) {
return;
} else {
System.out.print(n + ", ");
multiples(n + increment, m - 1, increment);
}
}
public static void multiples(int n, int m) {
multiplesHelper(n, m, n);
}
Example call would be then multiples(2, 6);
Related
Given an array of integers and number num.
I need to write a function public static int printExpr(int[] a, int num)
The function should print all the combinations that can give the number num with + or - operators, and to return the number of combinations.
The solution should be recursive
For example, for the given array:
{1, 3, 6, 2} and num=4
The output should be:
+3+1=4
+6-3+1=4
+2+3-1=4
+2+6-3-1=4
-2+6=4
5
My attempt:
public static void main(String[] args) {
int[] a = {1, 3, 6, 2};
System.out.println("\n" + printExpr(a, 4));
}
public static int printExpr(int[] a, int num) {
return printExpr(a, num, 0, 0, "");
}
public static int printExpr(int[] a, int num, int i, int sum, String s) {
if (i < 0 || i >= a.length)
return 0;
if (num == sum) {
System.out.println(s+"=4");
return 1 + printExpr(a, num, i , 0, "") ;
}
return printExpr(a, num, i + 1, sum, s + "")+printExpr(a, num, i + 1, sum + a[i], s + "+" + a[i]) + printExpr(a, num, i + 1, sum - a[i], s + "-" + a[i]) ;
}
My output:
+1+3=4
+1-3+6=4
2
I think that this question is kind of SubsetSum.
What am I missing?
Note LinkedList, HashSet, etc. are not allowed.
Firstly, a quick recap on recursion.
Every recursive implementation consists of two parts:
Base case - a part that represents a set of simple edge-cases which should terminate the recursion. The outcome for these edge-cases is known in advance. For this task, the first base case is when the target sum is reached and the expression has to be printed on the console and the return value has to be 1 (i.e. one combination was found). Another base case is a situation when array was fully discovered but the current sum differs from the target. For this case, return value will be 0.
Recursive case - the part of the method where recursive calls are made and where the main logic resides.
There are tree alternative branches of execution in the recursive case:
we can either ignore it;
contribute the target sum (add to the current string with + sign in front of it and subtract it from the target sum);
or subtract it from the sum (add to the current string with - sign in front of it and add it to the target sum).
In all these cases, we need to advance the index by 1 while calling the method recursively.
In order to found the total number of combinations, we need to introduce a variable (denoted as count in the code below). And the result returned by every recursive branch will contribute that variable.
The code might look like this:
public static int printExpression(int[] arr, int sum) {
return printExpression(arr, 0, "", sum);
}
public static int printExpression(int[] arr, int current, String expression, int sum) {
if (sum == 0) { // base case - target sum has been reached
System.out.println(expression);
return 1;
}
if (current == arr.length) { // base case - target sum wasn't reached and current index is out of bounds
return 0;
}
// recursive case
int count = 0;
count += printExpression(arr, current + 1, expression, sum); // ignore current element
count += printExpression(arr, current + 1, expression + "+" + arr[current], sum - arr[current]); // add current element (i.e. subtract from the target sum)
count += printExpression(arr, current + 1, expression + "-" + arr[current], sum + arr[current]); // subtract current element (i.e. increase the target sum)
return count;
}
public static void main(String[] args) {
int combinationCount = printExpression(new int[]{1, 3, 6, 2}, 4);
System.out.println("Number of combinations: " + combinationCount);
}
Output
+6-2
+1+3
+1-3+6
-1+3+2
-1-3+6+2
Number of combinations: 5
public static int printExpr(int[] a, int num) {
return printExpr(a, num, 0, 0, "");
}
public static int printExpr(int[] a, int num, int i, int sum, String s) {
if (i < 0 || i >= a.length){
if (num == sum) {
System.out.println(s + "=4");
return 1;
}
return 0;
}
if (num == sum) {
System.out.println(s+"=4");
return 1;
}
return printExpr(a, num, i + 1, sum, s)+printExpr(a, num, i + 1, sum + a[i], s + "+" + a[i]) + printExpr(a, num, i + 1, sum - a[i], s + "-" + a[i]) ;
}
Output:
+6-2=4
+1+3=4
+1-3+6=4
-1+3+2=4
-1-3+6+2=4
5
I had to write a program that will receive an int 'n' and another one 'd' - and will print the number n with commas every d digits from right to left.
If 'n' or 'd' are negative - the program will print 'n' as is.
I although had to make sure that there is no commas before or after the number and I'm not allowed to use String or Arrays.
for example: n = 12345678
d=1: 1,2,3,4,5,6,7,8
d=3: 12,345,678
I've written the following code:
public static void printWithComma(int n, int d) {
if (n < 0 || d <= 0) {
System.out.println(n);
} else {
int reversedN = reverseNum(n), copyOfrereversedN = reversedN, counter = numberLength(n);
while (reversedN > 0) {
System.out.print(reversedN % 10);
reversedN /= 10;
counter--;
if (counter % d == 0 && reversedN != 0) {
System.out.print(",");
}
}
/*
* In a case which the received number will end with zeros, the reverse method
* will return the number without them. In that case the length of the reversed
* number and the length of the original number will be different - so this
* while loop will end the zero'z at the right place with the commas at the
* right place
*/
while (numberLength(copyOfrereversedN) != numberLength(n)) {
if (counter % d == 0) {
System.out.print(",");
}
System.out.print(0);
counter--;
copyOfrereversedN *= 10;
}
}
}
that uses a reversNum function:
// The method receives a number n and return his reversed number(if the number
// ends with zero's - the method will return the number without them)
public static int reverseNum(int n) {
if (n < 9) {
return n;
}
int reversedNum = 0;
while (n > 0) {
reversedNum += (n % 10);
reversedNum *= 10;
n /= 10;
}
return (reversedNum / 10);
}
and numberLength method:
// The method receives a number and return his length ( 0 is considered as "0"
// length)
public static int numberLength(int n) {
int counter = 0;
while (n > 0) {
n /= 10;
counter++;
}
return counter;
}
I've been told that the code doesn't work for every case, and i am unable to think about such case (the person who told me that won't tell me).
Thank you for reading!
You solved looping through the digits by reversing the number, so a simple division by ten can be done to receive all digits in order.
The comma position is calculated from the right.
public static void printWithComma(int n, int d) {
if (n < 0) {
System.out.print('-');
n = -n;
}
if (n == 0) {
System.out.print('0');
return;
}
int length = numberLength(n);
int reversed = reverseNum(n);
for (int i = 0; i < length; ++i) {
int nextDigit = reversed % 10;
System.out.print(nextDigit);
reversed /= 10;
int fromRight = length - 1 - i;
if (fromRight != 0 && fromRight % d == 0) {
System.out.print(',');
}
}
}
This is basically the same code as yours. However I store the results of the help functions into variables.
A zero is a special case, an exception of the rule that leading zeros are dropped.
Every dth digit (from right) needs to print comma, but not entirely at the right. And not in front. Realized by printing the digit first and then possibly the comma.
The problems I see with your code are the two while loops, twice printing the comma, maybe? And the println with a newline when <= 0.
Test your code, for instance as:
public static void main(String[] args) {
for (int n : new int[] {0, 1, 8, 9, 10, 234,
1_234, 12_345, 123_456, 123_456_789, 1_234_567_890}) {
System.out.printf("%d : ", n);
printWithComma(n, 3);
System.out.println();
}
}
Your code seems overly complicated.
If you've learned about recursion, you can do it like this:
public static void printWithComma(int n, int d) {
printInternal(n, d, 1);
System.out.println();
}
private static void printInternal(int n, int d, int i) {
if (n > 9) {
printInternal(n / 10, d, i + 1);
if (i % d == 0)
System.out.print(',');
}
System.out.print(n % 10);
}
Without recursion:
public static void printWithComma(int n, int d) {
int rev = 0, i = d - 1;
for (int num = n; num > 0 ; num /= 10, i++)
rev = rev * 10 + num % 10;
for (; i > d; rev /= 10, i--) {
System.out.print(rev % 10);
if (i % d == 0)
System.out.print(',');
}
System.out.println(rev);
}
Are you allowed to use the whole Java API?
What about something as simple as using DecimalFormat
double in = 12345678;
DecimalFormat df = new DecimalFormat( ",##" );
System.out.println(df.format(in));
12,34,56,78
Using...
,# = 1 per group
,## = 2 per group
,### = 3 per group
etc...
It took me a bunch of minutes. The following code snippet does the job well (explanation below):
public static void printWithComma(int n, int d) { // n=number, d=commaIndex
final int length = (int) (Math.log10(n) + 1); // number of digits;
for (int i = 1; i < Math.pow(10, length); i*=10) { // loop by digits
double current = Math.log10(i); // current loop
double remains = length - current - 1; // loops remaining
int digit = (int) ((n / Math.pow(10, remains)) % 10); // nth digit
System.out.print(digit); // print it
if (remains % d == 0 && remains > 0) { // add comma if qualified
System.out.print(",");
}
}
}
Using (Math.log10(n) + 1) I find a number of digits in the integer (8 for 12345678).
The for-loop assures the exponents of n series (1, 10, 100, 1000...) needed for further calculations. Using logarithm of base 10 I get the current index of the loop.
To get nth digit is a bit tricky and this formula is based on this answer. Then it is printed out.
Finally, it remains to find a qualified position for the comma (,). If modulo of the current loop index is equal zero, the dth index is reached and the comma can be printed out. Finally the condition remains > 0 assures there will be no comma left at the end of the printed result.
Output:
For 4: 1234,5678
For 3: 12,345,678
For 2: 12,34,56,78
For 1: 1,2,3,4,5,6,7,8
I am trying to write the code for recursive function which prints every power of 2 from 1 to N, N is the argument of power function.
Function : int powers(n)
Currently I wrote this code:
int powers(int n) //here n=128
{
if(n==2)
{
System.out.print(n);
}
else if (n>2)
{
System.out.print(n +", ");
return powers(n/2);
}
System.out.println("");
return 0;
}
Output : 128, 64, 32, 16, 8, 4, 2
Expected : 2, 4, 8, 16, 32, 64, 128
As the purpose of your function is printing the powers of 2, you do not need to return the value. Hence, you can rewrite your function as the following:
int powers(int N) //here N=128
{
if(N==2){
System.out.print(N + ", ");
}
else if (N >2)
{
powers(N/2);
System.out.print(N + ", ");
}
System.out.println("");
return 0;
}
Also to handle the last extra comma you can return the previous step string and print outside the function.
String powers(int N) //here N=128
{
if(N==2){
return (N + "");
}
String prev = powers(N/2);
return (prev + ", " + N);
}
I think this would be a more elegant way to achieve this. Improvements are supposed to be:
Use bit shifting when possible to gain some
performance.
Fix comma placement for all cases of input N
More elegant looking code
int powers(int N) //here N=128
{
if (N < 2) return 0;
powers(N >> 1); // Right shifting achieves division by 2 but a lot faster.
if (N > 3) System.out.print(", "); // Fixing comma placement for all cases of N.
System.out.print(N);
return 0;
}
Why are we making the assumption that the input N is already a power of 2? Besides, 2 ^ 0 = 1, should that be in the result as well?
public int power(int num) {
if (num <= 0)
return -1;
else if (num <= 1) {
System.out.print(1);
return 1;
} else if (num <= 2) {
System.out.print(1 + ", " + 2);
return 2;
} else {
int result = 2 * power(num / 2);
System.out.print(", " + result);
return result;
}
}
This works even if you give 131 as the input.
I have the following program to write:
An interesting (yet unsolved) question in mathematics is called "hailstone numbers". This series is produced by taking an initial integer and if the number is even, dividing it by 2. If the number is odd, multiply it by 3 and add 1. This process is the repeated.
For example: An initial number of 10 produces: 10, 5, 16, 8, 4, 2, 1, 4, 2, 1... An initial value of 23 produces: 23, 70, 35, 106, 53, 160, 80, 40, 20, 10, 5, 16, 8, 4, 2, 1, 4, 2, 1...
Note that both numbers eventually reach the 4, 2, 1, 4, 2, 1... cycle.
Create an application that offers the user three different ways to run this program.
Option 1: Print the hailstone numbers for a single entry and its length
Example: Input> 10 10, 5, 16, 8, 4, 2, 1 Length 7
Option 2: Print all of the hailstone numbers from 4 to a given entry
Example: Input> 6 4, 2, 1 Length 3 5, 16, 8, 4, 2, 1 Length 6 6, 3, 10, 5, 16, 8, 4, 2, 1 Length 9
Option 3: Print out the number with the maximum number of iterations need to reach the cycle and which starting number produces this maximum from 4 to the number entered.
Example: Input> 6 Longest: 6 Length: 9
In writing this program you must implement the following method...
/**
*
* #param num Number that a hailstone chain will be generated
* #param showNumbers true if list of numbers is shown to screen
* #return Count of the numbers in the num hailstone chain.
*/
private static int hailStone(int num, boolean showNumbers) {
// your code
}
This is the code I've written so far:
public static void main(String[] args) {
int a = getInt("Give a number: ");
System.out.print("How would you like to run the program? Option 1 prints hailstone numbers for a single entry and its length." +
"Option 2 prints all the hailstone numbers from 4 to a given entry. Option 3 prints the number with the maximum number" +
"of iterations needed to reach the 4, 2, 1 cycle.");
int option = console.nextInt();
boolean showNumbers = (option == 1 || option == 2);
hailStone(a, showNumbers);
}
public static int getInt(String prompt) {
int input;
System.out.print(prompt);
input = console.nextInt();
return input;
}
private static void hailStone (int a, boolean showNumbers) {
if (showNumbers == true) {
if (a % 2 == 0) {
for (int i = 0; i < 50; i++) {
for (int j = 0; j <= i; j++)
a /= 2;
System.out.print(a + " ");
a *= 3;
a += 1;
System.out.print(a + " ");
}
} else {
for (int i = 0; i != a; i++) {
}
}
} else {
}
}
I feel like I've hit a brick wall because I have no idea how to implement all these options in the method my teacher is requiring us to use. Plus, I can't seem to get even the basic hailstone chain to print. Help?
The HailStone algorithm should not be hard to implement. It will actually be much easier if you make it a recursive function, since that is more natural Writing it as an iterative function is probably what is causing your issues.
This should be enough to get you started, this is a working HailStone implementation using a recursive function. You can implement the rest of the project requirements quite easily once you've got the algorithm working... but I'd like to challenge you to convert this into a working iterative function once you get the features correct and to write unit tests to test the program. (TDD dictates that you should write your tests BEFORE you write the actual implementation. This is a great practice that is often skipped due to time constraints and the perception that a strong test suite is overkill.)
HailStone.java
public class HailStone {
/* static variable to count calls to hailStone */
public static int iterCount = 0;
/* This variable is a senti */
public static boolean isRepeating = 0;
/* Simple main function */
public static void main(String[] args) {
// TODO:
// Either parse args or use a scanner to get input.
// Args = verbose, entryPoint
hailStone(10, true);
}
/* Recursive hailStone implementation */
private static void hailStone(int a, boolean showNumbers) {
// start off by printing the numbers if showNumbers is true
if (showNumbers) {
System.out.printf("Iteration #%d: %d\n", ++iterCount, a);
}
// base case: a = 1 => most important part of recursion
if (a == 1) {
if (isRepeating) {
return;
}
isRepeating = true;
}
// check if a is odd
// You can use modulo divison, but we'll use bitwise &
/* Explained: [ bitwise AND... bits that are set in a AND in 1 ]
**********************************************
Case 1: a is even =>
a = 10
10 in binary is 00001010
1 in binary is 00000001
------------------------------
10 & 1 in binary is 00000000
Case 2: a is odd =>
a = 10
11 in binary is 00001011
1 in binary is 00000001
------------------------------
11 & 1 in binary is 00000001
**********************************************
set(X) = set of all even numbers
set(Y) = set of all odd numbers
{
x is any arbitrary number in set X,
y is any arbitrary number in set Y
}
x & 1 will ALWAYS equal 0 -\
>- know this. bitwise hacks rock.
y & 1 will ALWAYS equal 1 -/
*/
if ((a & 1) == 1) {
a *= 3;
a += 1;
} else {
a /= 2;
}
// Tail recursion.
hailStone(a, showNumbers);
return;
}
}
without all the comments and extra stuff:
public class HailStone {
public static int iter_count = 0;
public static void main(String[] args) {
hailStone(10, true);
}
/* Recursive hailStone implementation */
private static void hailStone(int a, boolean showNumbers) {
if (showNumbers) {
System.out.printf("Iteration #%d: %d\n", ++iter_count, a);
}
// base case: a = 1
if (a == 1) {
return;
}
if ((a & 1) == 1) { // a is odd:
a *= 3;
a += 1;
} else {
a /= 2;
}
hailStone(a, showNumbers);
return;
}
}
private static Scanner console = new Scanner(System.in);
public static void main(String[] args) {
System.out.println("How would you like to run the program?");
System.out.println(" [1] - print hailstone numbers for a single entry and its length.");
System.out.println(" [2] - print all hailstone numbers from 4 to a given entry.");
System.out.println(" [3] - print the number with the maximum number of iterations needed to reach the 4, 2, 1 cycle.");
int option = queryInt("Option: ", 1, 3);
switch (option) {
case 1: {
int seed = queryInt("INPUT> ", 1, Integer.MAX_VALUE);
hailStone(seed, true);
break;
}
case 2: {
int maxSeed = queryInt("INPUT> ", 4, Integer.MAX_VALUE);
for (int i = 4; i <= maxSeed; i++) {
hailStone(i, true);
}
break;
}
case 3: {
int maxSeed = queryInt("INPUT> ", 4, Integer.MAX_VALUE);
int longestChain = 0;
int longestChainLength = 0;
for (int i = 4; i <= maxSeed; i++) {
int length = hailStone(i, false);
if(length > longestChainLength) {
longestChain = i;
longestChainLength = length;
}
}
System.out.println("Longest: " + longestChain + " Length: " + longestChainLength);
break;
}
}
}
private static int queryInt(String prompt, int min, int max) {
while (true) {
System.out.print(prompt);
String input = console.nextLine();
try {
int result = Integer.parseInt(input);
if (result >= min && result <= max) {
return result;
} else {
System.err.print("Expected a number ");
if (min == Integer.MIN_VALUE) {
System.err.println(" less than or equal to " + max);
} else if (max == Integer.MAX_VALUE) {
System.err.println(" greater than or equal to " + min);
} else {
System.err.println(" between " + min + " and " + max);
}
}
} catch (NumberFormatException ex) {
System.err.println("Not a number: " + input);
}
}
}
private static int hailStone(int num, boolean showNumbers) {
int result = 1;
for (Iterator<Integer> chain = iterateHailStone(num); num != 1; num = chain.next(), result++) {
if (showNumbers) {
System.out.print(num + ", ");
}
}
if (showNumbers) {
System.out.print(num);
System.out.println(" (length=" + result + ")");
}
return result;
}
private static Iterator<Integer> iterateHailStone(int seed) {
return new Iterator<Integer>() {
int value = seed;
#Override
public boolean hasNext() {
return true;
}
#Override
public Integer next() {
if (value % 2 == 0) {
value /= 2;
} else {
value *= 3;
value++;
}
return value;
}
};
}
So what my program is supposed to do...
Iterate through an array of 113 numbers
Print said numbers
But if..
number is odd print "odd" beside it
number is divisible by 5 print "hi five"
total number of x and its subsequent number (x+1) is divisible by 7 print "wow"
number is prime print "prime"
Currently my program will iterate through the numbers and print the ones that apply, and if two apply it will print it twice with different notes. What i would like to do is have it print all the numbers, then print the notes beside the numbers that apply. And if two conditions apply, print the notes beside each other and not on new lines.
ex. of what i would like it to do..
x: 5, odd, high five
Ive been trying different techniques from some examples i found but to no avail. Any direction or guidance would be greatly appreciated!
P.S. - i know i haven't implemented prime yet, my equation isn't right, thats next on my list.
Here is what i have so far..
import java.util.ArrayList;
public class Number {
public static ArrayList<Integer> getSequence() {
ArrayList<Integer> numbers = new ArrayList<Integer>(113);
for (int n = 0; n <= 113; n++) {
numbers.add(n);
}
return numbers;
}
public static boolean isOdd(int n) {
if (getSequence().get(n) % 2 != 0) {
System.out.println("x: " + n + ", x is odd");
}
return true;
}
public static boolean isDivisibleBy5(int n) {
if (getSequence().get(n) % 5 == 0) {
System.out.println("x: " + n + ", hi five");
}
return true;
}
public static boolean isDivisibleBy7(int n) {
int x = getSequence().get(n) + (getSequence().get(n) + 1);
if (x % 7 == 0 && x<113) {
System.out.println("x: " + n + ", wow");
}
return true;
}
public static boolean isPrime(int n) {
if (n <= 1) {
return false;
}
for (int i = 2; i < Math.sqrt(n); i++) {
System.out.println("x: " + n + ", prime");
if (n % 1 == 0) {
return false;
}
}
return true;
}
public static void main(String[] args) {
ArrayList<Integer> nums = getSequence();
for (int n : nums) {
if(isOdd(n)) {
}
if(isDivisibleBy5(n)){
}
if(isDivisibleBy7(n)){
}
}
}
}
Instead of using Integer arraylist create a separate class which can hold Integer and ArrayList<String>. Then create your arraylist of that class type.
Make methods in your new class as follows
Method to insert the number
Method to retrieve the number
Method to insert a label to the array list.
Method to retrieve the ArrayList or String[]
This way you can easily overcome your problem.
One other method is to use a Map object(HashMap instead). Integer as the KEY and ArrayList<String> as the VALUE.