Mind helping a newcomer who hit their first speed bump? - java

I just started learning how to program in Java. Everything was going well so far.. That was until I came across this "bonus" question/problem our teacher gave us to solve as an additional "challenge".
Please click here to view the Question and the Sample input/output (it's an image file)
Note that I'm not allowed to use anything that wasn't taught or discussed in class. So, things like arrays, method overloading, parsing arrays to methods, parseInt, etc. gets ruled out.
Here's what I was able to come up with, so far:
import java.util.Scanner;
public class Test
{
public static void main(String[] args)
{
int N; // number of lines of input
double length1, length2, length3; // the 3 lengths
double perimeter; // you get this by adding the 3 lengths
double minperimeter=0; // dummy value
Scanner input = new Scanner(System.in);
System.out.println("Enter the number of triangles you have:");
N = input.nextInt();
System.out.println("Insert the lengths of the sides of these " +
"triangles (3 real numbers per line):");
for (int counter=0; counter<N; counter++)
{
length1 = input.nextDouble();
length2 = input.nextDouble();
length3 = input.nextDouble();
perimeter = (length1 + length2 + length3);
minperimeter = Math.min(perimeter,Math.min(perimeter,perimeter));
}
System.out.printf("The minimum perimeter is %.1f%n", minperimeter);
}
}
My 2 main problems are:
1) The program only stores and works with the 'last' input.
The ones before it get replaced with this one. [update: solved this problem]
2) How do I print the "triangle number" in the final output? [update: solved this problem, too]
So, can anyone please help me come up with a solution that requires only the very basic learnings of Java? If it helps, this is the book we're using. Currently at Chapter 4. But we did learn about Math Class (which is in Chapter 5).
Update: Thank you so much for your replies, everyone! I was able to come up with a solution that does exactly what was asked in my question.

Math.min(perimeter,perimeter) will always give you perimeter. You probably wanted to do Math.min(perimeter,minPerimeter)
Since it's a programming assignment is best if I don't give you the full solution to your second question, but your hint is, in the counter parameter of your for loop. Save that when you update minperimeter, so that you know in which iteration of the loop you found the minimum.
Also, initialise your minPerimeter to 10000 or higher. If you start at 0, Math.Min will never be lower than that.

Change your for loop as:
double minperimeter=-1;
for (int counter=0; counter<N; counter++)
{
length1 = input.nextDouble();
length2 = input.nextDouble();
length3 = input.nextDouble();
perimeter = (length1 + length2 + length3);
if(minperimeter == -1){
minperimeter = perimeter;
} else{
Math.min(perimeter,minperimeter);
}
}

You have to store the smaller perimeter in your variable perimeter.
The hint from your task tells you, that any given perimeter is smaller than 1000. Thus initiate the perimeter to 1000.
In your for-loop then you have to store the smaller perimeter:
perimeter = Math.min(perimeter, length1 + length2 + length3)
if the sum of the edges is smaller than the current perimeter, the smaller value will be stored.
Please note that according to your given task, you have to input 3 doubles within one line.

Alternative Solution
Make an ArrayList and add all perimeter to that list and then find the minimum value from that list.
List<Double> perimeter = new ArrayList<>();
for (int counter=0; counter<N; counter++)
{
length1 = input.nextDouble();
length2 = input.nextDouble();
length3 = input.nextDouble();
perimeter.add(length1 + length2 + length3);
}
System.out.printf("The minimum perimeter is %.1f%n", Collections.min(perimeter));

Related

Can someone help analyse my java code on an averaging program?

