2011-09-11 14 views
5

Estoy tratando de resolver el acertijo de Spotify "mejor antes" descrito en este page. Básicamente, con una entrada de tres enteros separados por barras diagonales (por ejemplo, 11/3/4) se supone que debe generar un resultado con la fecha más temprana posible en el formato 2011-03-04. Si no hay fecha posible, debe devolver la cadena original seguida de "es ilegal".Problema de acertijo de Spotify

La idea de mi solución a continuación fue tomada de una solución de Python que encontré para el mismo problema en github. Cuando envío este código de Python, es aceptado. Al no estar familiarizado con Python, este es mi mejor intento de hacer algo similar con Java, y sin usar ninguna función de calendario como se puede ver en la solución this publicada aquí en stackoverflow.

Cuando presento mi solución, sin embargo, recibo "Respuesta incorrecta" como respuesta. Por más que lo intente, no puedo encontrar ningún error con este código. Siento que he probado todas las combinaciones posibles de entradas, y todas mis salidas salen correctamente. ¿Alguien tiene alguna idea de lo que me podría estar perdiendo?

Como soy relativamente nuevo en la programación en general, no dude en dar consejos sobre cómo se puede mejorar el código en general si lo desea. Estoy seguro de que podría parecer noobish. ¡Gracias!

import java.io.BufferedReader; 
import java.io.IOException; 
import java.io.InputStreamReader; 
import java.util.Arrays; 

public class DateProggy3 { 

    static int var1, var2, var3; 
    static int slashPosition1, slashPosition2; 
    static String yearString, monthString, dayString; 

    public static void main(String[] args) throws IOException { 
     String dateInput = readDate(); 
     splitInputToInts(dateInput); 
     Integer[] dateArray = {var1, var2, var3}; 
     Arrays.sort(dateArray); 
     Integer bestDate[] = getBestDate(dateArray, dateInput); 
     convertDate(bestDate); 
     printDate(bestDate); 
    } 

    public static String readDate() throws IOException { 
     BufferedReader stdin = new BufferedReader 
      (new InputStreamReader(System.in)); 
     String dateInput; 
     dateInput = stdin.readLine(); 
     return dateInput; 
    } 

    public static void splitInputToInts(String dateInput) { 
     try { 
     slashPosition1 = dateInput.indexOf('/'); 
     slashPosition2 = dateInput.lastIndexOf('/'); 
     var1 = Integer.parseInt(dateInput.substring(0, slashPosition1)); 
     var2 = Integer.parseInt(dateInput.substring(slashPosition1+1, slashPosition2)); 
     var3 = Integer.parseInt(dateInput.substring(slashPosition2+1, dateInput.length())); 
     }catch (StringIndexOutOfBoundsException e){ 
      illegal(dateInput); 
     }catch (NumberFormatException e){ 
      illegal(dateInput); 
     } 
    } 

    public static void illegal(String dateInput){ 
     System.out.println(dateInput + " is illegal"); 
     System.exit(0); 
    } 

    public static Integer[] getBestDate(Integer[] dateArray, String dateInput){ 
     var1 = dateArray[0]; 
     var2 = dateArray[1]; 
     var3 = dateArray[2]; 
     if (testDate(var1, var2, var3)){ 
      Integer[] bestDate = {var1, var2, var3}; 
      return bestDate; 
     } 
     else if (testDate(var1, var3, var2)){ 
      Integer[] bestDate = {var1, var3, var2}; 
      return bestDate; 
     } 
     else if (testDate(var2, var1, var3)){ 
      Integer[] bestDate = {var2, var1, var3}; 
      return bestDate; 
     } 
     else if (testDate(var2, var3, var1)){ 
      Integer[] bestDate = {var2, var3, var1}; 
      return bestDate; 
     } 
     else if (testDate(var3, var1, var2)){ 
      Integer[] bestDate = {var3, var1, var2}; 
      return bestDate; 
     } 
     else if (testDate(var3, var2, var1)){ 
      Integer[] bestDate = {var3, var2, var1}; 
      return bestDate; 
     }else{ 
      illegal(dateInput); 
     } 
     Integer[] bestDate = {var1, var2, var3}; 
     return bestDate; 
    } 

