I am currently starting a Java course and am a relative beginner, I have been given an exercise one part of which asks me to write a method that prints out whether or not it is good enough weather to go on a bike ride.
It must be greater than 40 degrees and less than 100 degrees unless it is raining in which case it must be greater than 70 degrees and less than 110 degrees.
The problem is that I am way more of a beginner (to programming in general) than most others on the course, and this exercise seems like a step up from the rest of the same assignment.
E.g the previous task, to create a dice rolling method -
public static int diceAverage (int pNumberofRolls) {
int total=0;
Random rand = new Random();
for (int loopy=1; loopy<=pNumberofRolls; loopy++){
total = total + rand.nextInt(6) + 1;
}
}
Sorry if formatting is off, I am on my mobile.
Kyle's answer is good. For academic purpose, the same code with ternary operator:
public static boolean bikeOrNot (int temp, boolean rain) {
return rain
? temp > 70 && temp < 110
: temp > 40 && temp < 100;
}
Few explanations:
I'm using boolean instead of Boolean because the answer should not be null. Same thing for the argument boolean rain instead of Boolean rain. For that point, you can check the primtive data type concept
ternary operator is a shortcut for if ... then ... else... written in one line: (condition) ? (return this if condition is true) : (return this if condition is false)
I think you are looking for this:
public static Boolean bikeOrNot (int temp, Boolean rain) {
// check for rain
if (rain){
if (temp > 70 && temp < 110){
return true;
}
} else {
if (temp > 40 && temp < 100){
return true;
}
}
return false;
}
Call this like:
Boolean shouldIBike = bikeOrNot(60, false);
It checks if its raining, then checks the temperate and does the same if its not raining. If it doesn't fall into any if, it will reach the last line and return false, in that case, you should not go cycling.
Related
The problem I'm trying to solve comes from ProjectEuler.
Some integers have following property:
n + reverse(n) = a number consisting entirely of odd digits.
For example:
14: 14 + 41 = 55
Numbers starting or ending with 0 aren't allowed.
How many of these "reversible" numbers are there below 10^9?
The problem also gives a hint:
there are 120 such numbers below 1000.
I'm quite new to Java, and I tried to solve this problem by writing a program that checks all the numbers up to a billion, which is not the best way, I know, but I'm ok with that.
The problem is that my program gives out a wrong amount of numbers and I couldn't figure out why! (The code will most likely contain some ugly things, feel free to improve it in any way)
int result = 0;
boolean isOdd = true;
boolean hasNo0 = true;
public int reverseNumber(int r) //this method should be working
{ //guess the main problem is in the second method
int n = 0;
String m = "";
if (r % 10 == 0) { hasNo0 = false; }
while (r > 0){
n = r % 10;
m = String.valueOf(m+n);
r /= 10;
}
result = Integer.parseInt(m);
return result;
}
public void isSumOdd(int max)
{
int number = 1;
int sum = 0;
Sums reverseIt = new Sums();
int amount = 0;
while (number <= max)
{
sum = reverseIt.reverseNumber(number) + number;
while (sum > 0)
{
int x = sum % 10;
if (x % 2 == 0) { isOdd = false; }
sum /= 10;
}
if (isOdd && hasNo0) { amount++; }
number++;
isOdd = true;
hasNo0 = true;
}
System.out.println(amount);
}
Called by
Sums first = new Sums();
first.reversibleNumbers(1000000000);
The most important problem in your code is the following line:
sum = reverseIt.reverseNumber(number) + number;
in isSumOdd(int max) function. Here the reverseIt object is a new instance of Sums class. Since you are using Sums member data (the boolean variables) to signal some conditions when you use the new instance the value of these member variables is not copied to the current caller object. You have to change the line to:
sum = this.reverseNumber(number) + number;
and remove the Sums reverseIt = new Sums(); declaration and initialization.
Edit: Attempt to explain why there is no need to instantiate new object instance to call a method - I've found the following answer which explains the difference between a function and a (object)method: https://stackoverflow.com/a/155655/25429. IMO the explanation should be enough (you don't need a new object because the member method already has access to the member data in the object).
You overwrite odd check for given digit when checking the next one with this code: isOdd = false;. So in the outcome you check only whether the first digit is odd.
You should replace this line with
idOdd = idOdd && (x % 2 == 0);
BTW. You should be able to track down an error like this easily with simple unit tests, the practice I would recommend.
One of the key problems here is that your reverseNumber method does two things: check if the number has a zero and reverses the number. I understand that you want to ignore the result (or really, you have no result) if the number is a multiple of 10. Therefore, you have two approaches:
Only send numbers into reverseNumber if they are not a multiple of 10. This is called a precondition of the method, and is probably the easiest solution.
Have a way for your method to give back no result. This is a popular technique in an area of programming called "Functional Programming", and is usually implemented with a tool called a Monad. In Java, these are implemented with the Optional<> class. These allow your method (which always has to return something) to return an object that means "nothing at all". These will allow you to know if your method was unable or unwilling to give you a result for some reason (in this case, the number had a zero in it).
I think that separating functionnalities will transform the problem to be easier. Here is a solution for your problem. Perhaps it isn't the best but that gives a good result:
public static void main(final String [] args) {
int counter = 0;
for (int i = 0; i < 20; i++) {
final int reversNumber = reverseNumber(i);
final int sum = i + reversNumber;
if (hasNoZeros(i) && isOdd(sum)) {
counter++;
System.out.println("i: " + i);
System.out.println("r: " + reversNumber);
System.out.println("s: " + sum);
}
}
System.out.println(counter);
}
public static boolean hasNoZeros(final int i){
final String s = String.valueOf(i);
if (s.startsWith("0") || s.endsWith("0")) {
return false;
}
return true;
}
public static int reverseNumber(final int i){
final StringBuilder sb = new StringBuilder(String.valueOf(i));
return Integer.parseInt(sb.reverse().toString());
}
public static boolean isOdd(final int i){
for (final char s : String.valueOf(i).toCharArray()) {
if (Integer.parseInt(String.valueOf(s))%2 == 0) {
return false;
}
}
return true;
}
the output is:
i: 12
r: 21
s: 33
i: 14
r: 41
s: 55
i: 16
r: 61
s: 77
i: 18
r: 81
s: 99
4
Here is a quick working snippet:
class Prgm
{
public static void main(String args[])
{
int max=(int)Math.pow(10, 3); //change it to (10, 9) for 10^9
for(int i=1;i<=max;i++)
{
if(i%10==0)
continue;
String num=Integer.toString(i);
String reverseNum=new StringBuffer(num).reverse().toString();
String sum=(new Long(i+Long.parseLong(reverseNum))).toString();
if(sum.matches("^[13579]+$"))
System.out.println(i);
}
}
}
It prints 1 number(satisfying the condition) per line, wc is word count linux program used here to count number of lines
$javac Prgm.java
$java Prgm
...//Prgm outputs numbers 1 per line
$java Prgm | wc --lines
120
I work on a genetic algorithm for a robotic assembly line balancing problem (assigning assembly operations and robots to stations to minimize the cycle time for a given number of stations). The solution is represented by an ArrayList (configuration) which holds all the operations in the sequence assigned to different stations. Furthermore, I have two more ArrayLists (robotAssignment, operationPartition) which indicate where a new station starts and which robot is assigned to a station. For example, a solution candidate looks like this (configuration, robotAssignment, operationPartition from top to bottom):
Initial cycle time: 50.0
|2|7|3|9|1|5|4|6|8|10|
|2|1|3|2|
|0|2|5|7|
From this solution representation we know that operations 3, 9, and 1 are assigned to the second sation and robot 1 is used.
I need to keep track of the station an operation is assigned to. I tried a lot to store this in the Object Operation itself but I always ended up in problems and therefore I want to write a method that gives me the stations index of an operation.
Here is what I have coded so far:
// Get the station of an operation
public int getStation(Operation operation) {
int stationIndex = 0;
int position = configuration.indexOf(operation);
for (int i = 0; i < GA_RALBP.numberOfStations ; i++ ) {
if (i < GA_RALBP.numberOfStations - 1 && operationPartition.get(i) != null) {
if (isBetween(position, (int) operationPartition.get(i), (int) operationPartition.get(i + 1))) {
return stationIndex + 1;
} else {
stationIndex++;
}
}
else if (i >= GA_RALBP.numberOfStations - 1 && operationPartition.get(i) != null) {
if (isBetween(position, (int) operationPartition.get(i), configurationSize())) {
return stationIndex + 1;
}
}
}
return -1;
}
// Check if value x is between values left and right including left
public static boolean isBetween(int x, int left, int right) {
if (left <= x && x < right ) {
return true;
}
else {
return false;
}
}
However, this does not seem to be (a) very elegant and (b) if I have to do this for a large number of operations the runtime could become a problem. Has anoyone an idea how to solve this more efficiently?
Why not make the partitioning explicit (replaces your operationPartition) - something like:
Map<Integer, Integer> operationToStationMapping = new HashMap<>();
operationToStationMapping.put(2,0);
operationToStationMapping.put(7,0);
operationToStationMapping.put(3,2);
operationToStationMapping.put(9,2);
operationToStationMapping.put(1,2);
operationToStationMapping.put(5,5);
operationToStationMapping.put(6,7);
operationToStationMapping.put(8,-1);
operationToStationMapping.put(10,-1);
Then getStation() becomes:
getStation(int operation) {return operationToStationMapping.get(operation);}
How would I go about using recursion to calculate the probability of rolling a certain number, r, with a given number of dice? I tried to treat this as a choose problem but am still quite confused as to how the algorithm should work.
For example, it should work out to be something like this:
P(4,14)=(1/6)P(3,13)+(1/6)P(3,12)+(1/6)P(3,11)+(1/6)P(3,10)+(1/6)P(3,9)+(1/6)P(3,8)
P(3,8)=(1/6)P(2,7)+(1/6)P(2,6)+(1/6)P(2,5)+(1/6)P(2,4)+(1/6)P(2,3)+(1/6)P(2,2)
P(2,4)=(1/6)P(1,3)+(1/6)P(1,2)+(1/6)P(1,1)+(1/6)P(1,0)+(1/6)P(1,-1)+(1/6)P(1,-2)
=(1/6)(1/6)+(1/6)(1/6)+(1/6)(1/6)+(1/6)(0)+(1/6)(0)+(1/6)(0)
I'm just having trouble converting it into code.
static double P(int dice, int r) {
int ret = 1;
for (int i = 2; i < 7; i++) {
ret = (1/6)(ret*(dice-i))/(i+1);
}
return ret;
}
static double RollDice(int dice,int r) {
if (dice==1 && (r<1 || r>6)){
return 0;
}
if (dice==1 && (r>=1 && r<=6)){
return (1.0/6);
}
else {
return ((1.0/6)*P(dice-1,r-1));
}
I do not understand why you have to separate methods P() and RollDice(), since in your formulae you (correctly) describe everything with P.
If you were to put your formulae into code, it should look something like this:
EDIT: changed the base case to 0 dice, since then it becomes even simpler.
static double P(int dice, int r) {
if (dice == 0) {
// Zero dice: probabiliy 1 to get 0
if (r == 0) {
return 1.0;
} else {
return 0.0;
}
else {
// Multiple dice: recursion
double sum = 0.0;
for (/* TODO */) {
sum += //TODO
}
}
}
For the recursion part, try working it out by looking at the formula:
P(4, 14) = (1/6)P(3, 13) + (1/6)P(3, 12) + ... + (1/6)P(3, 8)
i.e. in the general case
P(dice, r)=(1/6)P(dice-1, r-1) + (1/6)P(dice-1, r-2) + ... + (1/6)P(dice-1, r-6)
meaning that you have to loop from r-6 to r-1.
And since you are taking a sum over multiple recursive calls, you have to use an accumulator initialized to 0. (The variable I called sum)
EDIT: Click here for a complete example, compare to WolframAlpha to verify the result.
The purpose of this program is to find the smallest number evenly divisible by all integers 1 through 20. I know it could be made more efficient, but I'm not interested in optimizing it right now. When I execute the program, it seems to hang forever, which leads me to believe that there's an infinite loop somewhere. I can't seem to find it though. I'm not sure what part of the code is causing the problem and it's relatively concise, so I'll post it all here.
public class Problem5{
public static void main(String[]args){
boolean notFound = true;
while(notFound){
int n = 20;
if(testDivide(n)){
System.out.println(n);
notFound = false;
}
else
n++;
}
}
private static boolean testDivide(int target){
for(int i = 20; i > 0; i--){
if(target % i != 0)
return false;
}
return true;
}
}
If anyone can help me out with this, I'd appreciate it a lot.
Additional Information: The program also never outputs any numbers, which leads me to believe that if(testDivide(n)) is never evaluating to true.
You are initializing the value of n inside your while loop to 20, since n is always 20 for testDivide(20), which will always return false since 20 % 19 != 0 returns false. Hence remove int n = 20 from your while loop.
boolean notFound = true;
while(notFound){
int n = 20;
should be
boolean notFound = true;
int n = 20;
while(notFound) {
your for loop makes sure you return false, and then your while loop always sets i to 20 this is your infinite loop.
See the while loop:
while(notFound){
int n = 20;
if(testDivide(n)){
System.out.println(n);
notFound = false;
}
else
n++;
}
When the while loop is executed first, the value of n is set to 20.
the test divide returns false.
The value of n is decremented to 19.
The loop executes again
The value of of n is reinitialized to 20.
This is the problem initialize n outside the while loop.
So me and my friend tried to code this little game when we were children called LOVERS..
Wherein you write down the name of 2 persons,Whole name without the middle name,and count the number of L's,O's,V's,E's,R's,and S's in the name, add it together and put beside the letters.
Sample:
name 1: Hello
name 2: Care
L: 2
O: 1
V: 0
E: 2
R: 1
S: 0
afterwards you will add them in pairs.
Sample:
L: 2 > 3 > 4 > 7 > 15 > 32
O: 1 > 1 > 3 > 8 > 17
V: 0 > 2 > 5 > 9
E: 2 > 3 > 4
R: 1 > 1
S: 0
here's how it goes...first you add the values of the first 2 letters...LO then OV then VE and so on and so forth. until you get one final answer in this case 32....the 32 signifies the percentage in which the 2 people is Compatible with each other.
i know its quite stupid. haha but we just tried to program it for fun. we are 2nd year IT Students here in the philppines. anyway we were wondering if there's a way to do the calculation RECURSIVELY and if there's a way to reduce the number of Arrays used.
Here's our code:
import java.util.*;
public class LOVERS {
static Scanner console = new Scanner(System.in);
public static void main(String[] args) {
String name1="";
String name2="";
char love[] = {'L','O','V','E','R','S'};
int[] lovers = new int[6];
int[] temp= new int[6];
int[] temp2= new int[6];
boolean done = true;
while(done){
name1 = getName();
name2 = getName();
temp = getLetterCount(name1);
temp2 = getLetterCount(name2);
lovers = sumOfLetters(temp,temp2,love);
System.out.println("");
int[] firstLayer = new int[5];
int[] secondLayer = new int[4];
int[] thirdLayer = new int[3];
int[] fourthLayer = new int[2];
firstLayer = sums(lovers);
secondLayer = sums(firstLayer);
thirdLayer = sums(secondLayer);
fourthLayer = sums(thirdLayer);
int output = fourthLayer[0]+fourthLayer[1];
if(output>100){
output=100;
}
System.out.println("Result is : "+ output +"%");
System.out.println("Do you want to try again? Y/N :");
char again = ' ';
if(again == 'n')
{
done = false;
}
else done = true;
}
}
public static int[] sums (int[] y){
int[] x = new int[y.length-1];
for(int ctr=1;ctr<y.length;ctr++){
x[ctr-1]=y[ctr-1]+y[ctr];
}
return x;
}
public static String getName(){
String n="";
System.out.println("Enter name: ");
n = console.nextLine();
n = n.toUpperCase();
return n;
}
public static int[] sumOfLetters(int[] temp, int[] temp2, char[] love){
int[] lovers = new int[6];
for(int ctr=0;ctr<6;ctr++){
lovers[ctr]=temp[ctr]+temp2[ctr];
System.out.println(love[ctr]+" - "+lovers[ctr]);
}
return lovers;
}
public static int[] getLetterCount(String n){
int[] temp = new int[6];
for(int x=0;x<n.length();x++){
if(n.charAt(x)=='L'){
temp[0]++;
}
else if(n.charAt(x)=='O'){
temp[1]++;
}
else if(n.charAt(x)=='V'){
temp[2]++;
}
else if(n.charAt(x)=='E'){
temp[3]++;
}
else if(n.charAt(x)=='R'){
temp[4]++;
}
else if(n.charAt(x)=='S'){
temp[5]++;
}
}
return temp;
}
}
as you can see we used 4 arrays for the 4 layers of calculation and we used a looping statement for the calculation.
So can this be done RECURSIVELY? and How can we reduce the number of arrays used?
this can help us greatly in learning how to do proper Recursive functions since we are currently learning Data Structures. hope you guys can help me. thanks
Yes, of course you can code it recursively.
First of all, your sum-fn. Instead of going through the string byte for byte, you can pass the string to the same function over and over again, just removing one character each time. That character will be added to your result-number. Your final-check will be that the string is empty, then you return null. Evaluation will go back up the recursion, potentially adding 1 (or 0 otherwise) for each character in the string.
For clearer, more readable code you should use enums instead of byte-arrays for storing your ints.
Also, instead of static functions, make it a class in which you can access the attributes.
For the summation of the 6 chars, each level does the same operation on it. So each function call should do that addition and return the result being called in the function again. Your final-check is that only the first integer value positive. If all the other values are 0 the first one holds your sum.
Yes, you can do it recursively:
public static int L(int i) {
return (i == 0) ? LVAL : L(i - 1) + O(i - 1);
}
public static int O(int i) {
return (i == 0) ? OVAL : O(i - 1) + V(i - 1);
}
public static int V(int i) {
return (i == 0) ? VVAL : V(i - 1) + E(i - 1);
}
public static int E(int i) {
return (i == 0) ? EVAL : E(i - 1) + R(i - 1);
}
public static int R(int i) {
return (i == 0) ? RVAL : R(i - 1) + SVAL;
}
Calling L(5) gives you the answer.
Actually the problem here is one instance of a much more general class of problems/algorithms which are incidentally quite important in some fields nobody would believe from this example ;)
Basically you can regard your triangle above as a matrix. Ie the second number in the L row (the 3) would be (0,1), 3rd value in the E row would be (3,2). If you look at it you see that every value except the start values depend on exactly two other nodes, which makes this a 2-point stencil. There are some extremely intriguing algorithms out there for this kind of problem - eg a cache oblivious, parallel algorithm for higher-order stencils (LBMHD uses 13-points or something).
Anyways that stuff is completely out of your league I fear (don't ask me about details either~) - there are even more or less recent papers about this ;)
PS: And my personal small implementation. Can't get much simpler and has the typical structure
of a simple recursive program. You call it with getVal(0, 5); or more generally getVal(0, startVals.length - 1). Just think about it as working backwards from the solution to the start. We want to know what the right field in the first row has. To get this we need to know two the values of two other fields which we have to compute first in the same manner. This is done until we get to a field where we already know the result - ie our start values.
private int[] startVals; // contains start values for all 6 letters.
// for your example startVals[0] == 2; startVals[5] == 0
public int getVal(int row, int col) {
if (col == 0) return startVals[row];
return getVal(row, col-1) + getVal(row + 1, col - 1);
}