_________________________________________________________________________
You have a digital, 7 led segment, clock. One day, while waking up from a sci-fi dream, you wonder: how many times will the individual leds turn on after X seconds, from a 00:00:00 position?

Yeah, geeks. But as a good geek you will not that question stay on your mind forever, right? ;)
Take into account that every second, all leds turn off and then the ones for the next position will turn on.
Sample input
0 4
Sample output
36 172
TEST
69758793
_________________________________________________________________________
UserInterface Class:
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
/**
* Clase encargada de mantener el bucle de ejecución del programa hasta el fin de linea.
* @author Javier de Pedro López
*/
public class UserInterface {
/**
* Permite mantener el bucle de lecutra.
*/
public void run() throws IOException{
String line;
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
//Bucle que realiza las lecturas hasta que lo recibido sea EOF (null)
do{
line = reader.readLine();
if (line != null && !line.trim().equals("")){
int time = Integer.valueOf(line.trim());
//Creamos el solucionador del problema
Clock clock = new Clock(time);
System.out.println(clock.getChanges());
}
} while(line != null);
}
}
Clock Class:
/**
* Permite encontrar el numero de veces que cambian los leds en un tiempo determinado.
* @author Javier de Pedro López
*/
public class Clock {
private int _time;
private int[] _clock = {0,0,0,0,0,0};
private final int[] ZERO = {0,6};
private final int[] ONE = {1,2};
private final int[] TWO = {2,5};
private final int[] THREE = {3,5};
private final int[] FOUR = {4,4};
private final int[] FIVE = {5,5};
private final int[] SIX = {6,6};
private final int[] SEVEN = {7,3};
private final int[] EIGHT = {8,7};
private final int[] NINE = {9,6};
private int _changes;
/**
* Intancia un nuevo elemento para calcular el tiempo.
* @param time tiempo del que se quieren calcular los cambios.
*/
public Clock (int time){
_time = time;
_changes = 0;
for (int i = 0; i <= time; i++){
_changes += countLeds();
_clock[_clock.length - 1] += 1;
organizeClock();
}
}
/**
* Permite realizar los cambios para que el reloj cambie propiamente.
*/
private void organizeClock(){
boolean isChanged = true;
int i = _clock.length - 1;
while (isChanged){
if (i % 2 != 0){
if (_clock[i] % 10 == 0 && _clock[i] != 0){
_clock[i] = 0;
_clock[i-1] += 1;
}else{
isChanged = false;
}
}else{
if (i != 0)
if (_clock[i] % 6 == 0 && _clock[i] != 0){
_clock[i] = 0;
_clock[i-1] += 1;
}else{
isChanged = false;
}
else{
restartClock();
isChanged = false;
}
}
i--;
}
}
/**
* Cuenta el numero de leds encendidos.
* @return el numero de leds.
*/
private int countLeds(){
int numLeds = 0;
for (int i = 0; i < _clock.length; i++){
numLeds += lightUp(_clock[i]);
}
return numLeds;
}
/**
* Compara un numero con los leds para saber cuantos se encienden con dicho numero.
* @param number que queremos encender con leds.
* @return el numero de leds necesarios para encender ese numero.
*/
private int lightUp(int number){
if (number == ZERO[0]){
return ZERO[1];
}else if (number == ONE[0]){
return ONE[1];
}else if (number == TWO[0]) {
return TWO[1];
}else if (number == THREE[0]){
return THREE[1];
}else if (number == FOUR[0]){
return FOUR[1];
}else if (number == FIVE[0]){
return FIVE[1];
}else if (number == SIX[0]){
return SIX[1];
}else if (number == SEVEN[0]){
return SEVEN[1];
}else if (number == EIGHT[0]){
return EIGHT[1];
}else if (number == NINE[0]){
return NINE[1];
} else return 0;
}
/**
* Permite volver a iniciar el reloj.
*/
private void restartClock(){
for (int i = 0; i < _clock.length; i++){
_clock[i] = 0;
}
}
/**
* Permite obtener el numero de cambios.
* @return el numero de cambios.
*/
public int getChanges(){
return _changes;
}
}
Hola Javier. Quería aclarar que me equivoqué al decir que el orden de mi algoritmo es 6 veces más rápido. Es igual al tuyo. Acabo de darme cuenta. Lo siento.
Nada hombre, todos nos confundimos alguna vez!! ;) Te agradezco mucho que le eches un ojo a mi manera de escribir código, que siempre cada uno piensa que la suya es la buena y hasta que no te lo dicen no te das cuenta de que no! =)
Hola Javier. Aquí sí que hay mucha tela que cortar :s
Antes que nada, mi intención es darte mis observaciones sobre tus soluciones, resaltando lo que me guste y comentando las cosas con las que no estoy de acuerdo. Si en algún momento me paso de la raya, me avisas. Disculpa si ocurre. Hay buena intención aunque pueda ser odioso a veces.
Ahora sí. Los nueve arreglos de dos enteros y el método lightUp() están de más. Podías agrupar todos esos datos con un solo arreglo [6,2,5,5,4,5,6,3,7,6]. Fíjate que la posición de cada número es el dígito del reloj.
Sobre organizeClock(). Supón que ya vas por las 09:59:59. Luego de algunas iteraciones tendrás
i=1
10:00:00
pero luego
i=0
restartClock()
00:00:00
Con lo cual, cualquier cantidad de segundos pasadas las 10 de la mañana, la tendrás mal. Los casos de prueba llegaban hasta las 8am apróximadamente. Esos los das correctamente.
Por último, el algoritmo en general lo tienes de orden O(6N) (puede que aún no sepas qué es orden, no importa) pero lo que sí es cierto es que se puede repensar para escribirlo O(N), es decir, 6 veces más rápido.
Apenas he publicado tres de mis respuestas, pues como las explico tardo algo mientras encuentro el tiempo para hacerlo. Cuando publique la sexta, échale un vistazo. Tenemos en común que yo voy segundo a segundo y que también tengo un arreglo con los leds de cada número.
Nada más lejos, toda crítica, si es constructiva, por mí perfecta! =)
En cuanto a la metedura de pata de las 10 de la mañana… digamos que es un error muy muy gordo, simplemente se me paso poner la ultima condicionde que puera como maximo 2 =) lo modifico ahora!
Y si si conozco lo de los órdenes! este año tuve una asignatura sobre algoritmia! pero bueno, este concurso lo hice para probarme y para divertirme, realmente no pensé en optimizar los algoritmos sino en resolver el problema y conseguir que mi código fuera lo más legible posible! pero está bien saber que se puede!
Cuando tengas la 6 le hecharé un vistazo muy gustósamente!
Un saludo!
(EDIT: ya está modificado lo del reloj!)