Spotify puzzle Best Before - java

I'm pretty new to Java and tried the Best Before puzzle from Spotify yesterday. I get the "Wrong Answer" error when I send it in.
Checking for other solutions didn't help and I cant figure out which input gives a wrong answer.
At best you would just tell me which code lead to the wrong answer. I should be able to correct the code myself then.
import java.util.Scanner;
public class Bestbefore {
public static void main(String[] args) {
//Process Input String
Scanner scanner = new Scanner(System.in);
String dateString = scanner.nextLine();
Integer a,b,c;
a=Integer.parseInt(dateString.substring(0,dateString.indexOf("/")));
b=Integer.parseInt(dateString.substring(dateString.indexOf("/")+1,
dateString.lastIndexOf("/")));
c=Integer.parseInt(dateString.substring(dateString.lastIndexOf("/")+1));
int[][] va={ //All possible combinations
{a,b,c},
{a,c,b},
{b,a,c},
{b,c,a},
{c,a,b},
{c,b,a}
};
int i=0;
while (!checkDate(va[i][0], va[i][1], va[i][2])
&& i<5) // get the first valid date combination
i++;
//to prevent OutofBoundsException of the while loop
if (!checkDate(va[i][0], va[i][1], va[i][2]))
i++;
if (i==6)
System.out.println(dateString+" is illegal");
else
{ //compare the rest of the va-Array and save the position of the lowest Date in i
for (int k=i+1;k<6;k++)
if (checkDate(va[k][0], va[k][1], va[k][2]))
{
if (ageOfDate(va[k][0], va[k][1], va[k][2])
< ageOfDate(va[i][0], va[i][1], va[i][2]))
i=k;
}
System.out.println(getDate(va[i][0], va[i][1], va[i][2]));
}
}
public static boolean checkDate(int day,int month, int year)
{
int[] dpm={31,28,31,30,31,31,30,31,30,31,30,31}; //Days per Month
if (year<2000)
year=year+2000;
if((year%4==0 && year%100!=0) || year%400==0)
dpm[1]=29; //Leapyear correction
if (month==0 || month>12)
return false;
else
if (day==0 || day>dpm[month-1])
return false;
else
return true;
}
public static int ageOfDate(int day,int month, int year) //to compare 2 dates
{
return ((year*10000)+(month*100)+day);
}
public static String getDate(int day,int month, int year) //for the Output
{
String smonth = String.valueOf(month);
String sday = String.valueOf(day);
if (year<2000)
year=year+2000;
if (month<10)
smonth="0"+smonth;
if (day<10)
sday="0"+sday;
return (year+"-"+smonth+"-"+sday);
}
}

June has 30 days, August and July both have 31. Your array dpm is initialized in a wrong manner. So here is where you can go wrong: 31/06/20 -> earliest possible is 20-th of June 2031 instead of 31-st of June 2020.
Hope this solves your problem.

Might be that you don't handle negative numbers. -3/5/2012 would be valid. Also, your program does not handle invalid integers gracefully as it will exit with an exception. If I pass "as/5/12" output should be "as/5/12 is illegal".
FYI, the following
while (!checkDate(va[i][0], va[i][1], va[i][2])
&& i<5) // get the first valid date combination
i++;
//to prevent OutofBoundsException of the while loop
if (!checkDate(va[i][0], va[i][1], va[i][2]))
i++;
Could be reduced to
while (i <= 5 && !checkDate(va[i][0], va[i][1], va[i][2]))
i++;

Related

