このパズルのために、次のコードを書きました。すべてのケースをカバーすると思われるテスト入力のリストを作成し、コードはそれらすべてに合格しました。しかし、ボットは私の答えを受け入れません。FSM の愛のために、今夜眠れるようにこれを締めくくる必要があります。私のコードが失敗するテストケースを誰かが提案できますか?
メインクラス:
package bestBefore;
import java.text.SimpleDateFormat;
import java.text.DateFormat;
import java.util.List;
import java.util.ArrayList;
import java.util.Date;
import java.util.Calendar;
import java.util.GregorianCalendar;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
public class BestBefore {
private String d_inputDate;
private List<Date> d_validDateList ;
private static String s_dateFormat = "yyyy-MM-dd";
private static DateFormat s_df ;
private static Calendar s_upperBoundary ;
private static Calendar s_lowerBoundary ;
static {
s_df = new SimpleDateFormat(s_dateFormat);
s_df.setLenient(false);
s_upperBoundary = new GregorianCalendar();
s_upperBoundary.clear();
s_upperBoundary.set(3000,Calendar.JANUARY,1);
s_lowerBoundary = new GregorianCalendar();
s_lowerBoundary.clear();
s_lowerBoundary.set(1999,Calendar.DECEMBER,31);
}
public static void main ( String[] args ) {
String inputDate = "";;
if ( args.length == 0 ){
//sop("Usage: java BestBefore <input_date>");
try {
BufferedReader stdin = new BufferedReader(new InputStreamReader(System.in));
inputDate = stdin.readLine();
}catch (IOException ioe) {
sop(ioe.getMessage());
}
}else{
inputDate = args[0];
}
BestBefore bb = new BestBefore(inputDate);
sop(bb.getEarliestDate());
}
public BestBefore ( String inputDate ) {
d_inputDate = inputDate;
d_validDateList = new ArrayList<Date> ();
processDate();
}
private void processDate() {
if ( d_inputDate == null)
return;
String[] dates = d_inputDate.split("/");
int[] datesInt = new int[3]; // to store the parseInts
if( dates.length !=3 ) {
return;
}
int yearInd = -1;
try {
// check if any 4 digits , then that is the year and also integer parse
for ( int i = 0 ; i < dates.length ; i ++ ) {
if(dates[i].length() == 3)
return;
//Covnert to int
datesInt[i] = Integer.parseInt(dates[i].trim());
if (datesInt[i] > 31){ // if number greater than 31 then year : TODO check month too and avoid looops
if ( yearInd == -1) {
yearInd = i;
}
else{
return;
}
}
// Check for negative numbers
if ( datesInt[i] < 0 ) {
return;
}
}
//ProcesDates
if ( yearInd != -1 ) // we have a year / cuts down number of date parses by factor of 3
haveYear(datesInt,yearInd);
else
noYear(datesInt);
}catch (Exception e ) { // not a number
return;
}
}
private void haveYear(int[] dates, int yearInd ) {
String dateToParse = padYear(dates[yearInd]+"") + "-";
int[] mD = new int[2];
for ( int i = 0,j = 0 ; i < dates.length ; i ++ ) {
if ( i == yearInd )
continue;
mD[j] = dates[i] ;
j++;
}
// parse date and rotate and repeat
for ( int i = 0 ; i < mD.length ; i ++ ) {
try {
Date date = s_df.parse( dateToParse+mD[0]+"-"+mD[1] );
if ( (s_lowerBoundary.getTime()).before(date) && (s_upperBoundary.getTime().after(date)))
d_validDateList.add(date );
}catch ( Exception e ) {
// Not a valid date
continue;
}finally {
mD = rotate(mD);
}
}
}
private void noYear(int[] dates){
// parse and repeat
for ( int i = 0 ; i < dates.length ; i ++ ) {
haveYear( dates, i );
}
}
public String getEarliestDate( ) {
try{
Date earliestDate = null;
if (d_validDateList.size() == 0) {
return d_inputDate+" is illegal";
}
// get the earliest date
for ( Date dt : d_validDateList ) {
if ( earliestDate == null ) {
earliestDate = dt;
continue;
}
if ( dt.before(earliestDate) )
earliestDate = dt ;
}
return (s_df.format(earliestDate)) ;
}
catch(Exception e ){
return d_inputDate+" is illegal";
}
}
//
// Static utility methods follow
//
private static void sop ( String message ) {
System.out.println(message);
}
private static int[] rotate(int[] a){
if (a.length ==0 )
return a;
int firstElement = a[0];
for ( int i = 0 ; i < a.length-1 ; i ++ ) {
a[i]= a[i+1];
}
a[a.length-1] = firstElement;
return a;
}
private static String padYear(String s ){
if ( s.length() > 3)
return s;
String frt = (String.format("2%1$#3s", s)).replace(" ","0");
return ( frt) ;
}
// Invalid Date Exception Class
}
テスト クラス:
package bestBefore;
public class BestBeforeTest {
private static String[] dta = {"01/01/01",
"999/12/31",
"12/12/12",
"0/0/0",
"4/1/5",
"999/12/12",
"10/11/12",
"qwe/1/1",
"-1/10/10",
"1000/1/1",
"2100/2/29",
"31/11/76",
"2400/2/29",
"2404/2/29",
"2401/2/29",
"",
"1/1/",
"000000000000/ /",
"1/1/1.0",
"1/1/1",
"1/2/3",
"30/5/09",
"26/12/12",
"36/12/12",
"0\3\33",
"1.1/3.0/3",
"999/31/12",
"1/1/000",
"02/4/67",
"",
"unknown",
"2012-10-10",
"20121010",
"2012/10/10/",
"2012/10/10" ,
"2012/1/10",
"2012/10/1", "12/10/10", "2/10/10",
"2/10",
"2",
"31/12/2999",
"1/1/3000"
};
public static void main ( String[] args){
for ( int i = 0; i < dta.length ; i ++ ) {
BestBefore bb = new BestBefore(dta[i]);
System.out.println(bb.getEarliestDate());
}
}
}
試験結果:
2001-01-01
999/12/31 is illegal
2012-12-12
0/0/0 is illegal
2001-04-05
999/12/12 is illegal
2010-11-12
qwe/1/1 is illegal
-1/10/10 is illegal
1000/1/1 is illegal
2100/2/29 is illegal
31/11/76 is illegal
2400-02-29
2404-02-29
2401/2/29 is illegal
is illegal
1/1/ is illegal
000000000000/ / is illegal
1/1/1.0 is illegal
2001-01-01
2001-02-03
2005-09-30
2012-12-26
2036-12-12
0 is illegal
1.1/3.0/3 is illegal
999/31/12 is illegal
1/1/000 is illegal
2/10 is illegal
2067-02-04
is illegal
unknown is illegal
2012-10-10 is illegal
20121010 is illegal
2012-10-10
2012-10-10
2012-01-10
2012-01-10
2010-10-12
2002-10-10
2/10 is illegal
2 is illegal
2999-12-31
1/1/3000 is illegal
null is illegal
皆さんありがとう。テストケースを考え出す上で、これは良い学習体験になると思います。