Artículos Técnicos

Artículos Tecnicos y Procedimientos (creado por Pablo Saitta - pablo.saitta@gmail.com)

viernes, septiembre 28, 2007

Dia de cumpleaños

Mi profesora de Algoritmos y Estructura de Datos nos dio un trabajo practico interesante, desarrollar un programa que dandole el dia, el mes y el año de nacimiento nos proporcionara el día en que nacimos.
Buscando en Internet el dato que me proporcionara alguna periodicidad en el almanaque me encontre con un matemático Ingles de nombre John Conway que inventó un algoritmo de calculo mental aplicando una peridicidad del calendario denominada Doomsday o día maldito, este día maldito es el mismo los 4/4 6/6 8/8 10/10 y 12/12. En Enero depende del año bisiesto siendo el 3/1 los años normales y 4/1 los bisiestos. Este doomsday es el último día de Febrero, o sea el 28 en años normales y 29 en año bisiesto. Para marzo es siempre el día 7 y para los otros meses usamos la regla memotecnica "trabajo de 9 a 5 los 11 a 7" o sea, el doomsday cae el 9/5, 5/9, 7/11 y 11/7.
La fórmula del día maldito depende de un marcador de siglo que es de una periodicidad de una centuria arrancando en el 1900 hasta 1999 y desde el 2000 hasta el 2099. Siendo estos marcadores en el siglo 20 el día míercoles y en el siglo 21 el día Martes.
Aplicando este algoritmo mental lo transformé en un chapin generando mi propio algoritmo de calculo y generé luego el siguiente programa en Pascal que espero sea de su provecho:

