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;
}
};
}
Related
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);
I'm having trouble with some code. This code's purpose is just to take user-inputted numbers, append them to a string, and create a histogram representing the amount of numbers in each 5 number range from 1 to 50. Ex.
1 - 5: ***
6 - 10: ********
11 - 15: *
etc.
Here is the code:
public class Ch10Ex4 {
public static int number;
public static ArrayList<Integer> numbers = new ArrayList<>();
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
for (int i = 0; i < 10; i++) {
getNums(1, 50);
}
histogram(1, 50, 5);
System.out.println();
}
public static void getNums(int low_num, int high_num) {
Scanner sc = new Scanner(System.in);
do {
System.out.print("Enter a number between " + low_num +
" and " + high_num + ": ");
number = sc.nextInt();
} while (number < 1 || number > 50);
System.out.println(number + " has been added sucsessfully.");
numbers.add(number);
}
public static void histogram(int low, int high, int range) {
int temp_low = low;
int temp_high = low + (range - 1);
for (int i = 0; i < high / range; i++) {
System.out.print("\n" + temp_low + " - " + temp_high + ": ");
for (int arr:numbers) {
if (arr >= temp_low && i <= temp_high) {
System.out.print("*");
} else {
}
}
temp_low += range;
temp_high += range;
}
}
}
I had a previous version of this code where I would call histogram() with two parameters. These would be the lowest number and the highest number like usual but no int range parameter. And I didn't have the outermost for-loop. I would have to call histogram 10 times ex.
histogram(1, 5);
histogram(6, 10);
histogram(11, 15);
etc.
Basically, I would call it for every set of five numbers. It worked but it was super inefficient and not very reusable. The problem is that when I run this code (entering numbers 1- 10), I get this:
1 - 5: **********
6 - 10: *****
11 - 15:
16 - 20:
etc.
The first set of five outputs an asterix for every number in the array.
Sorry for the incredibly long post. Any help is much appreciated and thank you in advance.
The bug is that you are using i in this if-statement.
if (arr >= temp_low && i <= temp_high) {
System.out.print("*");
} else {
}
Switch it to arr and you should be good.
How do I Write a program that compute the multiplication table for all numbers less than or equal N. Note that N is an integer read from the user.
The program will repeatedly
do that until the user enter -1 in JAVA.
I don't know if i should use nested loops or a method for this, but I wrote the following uncompleted code which is giving me an infinite loop
public static void main(String[] args) {
int N ;
System.out.println("Enter N: " );
N = in.nextInt();
while ( N != -1) {
for(int i = 1; i <= N; ++i)
{
for (int c = 1; c <= 10; ++c)
System.out.println(N + "*" + c + " = " + (N*c));
}
}
}
I want an output like this :
Enter an integer to print it's multiplication table, -1 to
exit
2
Multiplication table of 1
1*1 = 1, 1*2 = 2, 1*3 = 3, 1*4 = 4, 1*5 = 5, 1*6 = 6, 1*7 =
7, 1*8 = 8, 1*9 = 9, 1*10 = 10,
Multiplication table of 2
2*1 = 2, 2*2 = 4, 2*3 = 6, 2*4 = 8, 2*5 = 10, 2*6 = 12, 2*7
= 14, 2*8 = 16, 2*9 = 18, 2*10 = 20,
Enter an integer to print it's multiplication table, -1 to
exit
-1
Sunny Patel's answer is correct, but just to show you another way to do it:
import java.util.Scanner;
import java.util.stream.IntStream;
public class Multiply {
public static void main(String [] args) {
try (Scanner in = new Scanner(System.in)) {
int N;
do {
System.out.println("Enter N: " );
N = in.nextInt();
IntStream.range(1, N+1)
.forEach(i -> IntStream.range(1, 11)
.forEach(j -> System.out.println(String.format("%d*%d = %d", i, j, (i*j)))));
} while ( N != -1);
} catch (Exception e) {
e.printStackTrace();
}
}
}
Your code runs in an infinite loop because N does not change within the outer for-loop.
You can place the prompt inside the loop, and change to a do-while loop to guarantee at least 1 execution; or none if the user enters a number less than 1 (because of the outer for-loop).
You were also missing reference to Scanner to capture the input.
Finally, you forgot to use i instead of N in the output, otherwise the inner loop will output the same values every time.
import java.util.Scanner; // Import Scanner
public static void main(String[] args) {
int N;
Scanner in = new Scanner(System.in); // Missing Scanner
do { // Changed to do-while loop
System.out.println("Enter N: " );
N = in.nextInt(); // Prompt user for N.
for(int i = 1; i <= N; ++i)
{
for (int c = 1; c <= 10; ++c)
System.out.println(i + "*" + c + " = " + (i*c)); // Use i instead of N
}
} while ( N != -1);
}
So I am not very good at it yet at all (understatement). I am trying to solve problems in the Euler project, and I am already stuck on 2.
Each new term in the Fibonacci sequence is generated by adding the previous 2 terms. By starting with 1 and 2, the first 10 terms will be:
1, 2, 3, 5, 8, 13, 21, 34, 55, 89, ...
By considering the terms in the Fibonacci sequence whose values do not exceed four million, find the sum of the even-valued terms.
Here is my code which I have repeatedly tried to fix:
(I think there is something wrong with the for loop logic.)
public class tesy {
public static void main(String args[]) {
int fib = 0;
int tot = 0;
int total = 0;
for (fib = 0; tot < 4000000; fib++) {
tot = fib + (fib + 1);
if (tot % 2 == 0) {
total = tot + total;
}
}
System.out.println(total);
}
}
Your logic is erroneous in couple of ways,
tot = fib + (fib + 1); /** This will always be `(2*fib + 1)` and `fib` is getting
incremented by 1 each time. You have no reference to the previous two terms of the
sequence. **/
Try the below logic instead.
class Fibonacci
{
public static void main (String[] args)
{
int fiboFirst = 1;
int fiboSecond =2;
int fib = 0;
int sum = 0;
while(fiboSecond < 4000000)
{
// This will calculate the current term of the sequence
fib = fiboFirst + fiboSecond;
// Below two lines will update fib[i] and fib[i - 1] terms
// for the next loop iteration.
fiboFirst = fiboSecond; // fib[i]
fiboSecond = fib; // fib[i -1]
if (fib % 2 == 0)
{
sum = sum + fib;
}
}
System.out.println(sum+2);
}
}
Explanation
Here fiboFirst is equivalent to F[n] and fiboSecond is equivalent
to F[n - 1] in the Fibonacci sequence definition. In each iteration,
those two values should be replaced, in order to be used in the next
iteration. That is why I have these two lines,
fiboFirst = fiboSecond; // fib[i]
fiboSecond = fib; // fib[i -1]
HERE is the execution of the above program
You don't seem to be following the actual equation used to generate a fibonacci sequence, therefore there is no (obvious) way of fixing your code.
int fibA = 1, fibB = 2, total = 0;
while(fibB <= 4000000) {
// Add to the total, set fibA to fibB and get the next value in the sequence.
if(fibB % 2 == 0) total += fibB;
int temp = fibA;
fibA = fibB;
fibB = fibB + temp;
}
The above code should find the sum of all values less than or equal to 4000000
Here is a solution that uses BigInteger. Please verify the results.
public class Fibonacci{
public static void main(String[] args) {
BigInteger r = fibonacciEvenSum();
System.out.println(r);
}
public static BigInteger fibonacciEvenSum(){
int f = 1;
int s = 2;
int mn4 = 4000000;
BigInteger sum = BigInteger.valueOf(0);
while(s <= mn4){
if(s % 2 == 0){
sum = sum.add(BigInteger.valueOf(s));
}
f = f + s;
s = s + f;
}
return sum;
}
}
Before writing a program like this, you should first think of what's underlying this program. You should first understand how to generate a Fibonacci series before graduating on to doing something with the series. I'll give you my solution so that you can understand.
class euler2 {
public static void main(String[] args) {
int a = 0, b = 1; /* the first elements of Fibonacci series are generally
thought to be 0 and 1. Therefore the series is 0, 1, 1, 2, 3... .
I've initialized first and second elements such */
double sum = 0; // The initial sum is zero of course.
while (b < 4000000) /* since b is the second term, it will be our control variable.
This wouldn't let us consider values above 4M. */
{
int ob = b; // to swap the values of a and b.
b = a + b; // generating next in the series.
a = ob; // a is now the older value of b since b is now a + b.
if (b % 2 == 0) // if b is even
sum += b; // we add it to the sum
}
System.out.println(sum); // and now we just print the sum
}
}
Hope this helped!
I am working my way through a beginners java book which contains some practice questions to try out. I am currently learning while loops and there is one question that I am stuck on and have been for the last two days.
It is asking me to use a single While loop to print out the first ten numbers in the sequence 1, 2, 0, 3, -1, 4.
I have worked out the easy bit which is how the sequence goes( add 1, take 2, add 3, take 4, add 5, take 6, add 7 etc.) However I have no idea how to implement this.
public class WhileTester {
public static void main(String[] args) {
System.out.println("First 10 numbers in the sequence 1, 2, 0, 3, -1, 4, -2 ...");
int i = 0;
while (i <= 6) {
int a = 1;
int num = i;
if (i % 2 == 0) {
num = -i;
} else {
num = i;
}
a = a + num;
System.out.print(a+ ", ");
i++;
I know this is no where near close to where I need to get to but I am stuck for ideas.
Thanks in advance.
I think you got the sequence wrong, look at the numbers:
It starts at 1, then +1, -2 +3 -4 +5 ...
Maybe that helps on your implementation.
You set a back to 1 inside the loop with each iteration. Shouldn't a be initialized outside the loop?
It strikes me that you are a lot closer to a solution than you give yourself credit for.
if you take the num and move it outside the loop....
then, you add 1 to num each time you loop:
On 'even' loops you add num, and on odd loops you subtract num. Now, you need to loop 10 times (not until the value is 6.... which is a 'coincidence'....):
Your critical code becomes:
int num= 0;
int a = 1;
for (int i = 0; i < 10; i++) {
System.out.println(a);
num++;
if (i % 2 == 0) {
a += num;
} else {
a -= num;
}
}
public class tester {
public static void main(String[] args) {
System.out.println("First 10 numbers in the sequence 1, 2, 0, 3, -1, 4, -2 ...");
int num = 0;
int a = 1;
int value = 0;
while (value <= 10) {
if (value % 2 == 0) {
num = -value;
} else {
num = value;
}
a = a + num;
System.out.print(a + ", ");
value++;
}
}
}
class can't be compiled for the program:-
public class WhileTester {
public static void main(String[] args) {
System.out.println("First 10 numbers in the sequence 1, 2, 0, 3, -1, 4, -2 ...");
int i = 0;
while (i <= 6) {
int a = 1;
int num = i;
if (i % 2 == 0) {
num = -i;
} else {
num = i;
}
a = a + num;
System.out.print(a+ ", ");
i++;
it is a wrong information