Hi so I've started learning java online for two weeks now, but as I watched those tutorials, I felt the only way I'd actually grasp that information was to practice it. My other programs worked great, but just when I decided to do something spectacular (for me only of course; a java expert would find creating this program mind-numbing), something went terribly wrong. I'd really appreciate if you could take a look at my code below of an averaging program that could average any amount of numbers you want, and tell me what in the world I did wrong.
UPDATE: Eclipse just outputs a random number after typing in just one number and then shuts down the program.
Here is a snapshot where I type in the console to average 6 numbers and then start with the number 7, but for some reason, when I hit enter again, it outputs 8.
package justpracticing;
import java.util.*;
public class average{
int grade = 0;
int average;
Scanner notoaverage = new Scanner(System.in);
System.out.println("Please enter the amount of numbers you'd like the average of! ");
final int totalaverage = notoaverage.nextInt();
Scanner averagingno = new Scanner(System.in);
System.out.println("Start typing in the " + totalaverage + " numbers");
int numbers = averagingno.nextInt();
int counter = 0;
public void averagingnumbers(){
while(counter<=totalaverage){
grade+=numbers;
++counter;
}
}
public void printStatement(){
average = grade/totalaverage;
System.out.println(average);
}
}
It seems that you have created an average Object in another class, and are calling the methods given from a main class.
I don't know what exactly you're having trouble with, but one problem is here:
average = grade/totalaverage;
These 2 variables that you are dividing are both integers. That means that the result will also be an integer. This is called truncation. What you want to do is first convert at least one of the integers to a double:
... = (grade * 1.0) / totalaverage;
You also want your average variable to be a double instead of an integer so that it can be a lot more accurate.

The below code wont execute with some inputs

Sorry for such a basic level question guys. But I'm starter in programming. Not a computers guy. So kindly help me.
In this code when I give input 1000000000, 1000000000, 999999999 the answer should be 4. But my answer is 1. I expect the if statement to execute but it is not executing here.
if you take m*n as a room and "a" as the side as a square tile. Then I want to count MINIMUM no. of tiles required to fill the floor of room. tiles may cover a bit more area but should not leave the room empty. this is my objective. It's working with inputs like 6,6,4 or 15,20,13 etc.
Now its working guys. I had posted the correct code with those minor changes below.
import java.util.Scanner;
public class TheatreSquare {
private static Scanner input;
public static void main(String[] args) {
input = new Scanner(System.in);
float m=input.nextFloat();
float n=input.nextFloat();
float a=input.nextFloat();
long i=(int)(m/a);
long j=(int)(n/a);
if((a*a*i*j)<m*n){
if(a*i<m){
//to check weather it is entering if()
System.out.println("true");
i+=1;
}
if(a*j<n){
System.out.println("false");
//to check weather it is entering if()
j+=1;
}
}
System.out.println((double)(i*j));
}
}
Your floats are overflowing when you multiply them. Defining m, n and a as doubles will solve the issue:
double m = input.nextDouble();
double n = input.nextDouble();
double a = input.nextDouble();
The int conversion loses precision.
Here in this case, a*a*i*j is equal to m*n Hence the if loop will not execute. Also a*i is equal to m and a*j is equal to n.
Hence i isi and j is 1, so i*j is 1.
You need to allow it to go if it is equal too.
Replace
if((a*a*i*j)<m*n){
if(a*i<m){
//to check weather it is entering if()
System.out.println("true");
i+=1;
}
if(a*j<n){
System.out.println("false");
//to check weather it is entering if()
j+=1;
}
}
with
if((a*a*i*j) <= m*n){
System.out.println("Entered if block");
if(a*i <= m){
//to check weather it is entering if()
System.out.println("true");
i+=1;
}
if(a*j <= n ){
System.out.println("false");
//to check weather it is entering if()
j+=1;
}
System.out.println("i is:"+ i +"j is:"+j);
}
thankyou #Mureinik, #Uma Lakshmi Kanth, #Diego Martinoia for helping to solve this. All your answers contributed to solve my question. this is working now. as #Mureinik said my floats are overflowing( though I dont know the meaning). I used Double instead of float and that's it. its working. :-)
import java.util.Scanner;
public class TheatreSquare {
private static Scanner input;
public static void main(String[] args) {
input = new Scanner(System.in);
double m=input.nextDouble();
double n=input.nextDouble();
double a=input.nextDouble();
long i=(long)(m/a);
long j=(long)(n/a);
if((a*a*i*j) <m*n){
if(a*i < m){
//to check weather it is entering if()
i+=1;
}
if(a*j < n ){
//to check weather it is entering if()
j+=1;
}
}
System.out.println((long)(i*j));
}
}
The reason for your behavior is that you are reading numbers as floats. Floats have limited precision, so your m n and a are the same value (at runtime). Reading them as long (and getting rid of all the decimal stuff) should help. But, as mentioned in the comment, we don't know what you wanted to achieve!
--- EDIT DUE TO NEW INFO ---
You have to cover an area of m times n square meters. You have an unit of computation of 1 tile, i.e. a times a square meters (both assumed to be decimal).
Assuming you can cut your tile with good-enough precision, your result will be:
Math.ceiling((m*n) / (a*a));
i.e., either your area is an exact multiple of your tiles (and you can always cut them in rectangles to match the shape of the room), or you'll have some "spare" space to fill in, thus you will need 1 more tile, a part of which you'll use to cover the remaining space, and a part of which you'll throw away.