    public static boolean testDate(int year, int month, int day){ 
     boolean leapYear = false; 
     boolean dateOK; 
     if (year > 100 && year < 2000){ 
      return dateOK = false; 
     } 
     if (year < 1000){ 
      year+=2000; 
     } 
     if (year < 0){ 
      return dateOK = false; 
     } 
     if (year % 4 == 0) { 
      if (year % 100 == 0 && year % 400 != 0) { 
       leapYear = false; 
      } 
      leapYear = true; 
     }else{ 
      leapYear = false; 
     } 
     if (month > 12 || month < 1){ 
      return dateOK = false; 
     } 
     switch (month){ 
      case 1: 
      case 3: 
      case 5: 
      case 7: 
      case 8: 
      case 10: 
      case 12: 
       if (day > 31 || day < 1){ 
        return dateOK = false; 
       } 
       break; 
      case 4: 
      case 6: 
      case 9: 
      case 11: 
       if (day > 30 || day < 1){ 
        return dateOK = false; 
       } 
       break; 
      case 2: 
       int maxDay; 
       if (leapYear){ 
        maxDay = 29; 
       }else{ 
        maxDay = 28; 
       } 
       if (day > maxDay || day < 1){ 
        return dateOK = false; 
       } 
     } 
     return dateOK = true; 
    } 


    public static void convertDate(Integer[] dateArray){ 
     if (dateArray[0] < 1000){ 
      dateArray[0]+=2000; 
     } 
     yearString = String.valueOf(dateArray[0]); 
     if (dateArray[1] < 10){ 
      monthString = "0" + dateArray[1]; 
     }else{ 
      monthString = String.valueOf(dateArray[1]); 
     } 
     if (dateArray[2] < 10){ 
      dayString = "0" + dateArray[2]; 
     }else{ 
      dayString = String.valueOf(dateArray[2]); 
     } 
    } 

    public static void printDate(Integer[] dateArray){ 
     System.out.println(yearString + "-" + monthString +"-" + dayString); 
    } 
} 

soy yo el que hizo la pregunta, pero parece que no puede comentar y responder normalmente a las respuestas más ya que me inscribí a stackoverflow y perdido mis galletas originales o algo así.

De todos modos, gracias palacsint por su respuesta. Solucioné el problema del año bisiesto y ahora mi respuesta finalmente fue aceptada.

Una pregunta sobre las últimas dos líneas en el método getBestDate(). Los puse allí simplemente porque Eclipse IDE me da el error "Este método debe devolver un resultado de tipo Integer []". No parece satisfecho con tener todas las devoluciones en los corchetes if. ¿Hay alguna forma de evitar esto? Gracias.

Respuesta

1

Un error: acepta 2100/02/29. 2100 es no un año bisiesto, por lo que no hay 2011/02/29.

Si yo fuera usted, usaría SimpleDateFormat para analizar y validar (sugerencia: lenient análisis). Es mucho más simple, mucho más intuitivo y el código sería más fácil de leer. (No reinventar la rueda)

Algunas otras ideas anteriores.

Asignaciones innecesarias: return dateOK = false;

Sólo regresan con false:

return false; 

(La variable dataOK es innecesario en su caso.)

public static void illegal(String dateInput){ 
    System.out.println(dateInput + " is illegal"); 
    System.exit(0); 
} 

excepciones Throw en lugar de System.exit().

En el método getBestDate() las dos últimas líneas nunca se ejecutan. Son código muerto (ya illegal() llamadas System.exit()):

}else{ 
    illegal(dateInput); 
} 

Integer[] bestDate = {var1, var2, var3}; 
return bestDate; 

Si Es métodos y campos estáticos posible evitar. Por último, es un buen problema aprender cómo escribir pruebas unitarias.

0

Existen problemas en el manejo de su "año". El texto de puzzle dice

dado una fecha posiblemente ambigua "A/B/C", donde A, B, C son números enteros entre 0 y 2999, la producción de la fecha legal lo antes posible entre Ene 1, 2000 y 31 de diciembre de 2999 (inclusive) usándolos como día, mes y año (pero no necesariamente en ese orden).

Sin embargo, cuando ingreso años entre 1000 y 2000 en su programa, los informará textualmente, aunque no sean válidos.

+1

Supongo que esto no debería ser un problema ya que el problema dice "Puede suponer que el año, cuando se da con cuatro dígitos, es entre 2000 y 2999". y "Dada una fecha posiblemente ambigua 'A/B/C', donde A, B, C son números enteros entre 0 y 2999". Sin embargo, intenté reparar esto añadiendo una línea "if (year> 100 && year <2000)" como se puede ver en el código actualizado. Aún así recibo respuestas de "respuesta incorrecta". ¡Gracias! – mattboy

Cuestiones relacionadas