My logic seems to work for every one of the examples, but when I try to submit it, it comes up as wrong because there is one test input (which is not revealed) that somehow results in my code spitting out "24hours and 10min" which is wrong and that the answer should be "0hours and 10min".
import java.io.IOException;
import java.util.Scanner;
public class Main {
public static void main(String[] args) throws IOException {
Scanner sc = new Scanner(System.in);
int x = sc.nextInt();
int xminutes = sc.nextInt();
int y = sc.nextInt();
int yminutes = sc.nextInt();
int xm = x\*60 + xminutes;
if (y\<=x)y+=24;
int ym = y\*60 + yminutes;
System.out.println("O JOGO DUROU "+((ym-xm)/60)+" HORA(S) E "+ ((ym-xm)%60) +" MINUTO(S)");
}
}
Let's assume the times are begin=9:10 end=9:20. The correct answer is 10 minutes, obviously.
Then x = y = 9 and you execute if (y<=x)y+=24, which is where the extra 24 comes from.
You need to consider the whole times (xm and ym) in order to decide whether the 'end' is the next day after 'begin', and you must add 24 hours (or 24 * 60 minutes).
Your code will fail for input "7 30 7 40", because you only compare the hours when checking the day-rollover. I suggest to first convert the input into "minute of the day", then calculate the difference. If negative, add 24 hours.
Such exercices are best solved with (JUnit) unit tests and pure functions which allow you to test automatically without having to run the program manually and provide input.
package example;
import org.junit.jupiter.api.Test;
import java.util.Scanner;
import static org.junit.jupiter.api.Assertions.assertEquals;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
final int startHour = sc.nextInt();
final int startMinutes = sc.nextInt();
final int endHour = sc.nextInt();
final int endMinutes = sc.nextInt();
originalCode(startHour, startMinutes, endHour, endMinutes);
newCode(startHour, startMinutes, endHour, endMinutes);
}
private static void originalCode(final int startHour, final int startMinutes, int endHour, final int endMinutes) {
int xm = startHour * 60 + startMinutes;
if (endHour <= startHour) {
endHour += 24;
}
int ym = endHour * 60 + endMinutes;
System.out.println("O JOGO DUROU " + (ym - xm) / 60 + " HORA(S) E " + (ym - xm) % 60 + " MINUTO(S)");
}
private static void newCode(final int startHour, final int startMinutes, int endHour, final int endMinutes) {
final int diff = getDiffInMinutes(startHour, startMinutes, endHour, endMinutes);
System.out.println("Duration is " + hoursOfMinutes(diff) + ":" + minutesOfMinutes(diff));
}
private static int getDiffInMinutes(
final int startHour,
final int startMinutes,
final int endHour,
final int endMinutes) {
final int diff = toMinutes(endHour, endMinutes) - toMinutes(startHour, startMinutes);
return diff <= 0
? diff + 24 * 60
: diff;
// or (difficult to understand, not recommended):
// return (diff + 24 * 60 - 1) % (24 * 60) + 1;
}
private static int toMinutes(final int startHour, final int startMinutes) {
return startHour * 60 + startMinutes;
}
private static int minutesOfMinutes(final int minutes) { // that's a weird name ...
return minutes % 60;
}
private static int hoursOfMinutes(final int minutes) {
return minutes / 60; // integer division
}
#Test
void testHoursOfMinutes() {
assertEquals(0, hoursOfMinutes(0));
assertEquals(0, hoursOfMinutes(59));
assertEquals(1, hoursOfMinutes(60));
assertEquals(1, hoursOfMinutes(61));
assertEquals(1, hoursOfMinutes(90));
assertEquals(23, hoursOfMinutes(1400));
assertEquals(24, hoursOfMinutes(1440));
}
#Test
void testMinutesOfMinutes() {
assertEquals(0, minutesOfMinutes(0));
assertEquals(59, minutesOfMinutes(59));
assertEquals(0, minutesOfMinutes(60));
assertEquals(1, minutesOfMinutes(61));
assertEquals(30, minutesOfMinutes(90));
assertEquals(20, minutesOfMinutes(1400));
assertEquals(0, minutesOfMinutes(1440));
}
#Test
void testToMinutes() {
assertEquals(0, toMinutes(0, 0));
assertEquals(30, toMinutes(0, 30));
assertEquals(60, toMinutes(1, 0));
assertEquals(90, toMinutes(1, 30));
assertEquals(1440, toMinutes(24, 0));
}
#Test
void testDiffInMinutes() {
assertEquals(40, getDiffInMinutes(7, 20, 8, 0));
assertEquals(10, getDiffInMinutes(8, 20, 8, 30));
assertEquals(23 * 60 + 20, getDiffInMinutes(9, 0, 8, 20));
assertEquals(23 * 60 + 50, getDiffInMinutes(10, 20, 10, 10));
// minimum 1 minute, maximum 24 hours
assertEquals(24 * 60, getDiffInMinutes(11, 0, 11, 0));
}
#Test
void runOriginal() {
originalCode(7, 20, 8, 0); // 00:40
originalCode(8, 20, 8, 30); // 00:10
originalCode(9, 0, 8, 20); // 23:20
originalCode(10, 20, 10, 10); // 23:50
}
#Test
void runNew() {
newCode(7, 20, 8, 0); // 00:40
newCode(8, 20, 8, 30); // 00:10
newCode(9, 0, 8, 20); // 23:20
newCode(10, 20, 10, 10); // 23:50
}
}
Of course, nothing prevents you from calculating the difference for hours and minutes separately, but this forces you to keep track of the carry.
As you can see from above, each simple functionality is covered by a unit test. You are safe to refactor and not break anything. Smaller things are then combined into more complicated things. Unit tests let you sleep well and allow you to build the solution step by step.
Related
I'm experimenting with OLSMultipleLinearRegression and I wonder which of my parameters has most impact on the prediction. I do not understand which method in OLSMultipleLinearRegression that will return that information.
static void test() {
double y[] = {110, 120, 135, 140};
double data[][] = {
{9, 100},
{21, 260},
{29, 490},
{41, 650}
};
OLSMultipleLinearRegression regression = new OLSMultipleLinearRegression();
regression.newSampleData(y, data);
double[] beta = regression.estimateRegressionParameters();
for(int i = 0;i<beta.length;i++) {
System.out.printf("b%d = %.3f\n",i, beta[i]);
}
int ROW = 3;
double value = y[ROW];
double predict = beta[0] + beta[1] * data[ROW][0] + beta[2] * data[ROW][1];
System.out.printf("y=%.3f + %.3f * %.3f + %.3f * %.3f\n", beta[0],beta[1],data[ROW][0],beta[2],data[ROW][1]);
System.out.printf("predict=%.3f value=%.3f\n", predict, value );
}
this.maxHp = 100;
this.hp = this.maxHp;
it's mean objeact got 100hp and if we hit object, it's subtracted 5 hp from object.
here is method th check if object take damage:
public boolean takeDamage(int dmg) {
hp -= dmg;
reddish += 1.0f;
if (hp <= 0) {
return true;
}
return false;
}
here is method to check if bullet hit object:
public void checkCollisions() {
List<Bullet> b = bulletEmitter.getActiveList();
for (int i = 0; i < b.size(); i++) {
for (int j = 0; j < players.size(); j++) {
if (b.get(i).isArmed() && players.get(j).getHitArea().contains(b.get(i).getPosition())) {
b.get(i).deactivate();
players.get(j).takeDamage(5);
map.clearGround(b.get(i).getPosition().x, b.get(i).getPosition().y, 8);
continue;
}
}
I need to show taking damage (int dmg), damage might be any variable which we put in method takeDamage(int dmg). int this case int dmg = 5;
I can't calculate it this:
result = maxHp - hp
increase result on 5hp with evry hit
5.. 10.. 15.. 20..
here is method, which i put font in:
damageFont.draw(batch, "" + (maxHp - hp), position.x, position.y + 130, 85, 1, false);
}
}
(maxHp - hp) - increase result on 5hp with evry hit 5.. 10.. 15.. 20..
instead this, i need to calculate ammount of deal damage, but not with constant values.
(maxHp - hp) something instead this just should return 5, if we put 5 in takeDamage(int dmg)
or 10, if we put 10.
it's amount of damage take with evry hit:
should be 5, 5, 5, 5
not: 5... 10... 15... 20
Just like MarsAtomic mentioned you allready have your damage per hit, just save it as a new instance variable and display it instead of (maxHp - hp):
private int damageTaken;
public boolean takeDamage(int dmg) {
damageTaken = dmg;
hp -= dmg;
reddish += 1.0f;
if (hp <= 0) {
return true;
}
return false;
}
and when you draw your font:
damageFont.draw(batch, "" + damageTaken, position.x, position.y + 130, 85, 1, false);
I have an array of candy images which are randomly chosen. There are candies falling and I want to make a new one fall every 5 seconds, and I know I have to use millis() - but how would I implement it into my program? I tried using millis() like so:
int time = millis();
if (time<5*1000)
{
image(goodCandy[rand], randX, goodY, randCandyW, randCandyH);
goodY = goodY + (candySpeed * yDirCandy);
time = millis();
}
But it only appears for 5 seconds then goes away.
I also tried:
int time = millis();
if (millis() - time >= 5000)
{
image(goodCandy[rand], randX, goodY, randCandyW, randCandyH);
goodY = goodY + (candySpeed * yDirCandy);
time = millis();
}
But it didn't work.
Here's the simplified code:
PImage [] goodCandy = new PImage [3];
int candySpeed = 20;
int yDirCandy = 1;
int candyY = 10;
int candyX = 200;
int candyW = 187;
int candyH = 121;
int randCandyW = 100;
int randCandyH = 100;
int goodY = -200;
int rand=(int) (2*Math.random()) +1;
int randX = (int) (1500*Math.random())+20;
void setup() {
for (int i=0; i<goodCandy.length; i++) {
goodCandy[i] = loadImage("goodCandy" + i + ".png");
}
void draw() {
if (current=="play") {
loadStuff();
}
}
void loadStuff() {
image(candy, candyX, candyY, candyW, candyH); //original candy
candyY = candyY + (candySpeed * yDirCandy);
int time = millis();
if (millis() - time >= 5000)
{
image(goodCandy[rand], randX, goodY, randCandyW, randCandyH);
goodY = goodY + (candySpeed * yDirCandy);
time = millis();
}
//for (int i=0; i<time; i++) {
// image(goodCandy[rand], randX, goodY, randCandyW, randCandyH);
// goodY = goodY + (candySpeed * yDirCandy);
// time = millis();
//}
}
Any ideas how I could make millis() work so I can have a random candy falling every 5 seconds?
Thanks
Please try to get into the habit of breaking your problem down into smaller pieces and only taking on those pieces one at a time. For example, you should probably start with a simpler sketch that just shows a random circle every 5 seconds.
Here's a small example that shows how you would use the millis() function to draw something every 5 seconds:
int lastCircleTime = 0;
void draw() {
if (millis() > lastCircleTime + 5*1000) {
ellipse(random(width), random(height), 20, 20);
lastCircleTime = millis();
}
}
If you're still having trouble, please post a MCVE showing exactly which step you're stuck on. Note that this should not be your whole sketch. It should be a small example like this one. Good luck.
Hi I am trying to create a countdown stopwatch timer for my gym.
Here is what I have for the actual displaying and decrementing of the time: (bear in mind I used my normal stopwatch one and just edited it briefly to decrement. It is still first pass and I still want to thread it all at some stage but for now this should work. )
new Timer(1,new ActionListener(){
public void actionPerformed(ActionEvent e){
int seconds = (int)(System.currentTimeMillis()-watchStart)/1000;
int days = seconds / 86400;
//these are just initialization values for testing
int startHour, startMin, startSec;
startHour = 5;
startMin = 5;
startSec = 0;
int hours = (seconds / 3600) - (days * 24);
int min = (seconds / 60) - (days * 1440) - (hours * 60);
int sec = seconds % 60;
String s = String.format("%02d:%02d:%02d", startHour - hours, startMin - min, ((startSec == 0) ? startSec = 60 : startSec) - sec );
displayTimeLabel.setText(s);
}
});
Now my issue is:
a) It is not decrementing the minute to start with (if it starts at say 5 minutes)
b) If I start it at 30 seconds it will go into negative until it reaches a full minute then decrements the minute. ( I think I will need a method like if == 0 then minute - 1? but I fear that will break the actual count?)
Thanks.
Edit: Full program:
package countdown;
import java.awt.*;
import static java.awt.Frame.MAXIMIZED_BOTH;
import javax.swing.Timer;
import javax.swing.*;
import java.awt.event.*;
public class CountDown extends JFrame implements ActionListener{
private int hour;
private int minute;
private int second;
// The component that shows the elapsed time.
private JLabel displayTimeLabel;
private long watchStart, watchEnd;
private Timer theChronometer;
// Keeps track of time when pausing the Timer.
private long pausedTime;
// Lets the program know if starting or resuming
private boolean paused = false;
// Button that changes from "Start" to "Resume" depending on pause status.
private JButton activateTimerButton;
// run the program
public static void main(String[] args) {
CountDown count = new CountDown();
count.setVisible(true);
count.setLocationRelativeTo(null);
}
public CountDown(){
// initialize
super();
setExtendedState(MAXIMIZED_BOTH);
setLayout(new BorderLayout());
setLayout(new GridLayout(2,1));
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setTitle("CrossFit Slam");
setBackground(Color.black);
setForeground(Color.white);
Font largeFontBOLD = new Font("Calibri", Font.BOLD,20);
Font largeFontPLAIN = new Font("Calibri", Font.PLAIN,200);
JPanel buttonPanel = new JPanel();
buttonPanel.setLayout(new FlowLayout());
activateTimerButton = new JButton("Start");// will display resume when the watch is paused
JButton stopTimerButton = new JButton("Stop");
JButton pauseTimerButton = new JButton("Pause");
// register buttons to generate events when clicked
activateTimerButton.addActionListener(this);
stopTimerButton.addActionListener(this);
pauseTimerButton.addActionListener(this);
// the display for elapsed time
displayTimeLabel = new JLabel("00:00:00");
displayTimeLabel.setHorizontalAlignment(JLabel.CENTER);
buttonPanel.setBackground(Color.black);
buttonPanel.setForeground(Color.white);
displayTimeLabel.setFont(largeFontPLAIN);
displayTimeLabel.setForeground(Color.white);
displayTimeLabel.setBackground(Color.black);
activateTimerButton.setFont(largeFontBOLD);
stopTimerButton.setFont(largeFontBOLD);
pauseTimerButton.setFont(largeFontBOLD);
displayTimeLabel.setOpaque(true);
buttonPanel.add(activateTimerButton);
buttonPanel.add(stopTimerButton);
buttonPanel.add(pauseTimerButton);
add(displayTimeLabel);
add(buttonPanel, BorderLayout.PAGE_END);
theChronometer =
new Timer(1,new ActionListener(){
public void actionPerformed(ActionEvent e){
int seconds = (int)(System.currentTimeMillis()-watchStart)/1000;
int days = seconds / 86400;
int startHour, startMin, startSec;
startHour = 5;
startMin = 5;
startSec = 0;
int hours = (seconds / 3600) - (days * 24);
int min = (seconds / 60) - (days * 1440) - (hours * 60);
int sec = seconds % 60;
String s = String.format("%02d:%02d:%02d", startHour - hours, startMin - min, ((startSec == 0) ? startSec = 60 : startSec) - sec );
displayTimeLabel.setText(s);
}
});
}
public void actionPerformed(ActionEvent e){
if(e.getActionCommand().equals("Stop")){theChronometer.stop();}
else if(e.getActionCommand().equals("Start") || e.getActionCommand().equals("Resume")){
if(!paused){
watchStart = System.currentTimeMillis();
theChronometer.start();
}
else{
watchStart = System.currentTimeMillis()+pausedTime;
pausedTime = 0;
theChronometer.start();
paused = false;
activateTimerButton.setText("Start");
}
}
else if(e.getActionCommand().equals("Pause")){
long now = System.currentTimeMillis();
pausedTime -= (now - watchStart);
theChronometer.stop();
paused = true;
activateTimerButton.setText("Resume");
}
}
}
What you're trying to is easily achieved using standard libraries, in particular the Date class.
DateFormat f = new SimpleDateFormat("HH:mm:ss");
f.setTimeZone(TimeZone.getTimeZone("GMT"));
long startingTime = TimeUnit.HOURS.toMillis(5) + TimeUnit.MINUTES.toMillis(5);
public void actionPerformed(ActionEvent e) {
long elapsed = System.currentTimeMillis() - startTimestamp;
long displayTs = startingTime - elapsed;
String out;
if (displayTs >= 0) {
out = f.format(new Date(displayTs));
} else {
out = "-" + f.format(new Date(-displayTs));
}
displayTimeLabel.setText(out);
}
All of this is in the standard Java libraries and the Javadoc on the methods/classes should provide insight on what's happening.
I have a calculator that is suposed to figure the volume and the results come back as "0"
JButton btnCalculateVlmn = new JButton("Calculate Hot Tub Volume");
btnCalculateVlmn.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent arg0)
{
double width = 0, length = 0, depth = 0, volume = 0;
String lengthString, widthString, depthString;
lengthString = hotTubLengthText.getText();
widthString = hotTubWidthText.getText();
depthString = hotTubDepthText.getText();
try
{
if (rdbtnRoundTub.isSelected())
{
volume = Math.PI * Math.pow(length / 2.0, 2) * depth;
}
else
{
volume = Math.PI * Math.pow(length * width, 2)
* depth;
}
DecimalFormat formatter = new DecimalFormat("#,###,###.###");
hotTubVolumeText.setText("" + formatter.format(volume));
}
catch (NumberFormatException e)
{
labelTubStatus
.setText("Fill in all fields");
}
}
});
btnCalculateVlmn.setBounds(20, 200, 180, 20);
hotTubs.add(btnCalculateVlmn);
JButton Exit = new JButton("Exit");
Exit.setBounds(220, 200, 80, 20);
Exit.addActionListener(this);
hotTubs.add(Exit);
}
depth is declared as 0 and never overwritten... so the volume is always 0.
I guess you should do something like:
...
double width = 0, length = 0, depth = 0, volume = 0;
String lengthString, widthString, depthString;
lengthString = hotTubLengthText.getText();
widthString = hotTubWidthText.getText();
depthString = hotTubDepthText.getText();
depth = Double.valueOf(depthString);
length = Double.valueOf(lengthString);
width = Double.valueOf(widthString);
....
You forgot to convert the strings (lengthString, widthString and depthString) to doubles and assign them to your variables (length, width and depth).
you have depth = 0 and
anything * 0 = 0
you forgot to convert your strings from the input fields to double.
you get 0 as result because you set length and width to 0
In both branches of your main if condition your expressions ending * depth. However this depth variable seems to be set to 0 and not set to anything else. So volume will always be 0 since whatever you multiply by 0 will be 0.
Maybe you've wanted to use depthString. Something like this:
depth = Integer.parseInt(depthString);
if (rdbtnRoundTub.isSelected())
{
volume = Math.PI * Math.pow(length / 2.0, 2) * depth;
}
else
{
volume = Math.PI * Math.pow(length * width, 2) * depth;
}