giveChange method computes change and number of coins to return java?? [duplicate]

This question already has answers here:
min change greedy algorithm in java
(2 answers)
Closed 8 years ago.
I have a cashregister program that inputs purchases and payment and outputs the change due. i need it to not give just an amount but what particular coins/dollars user should get back. heres two methods i have
public void recordPurchase()
{
System.out.print("Enter total purchase price or negative number to end: ");
double input = keyboard.nextDouble();
while(input > 0)
{
purchase = purchase + input;
System.out.print("Enter total purchase price or negative number to end: ");
input = keyboard.nextDouble();
}
}
public double giveChange(Money moneyTypes)
{
double change = payment - purchase;
purchase = 0;
payment = 0;
//computes change rounding to two decimal places
change = (double)(Math.round(change*100))/100;
return change;
}
I need to output what coins/dollars person should get back. i have the money types saved in an array called moneyTypes. for example if the change due is $1.06 it would output you receive a dollar nickel and penny.
any advice would help. Thanks! if you need to see more of the code let me know
I'll give you an advice how to do it, not a solution.
Make a list of possible coin/note values.
Then from the biggest to lowest, compute how many times it fits into the remainder, and subtract this amount of money from the value. Make a note of the number of coins/notes.
This way, you will get the numbers you need.
count = Math.floor(remainder/coinValue) might help you.

exponential growth in java, return type array of doubles