error: class, interface, or enum expected [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
I have the following code that I am trying to get working for a project in a class that I am in. I will also include the requirements
Design and implement the class Day that implements the day of the week in a program. The class Day should store the day, such as Sun for Sunday. The program should be able to perform the following operations on an object of type Day:
A. Set the day.
B. Print the day.
C. Return the day.
D. Return the next day.
E. Return the previous day.
F. Calculate and return the day by adding certain days to the current day. For example, if the current day is Monday and we add four days, the day to be returned is Friday. Similarly, if today is Tuesday and we add 13 days, the day to be returned is Monday.
G. Add the appropriate constructors.
H. Write the definitions of the methods to implement the operations for the class Day, as defined in A through G.
I. Write a program to test various operations on the class Day.
The code is as follows:
`import java.util.*;
class Day {
private int dayValue;
private static final int INVALID = -1;
public Day() { this.dayValue = INVALID; }
public Day(String day) { setDay(day); }
public Day(int day) { this.dayValue = (day<0 || day>6) ? INVALID : day; }
public void setDay(String day) {
if(day.equals("sunday") || day.equals("Sun")) {
this.dayValue = 0;
} else if(day.equal("monday") || day.equals("Mon")) {
this.dayValue = 1;
} else if(day.equals("tuesday") || day.equals("Tues")) {
this.dayValue = 2;
} else if(day.equal("wednesday") || day.equals("Wed")) {
this.dayValue = 3;
} else if(day.equals("thursday") || day.equals("Thurs")) {
this.dayValue = 4;
} else if(day.equal("friday") || day.equals("Fri")) {
this.dayValue = 5;
} else if(day.equal("saturday") || day.equals("Sat")) {
this.dayValue = 6;
} else {
this.dayValue = INVALID;
}
}
public String getDay() {
if (dayValue==0) { return "Sunday"; }
if (dayValue==1) { return "Monday"; }
if (dayValue==2) { return "Tuesday"; }
if (dayValue==3) { return "Wednesday"; }
if (dayValue==4) { return "Thursday"; }
if (dayValue==5) { return "Friday"; }
if (dayValue==6) { return "Saturday"; }
return "\"I don't know what day it is!\"";
}
public void printDay() {
System.out.println("When printing, your day is " + getDay()); //displays the day at the time of printing.
}
// Next Day
public String getNextDay()
{
// the compareTo() method allows us to set saturday as Sat, Sunday to Sun, etc
if((day.compareTo("sunday") == 0) || (day.compareTo("Sun") == 0))
return ("Monday");
else if((day.compareTo("monday") == 0) || (day.compareTo("Mon") == 0))
return ("Tuesday");
else if((day.compareTo("tuesday") == 0) || (day.compareTo("Tue") == 0))
return ("Wednesday");
else if((day.compareTo("wednesday") == 0) || (day.compareTo("Wed") == 0))
return ("Thursday");
else if((day.compareTo("thursday") == 0) || (day.compareTo("Thu") == 0))
return ("Friday");
else if((day.compareTo("friday") == 0) || (day.compareTo("Fri") == 0))
return ("Saturday");
else if((day.compareTo("saturday") == 0) || (day.compareTo("Sat") == 0))
return ("Sunday");
else
return ("\"I don't know what day it is!\"");
}
// Previous day
public String getPreDay()
{
if((day.compareTo("sunday") == 0) || (day.compareTo("Sun") == 0))
return ("Saturday");
else if((day.compareTo("saturday") == 0) || (day.compareTo("Sat") == 0))
return ("Friday");
else if((day.compareTo("friday") == 0) || (day.compareTo("Fri") == 0))
return ("Thursday");
else if((day.compareTo("thursday") == 0) || (day.compareTo("Thu") == 0))
return ("Wednesday");
else if((day.compareTo("wednesday") == 0) || (day.compareTo("Wed") == 0))
return ("Tuesday");
else if((day.compareTo("tuesday") == 0) || (day.compareTo("Tue") == 0))
return ("Monday");
else if((day.compareTo("monday") == 0) || (day.compareTo("Mon") == 0))
return ("Sunday");
return ("\"I don't know what day it is!\"");
}
public Day calcDay(int offset) { /* your code here */ }
// extra good for printin
public String toString() { return getDay(); }
}
// main execution point
public static void main (String args[]) {
{
// One of its weakness is the case sensitive: sun, Sunday, sunday, SuNdAy...
// need more codes to avoid this case sensitiveness...
// instantiate testday object of type MyDay class
// with "Sun" as initial value....
Day testday = new Day("Sun");
// prompt user to set his/her day
System.out.print("Enter day to set your day: ");
// read and store user's day
String storeday = readinput.nextLine().toLowerCase(); //Changes input into all lowercase to deal with variations
// invoke setDay() method to set a day defined by user
testday.setDay(storeday);
// invoke getDay() method to get a day
System.out.println("Your day is " + testday.getDay());
// test printing by invoking printDay() method
testday.printDay();
// invoke getPreDay() method to get the previous day
System.out.println("Your previous day is " + testday.getPreDay());
// invoke getNextDay() method to get the next day
System.out.println("Your next day is " + testday.getNextDay());
System.out.println("How many Days would you like to add? " + testday.calcNextDay());
}
}`
I am receiving the following error:
Day.java:92: error: class, interface, or enum expected
public static void main () {
^
Day.java:101: error: class, interface, or enum expected
System.out.print("Enter day to set your day: ");
^
Day.java:103: error: class, interface, or enum expected
String storeday = readinput.nextLine().toLowerCase(); //Changes input into all lowercase to deal with variations
^
Day.java:105: error: class, interface, or enum expected
testday.setDay(storeday);
^
Day.java:107: error: class, interface, or enum expected
System.out.println("Your day is " + testday.getDay());
^
Day.java:109: error: class, interface, or enum expected
testday.printDay();
^
Day.java:111: error: class, interface, or enum expected
System.out.println("Your previous day is " + testday.getPreDay());
^
Day.java:113: error: class, interface, or enum expected
System.out.println("Your next day is " + testday.getNextDay());
^
Day.java:115: error: class, interface, or enum expected
System.out.println("How many Days would you like to add? " + testday.calcNextDay());
^
Day.java:116: error: class, interface, or enum expected
}
^
10 errors
Originally my code looked like this
public class Day
{
static Scanner readinput = new Scanner(System.in);
String day;
public Day(String day)
{
day = "Sunday";
}
// set the day
public void setDay(String theDay)
{
day = theDay;
}
public String getDay()
{
return day;
}
public void printDay()
{
System.out.println("When printing, your day is " + day);
}
Why not use arrays?
With an array, you could handle things in a more concise and simple way.
String[] dayOfWeekShortNames = new String[] {
"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"
};
String[] dayOfWeekLongNames = new String[] {
"Sunday", "Monday", "Wednesday", "Thursday", "Friday", "Saturday"
};
Then, simply validate whether the value passed in parameter is correct.
public void setDay(String dayOfWeek) {
if (dayOfWeek == null || (0 < dayOfWeek.length() && dayOfWeek.trim().length() == 0))
throw new IllegalArgumentException("dayOfWeek cannot be null or white space.");
for (int i = 0; i < dayOfWeek.length(); i++)
if (dayOfWeek.charAt(i).isDigit())
throw new IllegalArgumentException("dayOfWeek cannot be numeric.");
if (dayOfWeek.length() < 3) // for short names
throw new IllegalArgumentException("dayOfWeek must be at least 3 characters long.");
for (int i = 0; i < dayOfWeekShortNames.length && i < dayOfWeekLongNames.length; i++)
if (dayOfWeekShortNames[i].toLowerCase() == dayOfWeek.ToLowerCase()
|| dayOfWeekLongNames[i].toLowerCase() == dayOfWeek.ToLowerCase()) {
dayValue = i;
return;
}
throw new IllegalArgumentException(
"Day of week: " + dayOfWeek + " could not be found.");
}
This is just a simple example off the top of my head.
Why not use a Program class?
Instead of just writing the main() method out of nowhere which can lead to multiple compile-time errors, perhaps one great deal would be to locate your main method inside a Program class so that it is a member of a class, and the compiler shall no longer complaint. Furthermore, the advantage of doing so shall make it obvious, at least at some extent, that your program entry point is there. This Program class shall contain nothing more than the main() method.
public class Program {
public static void main(String args[]) {
// You code here...
}
}
As for the user inputs, perhaps using the Console class... Here's an example on how to use it.
I/O from the Command Line
Disclaimer
I have not tested this code and is provided as-is for example purposes only. I am not a Java expert, and I did my best off the top of my head to help.
EDIT
I did not use an array because I wanted to store the value as a string and not the index.
In fact, the code sample in your question stores the day of week in an integer value as per this line:
private int dayValue;
Hence the assignments when you set the day as follows:
public void setDay(String day) {
if (day == "sunday" || day == "Sun")
dayValue = 0;
else if (day == "monday" || day == "Mon")
dayValue = 1;
...
}
The above actually stores the day of week in an integer format which shall satisfy most of any systems which is going to use days of week. Plus, you cannot guarantee the exact syntax of a string input by the user so that even if you either compare day == "sunday" or day == "Sun", you would have to adjust your casing according to the string you're expecting in your setDay() function, which in my opinion doesn't make sense.
The most common practice for such behaviour playing around with days of week, etc. is to use arrays with the proper expected casing, then compare the input values with either uppercase or lowercase values for both, the input and the value from the array (only this can guarantee a perfect match), then you can store the index in you dayValue private member. Then, when retrieving the day of week through the getDay() function, you can simply write a single line of code which can assure you to work flawlessly, since you captured any potential errors while setting the input through the setDay() method.
public String getDay() { return dayOfWeekLongNames[dayValue]; }
And you shall get the name of the day of week previously set, instead of having to write if statements over and over again.
Another way to approach the problem is to use an enum for the days of the week. Here's a working example provided to show the general idea:
public class Day
{
enum DAY {
MONDAY("Monday"), TUESDAY("Tuesday"), WEDNESDAY("Wednesday"), THURSDAY("Thursday"), FRIDAY("Friday"), SATURDAY(
"Saturday"), SUNDAY("Sunday");
public static DAY parse(final String value)
{
for (final DAY day : values())
{
if (day.description.equalsIgnoreCase(value) || day.description.substring(0, 3).equalsIgnoreCase(value))
{
return day;
}
}
return null;
}
private String description;
private DAY(final String description)
{
this.description = description;
}
#Override
public String toString()
{
return description;
}
}
public static void main(final String args[])
{
Day myDay;
myDay = new Day(DAY.SUNDAY);
System.out.println(myDay);
System.out.println(myDay.getPreviousDay());
System.out.println(myDay.getNextDay());
myDay = new Day("monday");
System.out.println(myDay);
System.out.println(myDay.getPreviousDay());
System.out.println(myDay.getNextDay());
myDay = new Day("wed");
System.out.println(myDay);
System.out.println(myDay.getPreviousDay());
System.out.println(myDay.getNextDay());
}
private final DAY day;
public Day(final DAY day)
{
this.day = day;
}
public Day(final String day)
{
this.day = DAY.parse(day);
}
public DAY getNextDay()
{
final DAY[] days = DAY.values();
return days[(day.ordinal() + 1) % days.length];
}
public DAY getPreviousDay()
{
final DAY[] days = DAY.values();
return days[((day.ordinal() - 1) + days.length) % days.length];
}
#Override
public String toString()
{
return day.toString();
}
}

Constructor not setting values? Get method not working [duplicate]

When I try to run this program, the result is always null, 0 0. Why do the values of monthName, day, and year not show up when the getDay() method is invoked and printed on the screen.
public class Assignment1 {
public static void main(String[] args) {
//creates an array of type Date filled with two LongDate objects
Date [] collectionOfDates = { new LongDate("February",2,1996), new LongDate("February",13,1999) };
// loops through the array and displays output of getDate() for each object
for( int i = 0; i < collectionOfDates.length; i++ ) {
System.out.println( collectionOfDates[i].getDate() );
}
}
}
For your information, the LongDate class is a subclass of the Date class which contains methods editDay() and editYear() along with several others. The LongDate method is listed below.
Any help greatly appreciated, Thanks. Also, feel free to comment if you want more information.
public class LongDate extends Date {
private String monthName;
private int day;
private int year;
public LongDate() {
}
public LongDate(String m, int d, int y) {
super.editday(d);
super.edityear(y);
editMonth(m);
}
public void setDate(String m, int d, int y) {
monthName = m;
day = d;
year = y;
}
public String getDate() {
StringBuilder fullDate = new StringBuilder();
fullDate.append(monthName);
fullDate.append(" ");
fullDate.append(day);
fullDate.append(", ");
fullDate.append(year);
return fullDate.toString();
}
public String getShortDate() {
int month = 0;
if (monthName == "January") {
month = 1;
} else if (monthName == "February") {
month = 2;
} else if (monthName == "March") {
month = 3;
} else if (monthName == "April") {
month = 4;
} else if (monthName == "May") {
month = 5;
} else if (monthName == "June") {
month = 6;
} else if (monthName == "July") {
month = 7;
} else if (monthName == "August") {
month = 8;
} else if (monthName == "September") {
month = 9;
} else if (monthName == "October") {
month = 10;
} else if (monthName == "November") {
month = 11;
} else if (monthName == "December") {
month = 12;
}
StringBuilder shortDate = new StringBuilder();
shortDate.append(month);
shortDate.append("/");
shortDate.append(day);
shortDate.append("/");
shortDate.append(year);
return shortDate.toString();
}
protected String editMonth(String m) {
// asks person to try again if month is not capitalized and spelled properly
if (m != "January" && m != "February" && m != "March" && m != "April" && m != "May" && m != "June" && m != "July" && m != "August" && m != "September" && m != "October" && m != "November" && m != "December") {
m = Input.getString( "Invalid month. Please type the month again." );
return m;
} else
return m;
}
}
There's nothing in the constructor of LongDate which sets the fields (monthName, day, and year) that getDate() reads.
I assume that the Date#editDay() and Date#editYear() functions look similar to LongDate#editMonth(). Note that editMonth() does not assign a value to the monthName field!
You should compare your strings with equals() and not ==. The equals() method compares string values, whereas == compares object references, which is not what you want here. So change:
if (monthName == "January") {
to:
if (monthName.equals("January")) {
and similarly for the other comparisons.
Couple of issues. First:
public LongDate(String m, int d, int y) {
super.day(d);
super.year(y);
editMonth(m);
}
You don't show Date so it is unclear to us what day() and year() are supposed to do, but regardless:
public class LongDate extends Date {
private String monthName;
private int day;
private int year;
...
}
Your declarations of these fields are hiding any similar fields that the base presumably has. In any case, at no point in your constructor are you setting this.day or this.year to anything, and so, of course, they remain at their initial value of 0.
You need to clean up your code a bit. Either refer to the correct day and year, or make sure you are setting and getting the base class' version of those fields instead of redeclaring them in the subclass (again, not sure what your base implementation does).
You may want to have a look at the official tutorial on Inheritance. It's concise and well-written and covers topics like overriding methods, hiding fields, etc. I think it will give you a good starting point for solving your issues here.
And, of course, comparing strings with == here will lead to other issues in the future: How do I compare strings in Java?
Your editMonth method returns a string, instead it should set the month:
monthName = m;
Another option is to keep the editMonth method the same, but in your constructor put:
monthName = editName(m);

Creating Java Program to Return Previous, Current, and Next Day

I am creating a final program for my introductory java programming course and I am in need of some assistance. The current day and the next day values are not correctly printing. I have read over my code again and again but I cannot wrap my head around why this is not running properly. Any help/advice is GREATLY appreciated!
The guidelines I must follow for this program assignment are as follows:
A. Set the day.
B. Print the day.
C. Return the day.
D. Return the next day.
E. Return the previous day.
F. Calculate and return the day by adding certain days to the current day. For example, if the current day is Monday and we add four days, the day to be returned is Friday. Similarly, if today is Tuesday and we add 13 days, the day to be returned is Monday.
G. Add the appropriate constructors.
H. Write the definitions of the methods to implement the operations for the class Day, as defined in A through G.
I. Write a program to test various operations on the class Day.
*EDIT***
This new code I have written works excellent until I set the day as Monday. The issue I am having is within the previousDay method. I'm trying to add an if/else statement but I cannot get it to compile correctly without receive an outOfBounds Exception error. What is a good way to accomplish this in a String array?
The UPDATED CODE I have written in attempt to accomplish this program task:
public class Day {
int index;
static String[] days = {"Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"};
public Day(String currentDay)
{
for(int i = 0; i < days.length; i++)
{
if(currentDay.equals(days[i]))
{
index = i;
return;
}
}
System.out.println("Days is invalid");
}
public void printDay()
{
System.out.println("The Day is " + days[index]);
}
public String returnDay()
{
return days[index];
}
public String returnNextDay()
{
return days[(index + 1 )% days.length];
}
public String returnPreviousDay()
{
if (days.length <= 1)
return days[index + 6];
else return days[(index - 1)%days.length];
}
public String whatDayIs(int i)
{
return days[(index + i)%days.length];
}
public static void main(String[] args)
{
Day day = new Day("Mon");
day.printDay();
System.out.println("Return Day: " + day.returnDay());
System.out.println("Next Day: " + day.returnNextDay());
System.out.println("Previous Day: " + day.returnPreviousDay());
System.out.println(day.whatDayIs(7));
}
}
Thank you for your time!
Adam
First of all, use java naming conventions. It makes your code clearer and easier to help.
You have some errors in your code:
public Day setNameDay(String Day) {
Day = Days;
return this;
}
What you do here is saving Days value in method's parameter Day which actually does nothing.
public void nextDay() {
Day++;
if (Day <8)
Day = 1;
setDay(Day);
}
Why setting day to one if it is lower than 8? You should use:
if (Day >8) {
Day = 1;
}
"The current day and the next day values are not correctly printing."
nextDay() has no print statement
public void nextDay()
{
Day++;
if (Day <8)
Day = 1;
setDay(Day);
}
And you actually need to call setDay() before Days has a value;
Day myDay = new Day();
myDay.setDay(1);
myDay.printDay();
And the fact that you have a class Day, and int Day and String Days is totally confusing for anyone who is reading your code. I'm surprised you're even able to follow it. Consider Java naming convention: variable names start with lower case.
Your code is full of problems, problems that stem from a deep non-understanding of Java.
For example, look at this:
public Day setNameDay(String Day) {
Day = Days;
return this;
}
It is not only the naming that is bad.
What do you think this method actually does?
I seriuously suggest you take the course again, and pay attention when topics like parameter passing etc. come up.
You can use the Calendar API with Date.
try below code.
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.GregorianCalendar;
public class CameoWebServiceClient {
public enum day {
SUNDAY, MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY
}
public static void main(String[] args) {
// read day
int lDay = 5;
SimpleDateFormat date_format = new SimpleDateFormat("yyyyMMdd");
System.out.println(date_format.format(new Date()));
Calendar cal1 = date_format.getCalendar();
cal1.set(Calendar.DAY_OF_WEEK, lDay);
cal1 = setDay(cal1, lDay);
System.out.println(""+curDay(cal1));
System.out.println(""+nextDay(cal1));
System.out.println(""+prevDay(cal1));
}
public static Calendar setDay(Calendar cal1, int lDay) {
cal1.set(Calendar.DAY_OF_WEEK, (lDay));
return cal1;
}
public static String curDay(Calendar cal1) {
int i = cal1.get(Calendar.DAY_OF_WEEK)-1 ;
i = i < 0 ? 6:i;
return day.values()[i]+"";
}
public static String nextDay(Calendar cal1) {
int i = cal1.get(Calendar.DAY_OF_WEEK);
i = i > 6 ? 0:i;
return day.values()[i]+"";
}
public static String prevDay(Calendar cal1) {
int i = cal1.get(Calendar.DAY_OF_WEEK)-2;
i = i < 0 ? 6:i;
return day.values()[i]+"";
}
}
Try updating your method as:
public String returnPreviousDay() {
return days[(index + days.length - 1) % days.length];
}
Here, instead of moving backwards to 0 index, I moved it forward by n - 1 days to get the previous day.
You are trying to re-invent something that already exists and it is making your life harder.
Simply store the data in a Calendar object. Use dateAdd to add and remove days, read the result.
import java.util.*;
import java.lang.*;
import java.io.*;
class Main {
public static void main(String[] args) {
Day day = new Day();
day.setDay(2);
day.printDay();
day.returnDay1(13);
day.returnDay();
day.nextDay();
day.previousDay(); }}
class Day {
int setday = 0;
int returnday=0;
String x,y;
static String[] days = {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"};
void printDay() {
if(setday < 7) {
System.out.println("The Day is " + days[setday]); }
else
System.out.println("Invalid set of day"); }
void setDay(int dayset) {
setday = dayset; }
void returnDay1(int returnday1) {
returnday = returnday1; }
void returnDay() {
if(setday < 7) {
x = days[(setday + returnday )% days.length];
System.out.println("Return Day after "+String.valueOf(returnday)+ " days is " + x); }
else
System.out.println(" "); }
void nextDay() {
if(setday < 7) {
y = days[(setday + returnday + 1 )% days.length];
System.out.println("Next Day is " + y); }
else
System.out.println(" "); }
void previousDay() {
if(setday < 7) {
y = days[(setday + returnday - 1 )% days.length];
System.out.println("Previous Day is " + y); }
else
System.out.println(" "); } }

Stuck in a while loop; calc days between two dates

I've actually been browsing for quite a while on this site, sadly without much progress. Thanks to a lot of extremely useful answers, I've learned quite a bunch of stuff though!
I'm learning Java since ... about 4 days (I guess?) so I'm not very experienced in the methods I can use.
There's this assignment we got at our univ. We shall write a program that returns how many days have passed between two dates. The only restriction is to keep the program as simple as possible, we're not allowed to use "complicated methods".
Sadly, my program is kind of stuck. If I try it out e.g. the dates 23 01 1994 and 07 04 1997, it counts only up to 01 01 1997 and suddenly stops. I have no idea why that happens, I even doubt if I fully understood what I wrote there.
Anyways, here's my code:
import java.util.Arrays;
import java.util.Scanner;
public class Datecalc {
public static int yearcounter,monthcounter,daycounter,days;
public static int[] input() {
Scanner input = new Scanner(System.in);
//Eingabe der Daten
String day1 = input.next();
String month1 = input.next();
String year1 = input.next();
String day2 = input.next();
String month2 = input.next();
String year2 = input.next();
int day1int = Integer.parseInt(day1);
int month1int = Integer.parseInt(month1);
int year1int = Integer.parseInt(year1);
int day2int = Integer.parseInt(day2);
int month2int = Integer.parseInt(month2);
int year2int = Integer.parseInt(year2);
int [] eingabe = new int [6];
eingabe[0] = day1int;
eingabe[1] = month1int;
eingabe[2] = year1int;
eingabe[3] = day2int;
eingabe[4] = month2int;
eingabe[5] = year2int;
return eingabe;
// put everything into an array to be able to use it in the main method
}
public static void main(String[] args) {
int[] eingabe = input();
days=0;
daycounter = eingabe[0];
monthcounter = eingabe[1];
yearcounter = eingabe[2];
Integer[] einunddreissig = {1,3,5,7,8,10,12}; //months with 31 days
Integer[] dreissig = {4,6,9,11}; // months with 30 days
while (daycounter != eingabe[3] && monthcounter != eingabe[4] && yearcounter != eingabe[5] ) {
// if its a month that has 31 days
if ( Arrays.asList(einunddreissig).contains(monthcounter) ) {
for (int i = daycounter; i <= 31; i++) {
days++;
}
daycounter=1;
monthcounter++;
}
// if its a month with 30 days
if ( Arrays.asList(dreissig).contains(monthcounter) ) {
for (int i = daycounter; i <= 30; i++) {
days++;
daycounter++;
}
daycounter=1;
monthcounter++;
// february
} else if ( monthcounter == 2) {
for (int i = daycounter; i <= 28; i++) {
days++;
}
daycounter=1;
monthcounter++;
} else if (monthcounter==13) {
monthcounter=1;
yearcounter++;
}
}
// checking how many days were counted and comparing the input (eingabe[something]) to how far the daycounter reached
System.out.println(" "+days);
System.out.println(" "+daycounter+" "+monthcounter+" "+yearcounter);
System.out.println(eingabe[3]+" "+eingabe[4]+" "+eingabe[5]);
}
}
I hope there is somebody who might be so kind to give me a hint how to fix that.
I would separate this out into two different functions, one that counts the days until the end of the current year and another which counts the days since the beginning of the current year. Then you can put the total days in terms of those values.
First write a generic sum() function:
public static int sum(int[] a, int start, int end){
int sum = 0;
for(int i = start; i < end; i++) sum += a[i];
return sum;
}
Then use the sum() function to easily compute daysToEnd and daysFromStart:
static int[] daysInMonth = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
public static int daysToEnd(int day, int month){
return sum(daysInMonth, month - 1, 12) - day;
}
public static int daysFromStart(int day, int month){
return sum(daysInMonth, 0, month - 1) + day;
}
public static void main(String... args){
int[] date1 = {23, 1, 1994};
int[] date2 = {1, 1, 1997};
// This actually works for same or different years
int days = daysToEnd(date1[0], date1[1]) +
365*(date2[2] - date1[2] - 1) +
daysFromStart(date2[0], date2[1]);
System.out.println(days);
}
Do you have to use loops? Here's some food for thought -- imagine this as a simple algebra problem. In your program, each date is modeled as a collection of quantities, each of a different unit. Once you obtain uniform units, you can just do the arithmetic.
In the UNIX world we use an agreed-upon reference date called the "epoch", 12:00 AM on 01 January, 1970 as a reference date. Kind of like "tare" on a balance. All other dates can be represented as some number of seconds relative to that time.
I would construct the passed in user input to java.util.Date type. But I am assuming line by line input. You can construct a string using StringBuilder if you want to get day,mth,year separately.
try{
BufferedReader br = new BufferedReader(
new InputStreamReader(System.in));
DateFormat df = new SimpleDateFormat ("dd/MM/yyyy");
System.out.println("Enter Date1");
String dateSt1= br.readLine(); // Accepts date1 as string
System.out.println("Enter Date2");
String dateSt2= br.readLine(); // Accepts date2 as string
Date date1=df.parse(dateSt1); // Date String to Date
Date date2=df.parse(dateSt2);
}catch(IOException ex)
}catch(ParseExceptionOfSomesort pex)
}
then use this to get the difference in days -
int diffInDays = (int)( (date2.getTime() - date1.getTime())
/ (1000 * 60 * 60 * 24) )
If you get this in negative, that means the second date is before first date.
Think: Do I have to do it using a loop or hasn't java already added some utility method to do date compare?
What makes something "complicated" though? Writing too many lines of code or using existing java library?

Chat Bot, last part

Just one last part remaining in the ChatBot. I need to figure out a way to modify the chatbot class so
that it occasionally (say, 30% of the time) returns a randomly-­‐generated standard reply to user input one of at least five possible replies, like “LOL”, “OMG”, “You don’t say”, “Really?”, or “I see”.
Edit: Applied recommended changes:
import java.util.Random;
import java.util.Scanner;
public class ChatBot
{
private int responseCount = 0;
public String getResponse(String value)
{
String X = longestWord(value);
this.responseCount++;
if (responseCount == 10)
{
return "Sorry, but our time is up. I can't talk with you any longer.";
}
if (value.contains("you"))
{
return "I'm not important. Let's talk about you instead.";
}
else if (X.length() <= 3)
{
return "Maybe we should move on. Is there anything else you would like to talk about?";
}
else if (X.length() == 4)
{
return "Tell me more about " + X;
}
else if (X.length() == 5)
{
return "Why do you think " + X + " is important?";
}
else if (X.length() <=9)
{
return "Now we are getting somewhere. How does " + X + " affect you the most?";
}
return getRandomResponse();
}
public String longestWord(String value){
Scanner input = new Scanner (value);
String longest = new String();
longest = "";
while (input.hasNext())
{
String temp = input.next();
if(temp.length() > longest.length())
{
longest = temp;
}
}
return longest;
}
private String getRandomResponse()
{
String [] responses = {"OMG", "LOL", "You don't say", "Really?", "I See"};
return responses [(int)(Math.random() * responses.length)];
}
}
The problem is, it keeps returning the same response, instead of one of the five responses given. Any help would me much appreciated, thank you!
Edit:It's now giving only the random responses, and overriding every other response in the getResponse() method.
Given your logic, your getRandomResponse method should always return "OMG". This is because on the first run of the loop in that method, counter = 1. Thus the first if statement will run and will return "OMG" exitting the method. A nicer equivalent might putting all teh responses into an array and returning a random value from it, rather than doing somehting strange with iteration:
String[] responses = {"OMG", "LOL", "You don't say", "Really?", "I See"};
return responses[(int)(Math.random() * responses.length)];
In getRandomResponse, you make a random number generator using Random(), but you never use it. Then in your for loop, you execute your decision-making tree but use a variable counter that always begins at 0. Then on the first time through your loop, the first if statement will execute because 0 < 5, so "OMG" is returned.
Edit: I just noticed something else that is not going to work in your code:
Random randomNumber = new Random();
for (int counter =0; counter<10; counter++)
{
counter = randomNumber.nextInt();
You're trying to use counter to do two different things: you are trying to run this loop 10 times, but you're also using it to store random values.

Categories