En el ejercicio Best Before Spotify nos propone resolver un problema de fechas. Como bien sabemos, según el formato, una tupla de números puede representar varias fechas válidas. Dada una tupla nos piden encontrar, por combinaciones, la menor fecha correcta posible. Consejo: lee detenidamente el enunciado. Hay varias limitaciones sobre cómo pueden aparecer los datos (esto es, con diferencia, lo que me entretuvo mas tiempo a la hora de llegar a la solución correcta). A continuación os detallo el código Java que lo resuelve. He intentado que sea lo mas legible y hacer uso de tipos de fecha, que me parecía lo mas elegante (el código puede verse con mayor claridad en el siguiente enlace):
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import java.util.Date; | |
import java.util.Scanner; | |
import java.util.LinkedList; | |
import java.util.Iterator; | |
import java.text.SimpleDateFormat; | |
public class BestBefore { | |
//Verify if it is a leap year | |
public static boolean isaleapyear (int year) { | |
boolean result=false; | |
if ((year%4==0)&&((year%100!=0)||(year%400==0))) { result=true; } | |
return result; | |
} | |
//Verify is generated date could be a valid date | |
public static boolean correctDate(String s_year, String s_month, String s_day) { | |
int year=Integer.parseInt(s_year),month=Integer.parseInt(s_month),day=Integer.parseInt(s_day); | |
int[] monthDays={0,31,28,31,30,31,30,31,31,30,31,30,31}; | |
boolean result=true; | |
if (isaleapyear(year)) { monthDays[2]=29; } | |
if ((month<=0)||(month>12)) { | |
result=false; | |
} else { | |
if ((day<=0)||(day>monthDays[month])) { result=false; } | |
} | |
return result; | |
} | |
//Transform input year in a four digit year | |
public static String extendedYear (String s_year) { | |
int year=0; | |
year=Integer.parseInt(s_year); | |
if (year<2000) { year=year+2000; } | |
return String.valueOf(year); | |
} | |
//Verify input string is correctly formated | |
public static boolean inputStringisCorrect(String line) { | |
int k=0,x=0,y=0,fourDigitYear=0; | |
String n_line; | |
boolean result=true; | |
n_line = new String(line.replaceAll("/", "")); | |
if ((n_line.length()+2)!=line.length()) { | |
result=false; | |
} else { | |
String[] number = line.split("/"); | |
for (int i=0;i<3;i++) { | |
if (number[i].length()==4) { fourDigitYear++; k=i; } | |
} | |
if (fourDigitYear>1){ | |
result=false; | |
} else { | |
if (fourDigitYear==1) { | |
switch(k) { | |
case 0: x=1; y=2; break; | |
case 1: x=0; y=2; break; | |
case 2: x=0; y=1; break; | |
} | |
if ((Integer.parseInt(number[k])<2000)||(Integer.parseInt(number[k])>2999)) { result=false; } | |
if ((number[x].length()<1)||(number[x].length()>2)) { result=false; } | |
if ((number[y].length()<1)||(number[y].length()>2)) { result=false; } | |
} else { | |
for (int i=0; i<3; i++) { | |
if ((number[i].length()<1)||(number[i].length()>2)) { result=false; } | |
} | |
} | |
} | |
} | |
return result; | |
} | |
//Main | |
public static void main(String[] args) { | |
try { | |
long value=0; | |
boolean anyDate=false; | |
int val1=0,val2=0,val3=0; | |
Date currentDate; | |
Date resultDate = new Date(); | |
LinkedList<Date> listofDates = new LinkedList<Date>(); | |
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd"); | |
//Read initial date from the standard system input | |
Scanner sca = new Scanner(System.in); | |
String line = sca.nextLine(); | |
//Verify input string is correct | |
if (inputStringisCorrect(line)) { | |
String[] number = line.split("/"); | |
//In each iteration we change the position of array elements to generate all possible date combinations (up to six) | |
for (int i=0;i<6;i++) { | |
switch (i) { | |
case 0: val1=0;val2=1;val3=2; break; | |
case 1: val1=0;val2=2;val3=1; break; | |
case 2: val1=1;val2=0;val3=2; break; | |
case 3: val1=1;val2=2;val3=0; break; | |
case 4: val1=2;val2=0;val3=1; break; | |
case 5: val1=2;val2=1;val3=0; break; | |
} | |
if (correctDate(extendedYear(number[val1]), number[val2], number[val3])) { | |
currentDate=dateFormat.parse(extendedYear(number[val1])+"/"+number[val2]+"/"+number[val3]); | |
if (currentDate.getTime()>=value) { value=currentDate.getTime(); } | |
listofDates.add(currentDate); | |
} | |
} | |
//Now, we got a list of valid dates. We're going to search on it to find the earliest one | |
Iterator<Date> iterator = listofDates.iterator(); | |
while(iterator.hasNext()) | |
{ | |
currentDate = (Date) iterator.next(); | |
if (currentDate.getTime()<=value) { | |
anyDate=true; | |
value=currentDate.getTime(); | |
resultDate = currentDate; | |
} | |
} | |
//Finally, if there is any valid date, we show it in the required output format | |
if (anyDate) { | |
java.text.SimpleDateFormat sdf=new java.text.SimpleDateFormat("yyyy-MM-dd"); | |
System.out.println(sdf.format(resultDate)); | |
} else { | |
System.out.println(line+" is illegal"); | |
} | |
} else { | |
//Input string is incorrect so we write an illegal message on standard output | |
System.out.println(line+" is illegal"); | |
} | |
}catch (Exception e){ | |
System.err.println("Error: " + e.getMessage()); | |
} | |
} | |
} |
No hay comentarios:
Publicar un comentario