Im working on a CS assignment and Im having a little trouble understanding how to output an array of doubles that represent the amt of money in a bank account at increments of time given a user specified growth rate. I have a main method that asks the user for initialAmount of $, a growthRate and the number of time intervals (denoted iA, gR and nP for inital Amount, growth Rate and number of Periods). this method then calls another method which is of return type double[]. My issue is with the code inside my for-loop, it compiles fine but outputs gibberish. heres the code:
import java.util.Scanner;
public class Benford {
public static double[] generateBenfordNumbers (double iA, double gR, int nP) {
double[] bankStatement = new double[nP];
for (int i = 0; i<nP; i++) {
bankStatement[i] = (iA*(Math.pow((1+(gR)), (i++))));
}
return bankStatement;
}
public static void main (String[] args) {
Scanner scan = new Scanner(System.in);
double iA;
double gR;
int nP;
System.out.print("What is the initial amount of money that you are starting with? : ");
iA = scan.nextDouble();
System.out.println();
System.out.print("What is the amount of growth per time period? : ");
gR = scan.nextDouble();
System.out.println();
System.out.print("How many time periods would you like to use? : ");
nP = scan.nextInt();
System.out.println();
generateBenfordNumbers(iA, gR, nP);
System.out.print(generateBenfordNumbers(iA, gR, nP));
}
}
In the line
bankStatement[i] = (iA*(Math.pow((1+(gR)), (i++))));
i++ increments i a second time. You probably want:
bankStatement[i] = (iA*(Math.pow((1+(gR)), i + 1)));
or, if we clean it up,
bankStatement[i] = iA * Math.pow(1 + gR, i + 1);
i + 1 returns a value 1 greater than that of i, but does not actually increment the variable itself.
Also, do you really have to use Math.pow each time? Can't you just manually set the first element of your array to iA and subsequently use bankStatement[i-1] to compute bankStatement[i]? Doing something like this will probably improve your program.
i is incremented twice : at loop level and into the body
The gibberish output looks like this:
[D#1b67f74
which is s double array text representation. You could use:
System.out.print(Arrays.toString(generateBenfordNumbers(iA, gR, nP)));
You should not be incrementing i inside your call to Math.pow. This is because you already increment it in your for loop. The result is that elements of your array are getting skipped and not set. This is probably where the gibberish-ness is coming from.
You probably want to change:
bankStatement[i] = (iA*(Math.pow((1+(gR)), (i++))));
To:
bankStatement[i] = iA*Math.pow(1+gR, i);
Also, as an aside, you generally shouldn't use so many parenthesis because it makes it hard to read. If you're not sure what the order of operations is, look it up.
What the others said, you're incrementing i twice so I'm not going to repeat that. I just want to add that brackets are good to organize formulas and to ensure correct execution order of calculations, but if you overuse them, they can obfuscate the intention of your program and they may make the problem you're looking for harder to spot. Compare
bankStatement[i] = iA * Math.pow(1.0 + gR, i+1);
with
bankStatement[i] = (iA*(Math.pow((1+(gR)), (i))));
See what I mean?
EDIT - following ARS very valid remark about the initial value of i, I changed the cleaned up statement.

Average of n numbers in java

Using loop I want to calculate the average of n numbers in Java and when user enters 0 the loop ends.
Here is the code that I have written:
public class start {
public static void main(String[] args) {
System.out.println("Enter an int value, the program exits if the input is 0");
Scanner input = new Scanner (System.in);
int h = 0;
while (input.nextInt() == 0){
int inp = input.nextInt();
int j = inp;
int i = 0;
h = j + i;
break;
}
System.out.println("The total is: "+ h);
}
}
Am I making any logical error?
Don't name the sum h, but sum.
The while-condition is wrong
Why do you use inp and j and i?
There is an unconditional break - why?
You talk about the average. Do you know what the average is?
Your output message is not about average - it is about the sum.
"Am I making any logical error?"
Yes. This looks like a homework problem so I won't spell it out for you, but think about what the value of i is, and what h = j + i means in this case.
You also need to be careful about calling input.nextInt(). What will happen when you call it twice each time through the loop (which is what you are doing)?
Homework, right?
Calling input.nextInt() in the while loop condition and also to fill in int inp means that each trip through the loop is reading two numbers (one of which is ignored). You need to figure out a way to only read one number per loop iteration and use it for both the == 0 comparison as well as for inp.
Additionally, you've done the right thing having h outside the while loop, but I think you're confusing yourself with j and i inside the loop. You might consider slightly more descriptive names--which will make your code much easier to reason about.
You need to keep a counter of how many numbers you read so you can divide the total by this number to get the average.
Edited the while loop:
while(true){
int e=input.nextInt();
if(e==0) break;
h+=e;
numberOfItems++;
}
Your original implementation called nextInt() twice, which has the effect of discarding every other number (which is definitely not what you intended to do).
Assuming that you asking the user only once, to enter and if the number if zero you simply want to display the average. you need a variable declared outside the while loop that will keep adding different numbers entered by the user, along with a second variable which track the number of cases entered by the user and keep incrementing itself by one till number is not zero as entered by the user. And as the user Enters 0, the loop will break and here our Average will be displayed.
import java.util.Scanner;
public class LoopAverage
{
public static void main(String[] args0)
{
Scanner scan = new Scanner(System.in);
System.out.println("Enter any Integer value : ");
int value = -1, sum = 0, count = 0;
while((value = scan.nextInt()) != 0)
{
count++;
sum = sum + value;
}
System.out.println("Average : " + (sum / count));
}
}
Hope that might help,
Regards
yes, oodles of logical errors.
your while loop condition is wrong, you're consuming the first value
you enter and unless that number is 0 you never enter the loop at all
i var has no purpose
you're breaking after one iteration
you're not calculating a running total
you're not incrementing a count for the average dividend
you're not calculating an average
This looks like you threw some code together and posted it. The most
glaring errors would have been found just by attempting to run it.
Some other things to consider:
Make sure to check for divide by 0
If you do an integer division, you might end up with an incorrect
average, as it will be rounded. Best to cast either the divisor or
dividend to a float
variable names should be helpful, get into the habit of using them
I recommend you to refer to the condition of "while" loop: if condition meets, what would the program do?
(If you know a little bit VB, what is the difference between do...until... and do...while...?)
Also, when you call scanner.nextInt(), what does the program do? For each input, how should you call it?
Last but not least, when should you use "break" or "continue"?
For the fundamentals, if you are in a course, recommend you to understand the notes. Or you can find some good books explaining details of Java. e.g. Thinking in Java
Enjoy learning Java.

Categories