program doomsday(input,output);
var ano, mes, dia, bis, dooms, R :integer;
procedure vali1(var B :integer; dia :integer);
begin
IF (dia>31) and (dia < 1) then B:=1
else B:=0
end;
procedure vali2(var B :integer; dia :integer);
begin
if (dia > 31) and (dia < 1) then B:=1
else B:=0
end;
procedure valif(var B :integer; dia :integer; bis :integer);
begin
if bis = 1 then
begin
if (dia > 29 ) and (dia < 1) then B:=1
else B:=0
end
else
begin
if (dia > 28) and (dia < 1) then B:=1
else B:=0
end
end;
procedure validadi(var B:integer; dia :integer; bis :integer; mes :integer);
begin
case mes of
1: vali1(B,dia);
2: valif(B,dia,bis);
3: vali1(B,dia);
4: vali2(B,dia);
5: vali1(B,dia);
6: vali2(B,dia);
7: vali1(B,dia);
8: vali1(B,dia);
9: vali2(B,dia);
10: vali1(B,dia);
11: vali2(B,dia);
12: vali1(B,dia);
end
end;
procedure carga(var ano :integer; var mes :integer; var dia :integer; var bis :integer);
var B :integer;
begin
writeln('Ingrese al año de nacimiento: ');
readln(ano);
if (ano mod 4)=0 then bis:=1
else bis:=0;
writeln('Ingrese el mes de nacimiento: ');
repeat
readln(mes)
until (mes>=1) and (mes<=12);
writeln('Ingrese el día de nacimiento: ');
repeat
readln(dia);
validadi(B,dia,bis,mes)
until B=0
end;
procedure doomsday(ano :integer; var dooms :integer);
var Y :integer;
begin
if ano>=2000 then
begin
Y:= ano - 2000;
dooms:= ((Y div 12) + Y mod 12 + (( Y mod 12) div 4) mod 7)+2
end
else
begin
Y:= ano - 1900;
dooms:= ((Y div 12) + Y mod 12 + (( Y mod 12) div 4 ) mod 7)+ 3
end;
if dooms >= 29 then dooms := dooms - 28
else if dooms >= 22 then dooms:=dooms-21
else if dooms >= 15 then dooms := dooms -14
else if dooms >= 8 then dooms := dooms - 7
end;
procedure moddia( dia :integer; var D :integer);
begin
if dia >= 29 then D:=dia-28
else if dia >=22 then D:=dia-21
else if dia>=15 then D:=dia-14
else if dia>=8 then D:=dia-7
end;
procedure res1(bis :integer; dia :integer; dooms :integer; var R :integer);
var D :integer;
begin
moddia(dia,D);
if bis = 1 then if D>=4 then R:=(D-4)+dooms
else R:=(4-D)+dooms
else if D>=3 then R:=(D-3)+dooms
else R:=(3-D)+dooms
end;
procedure res2(bis :integer; dia :integer; dooms :integer; var R:integer);
var D :integer;
begin
moddia(dia,D);
if bis = 1 then R:=(D-1)+dooms
else if D>=7 then R:=(D-7)+dooms
else R:=(7-D)+dooms
end;
procedure res3(dia :integer; dooms :integer; var R:integer);
var D :integer;
begin
moddia(dia,D);
if D>=7 then R:=(D-7)+dooms
else R:=(7-D)+dooms
end;
procedure res4(dia :integer; dooms :integer; var R:integer);
var D :integer;
begin
moddia(dia,D);
if D>=4 then R:=(D-4)+dooms
else R:=(4-D)+dooms
end;
procedure res5(dia :integer; dooms :integer; var R :integer);
var D :integer;
begin
moddia(dia,D);
if D>=2 then R:=(D-2)+dooms
else R:=(2-D)+dooms
end;
procedure res6(dia :integer; dooms :integer; var R :integer);
var D :integer;
begin
moddia(dia,D);
if D>=6 then R:=(D-6)+dooms
else R:=(6-D)+dooms
end;
procedure res7(dia :integer; dooms :integer; var R :integer);
var D :integer;
begin
moddia(dia,D);
if D>=4 then R:=(D-4)+dooms
else R:=(4-D)+dooms
end;
procedure res8(dia :integer; dooms :integer; var R :integer);
var D :integer;
begin
moddia(dia,D);
R:=(D-1)+dooms
end;
procedure res9(dia :integer; dooms :integer; var R :integer);
var D :integer;
begin
moddia(dia,D);
if D>=5 then R:=(D-5)+dooms
else R:=(5-D)+dooms
end;
procedure res10(dia :integer; dooms :integer; var R :integer);
var D :integer;
begin
moddia(dia,D);
if D>=3 then R:=(D-3)+dooms
else R:=(3-D)+dooms
end;
procedure res11(dia :integer; dooms :integer; var R :integer);
var D :integer;
begin
moddia(dia,D);
if D>=2 then R:=(D-2)+dooms
else R:=(2-D)+dooms
end;
procedure res12(dia :integer; dooms :integer; var R :integer);
var D :integer;
begin
moddia(dia,D);
if D>=5 then R:=(D-5)+dooms
else R:=(5-D)+dooms
end;
procedure resgen (bis :integer; mes :integer;dia :integer; dooms :integer; var R :integer);
begin
case mes of 1: res1(bis,dia,dooms,R);
2: res2(bis,dia,dooms,R);
3: res3(dia,dooms,R);
4: res4(dia,dooms,R);
5: res5(dia,dooms,R);
6: res6(dia,dooms,R);
7: res7(dia,dooms,R);
8: res8(dia,dooms,R);
9: res8(dia,dooms,R);
10: res10(dia,dooms,R);
11: res11(dia,dooms,R);
12: res12(dia,dooms,R);
end
end;
procedure muestra(R :integer);
begin
if (R>=8) and (R<=14) then R:=R-7;
case R of 1 : writeln('El dia de nacimiento es Lunes');
2 : writeln('El dia de nacimiento es Martes');
3 : writeln('El dia de nacimiento es Miercoles');
4 : writeln('El dia de nacimiento es Jueves');
5 : writeln('El dia de nacimiento es Viernes');
6 : writeln('El dia de nacimiento es Sabado');
7 : writeln('El dia de nacimiento es Domingo')
end
end;
begin
carga(ano,mes,dia,bis);
doomsday(ano,dooms);
resgen(bis,mes,dia,dooms,R);
muestra(R)
end.