PDA

Ver la Versión Completa : Calcular Año (condición cíclica)


MaMu
31-07-2007, 17:50:11
Resulta que tengo un orden de equivalencias entre una Letra y su correspondiente Año, el cual se va repitiendo a lo largo de la historia.
Empieza con la letra K en el años 2000.


K=2000
L=2001
M=2002
N=2003
P=2004
R=2005
S=2006
T=2007
V=2008
X=2009
Z=2010
A=2011
B=2012
C=2013
D=2014
E=2015
F=2016
H=2017
J=2018

//y asi suscesivamente...

K=2019
L=2020
... etc.


Pero no se me ocurre como hacer, para que introciendo una variable "año", me devuelva la Letra del año que correspode, segun el orden cíclico establecido


anio:='2007';
//anio:='1995';
//anio:= ..... etc
QueAnio:=LetraAnio(anio);


Realmente no se me ocurre que hacer.

Saludos y Gracias

Delphius
31-07-2007, 19:05:11
La condición cíclica se puede conseguir con Mod.

1 mod 100 = 1
2 mod 100 = 2
...
99 mod 100 = 99
100 mod 100 = 0
101 mod 100 = 1
102 mod 100 = 2
....
200 mod 100 = 0
...

Con unos pequeños ajustes se puede conseguir el efecto que tu buscas.
Saludos,

emilioeduardob
31-07-2007, 19:10:00
y depende man...
Si es solo hasta la Z o sino seria un poquitin mas complejo.
Yo haria algo asi. Claro esto solo funcionaria hasta la Z.
Código Delphi

function AnoToLetra(Anho: integer): string;
begin
result := Char(Anho - 1925);
end;

MaMu
31-07-2007, 19:16:07
y depende man...
Si es solo hasta la Z o sino seria un poquitin mas complejo.
Yo haria algo asi. Claro esto solo funcionaria hasta la Z.
Código Delphi

Código Delphi [-] (http://www.clubdelphi.com/foros/#)
function AnoToLetra(Anho: integer): string;
begin
result := Char(Anho - 1925);
end;




Pense en lo que decis, pero las letras no van de la A..Z, es decir, hay letras que no se usan en el ciclo, la "U" por ejemplo.

MaMu
31-07-2007, 19:17:18
La condición cíclica se puede conseguir con Mod.

1 mod 100 = 1
2 mod 100 = 2
...
99 mod 100 = 99
100 mod 100 = 0
101 mod 100 = 1
102 mod 100 = 2
....
200 mod 100 = 0
...

Con unos pequeños ajustes se puede conseguir el efecto que tu buscas.
Saludos,

Esta buena la idea, pero esto seria para un Ciclo con una serie de 100. Yo solo utilizo 19 letras, lo que me lo complica bastante.

Delphius
31-07-2007, 19:23:30
No la he probado... yo me estoy imaginando algo como esto:


EDITO:


function TForm1.AnnoALetra(Anno: integer): string;
const
LETRAS = 'KLMNPRSTVXZABCDEFHJ';
var dif: integer;
begin
dif := Anno mod 2000; //2000 es el primer año a contabilizar
id Dif = 0
then Dif = 1;
result := LETRAS[(dif div Length(LETRAS))];
end;


Ahora si debería andar.
Saludos,

MaMu
31-07-2007, 19:36:02
No la he probado... yo me estoy imaginando algo como esto:


Código Delphi [-] (http://www.clubdelphi.com/foros/#)
function TForm1.AnnoALetra(Anno: integer): string;
const
LETRAS = 'KLMNPRSTVXZABCDEFHJ';
var dif: integer;
begin
dif := Anno mod 2000; //2000 es el primer año a contabilizar
result := LETRAS[dif + 1];
end;





No lo he probado totalmente... habría que ver...
Saludos,

Está muy bien, retocando la sugerencia me quedo casi igual, ahora bien, que pasa si intento averiguar a que letra corresponde el año 1994, estoy en problemas porque defini que el ciclo arranque del 2000. Inicié del 2000 porque seria lo mas actual del ciclo, pero deberia arrancar de 1950. Y al llegar al tope maximo, volver a empezar. En este caso el año 2018 es la J, pero el 2019 deberia ser la K nuevamente y asi suscesivamente.

Delphius
31-07-2007, 19:40:54
Si es como dices, que debe computarse dese una fecha más temprana puedes modificarla.

Estoy viendo porqué algo no me está andando el código... me parece raro.:confused: No logro ver donde estoy metiendo mal la pata.
Saludos,

Delphius
31-07-2007, 19:45:53
Bueno, creo que ahora si podría andar. Al menos, la he probado y está funcionando. Se pueden hacer algunas comprobaciones extras, pero creo que la idea está:

function TForm1.AnnoALetra(Anno, AnnoIni: integer): string;
const
LETRAS = 'KLMNPRSTVXZABCDEFHJ';
var dif: integer;
begin
dif := Anno mod AnnoIni; //AnnoIni es el primer año a computar
dif := dif mod Length(LETRAS);
result := LETRAS[dif+1];
end;

Saludos,

MaMu
31-07-2007, 19:46:03
Si es como dices, que debe computarse dese una fecha más temprana puedes modificarla.

Estoy viendo porqué algo no me está andando el código... me parece raro.:confused: No logro ver donde estoy metiendo mal la pata.
Saludos,

Yo lo que pienso, es jugar con la cantidad de Letras (18), y sus condiciones de <, > e =. Puesto a que puedo hacer:


function AnnoALetra(Anno: integer): string;
const
LETRAS = 'KLMNPRSTVXZABCDEFHJ';
var dif: integer;
begin
dif := Anno mod 2000; //2000 es el primer año a contabilizar
if dif<=18 then result := LETRAS[dif + 1];
if dif>18 then result := LETRAS[dif - 18];
end;


Lo que me faltaria, es usar una variable multiplo de 18, cosa de mantener su valor de entre 0 y 18.

Delphius
31-07-2007, 19:52:30
Mamu, acabo de editar mi función anterior... chequeala. El segundo mod hace lo que pides: que el rango oscile entre 0 y 18.

Saludos,

MaMu
31-07-2007, 20:00:44
Mamu, acabo de editar mi función anterior... chequeala. El segundo mod hace lo que pides: que el rango oscile entre 0 y 18.

Saludos,

La he chequeado, pero el problema esta en el año de inicio, ya que segun varie este, me desplaza el orden ciclico. La letra T equivale al año 2007, y no debe varias segun el año de inicio a computar, ya sea que arranque del 2000, como del 1950, llegado al año 2007, deberia corresponderse con la letra T.

basti
31-07-2007, 21:27:16
Modificando un poco la función

function AnnoALetra(Anno: integer): string;
const
LETRAS = 'KLMNPRSTVXZABCDEFHJ';
var dif: integer;
begin
// para los años mayores de 2000
if anno - 2000 >= 0 then
dif := (Anno - 2000) mod 19 + 1
else
dif := 19 - (2000 - Anno) mod 19;
result := LETRAS[dif];
end;


No lo probé pero creo que la solución va por ahí.

Edito: el número de letras son 19 así que cambié algo

luisgutierrezb
01-08-2007, 00:41:36
se me ocurrio esto, cuestion de probarlo bien:


// basado en el codigo de Delphius

function AnioALetra(Anio: integer): string;
const
LETRAS = 'KLMNPRSTVXZABCDEFHJ';
var dif: integer;
begin
dif := (Anio + 14) mod 19 + 1;
result := LETRAS[dif];
end;

MaMu
01-08-2007, 03:40:10
se me ocurrio esto, cuestion de probarlo bien:


Código Delphi [-] (http://www.clubdelphi.com/foros/#)
// basado en el codigo de Delphius

function AnioALetra(Anio: integer): string;
const
LETRAS = 'KLMNPRSTVXZABCDEFHJ';
var dif: integer;
begin
dif := (Anio + 14) mod 19 + 1;
result := LETRAS[dif];
end;






SOLUCIONADO

Gracias a todos por la ayuda. Implemente esta funcion y el resultado fue optimo. Ahora bien, utilice un poco de todas las ideas para hacer una acorde a los cambios que necesitaba y logre solucionarlo.

Saludos

MaMu
01-08-2007, 06:20:17
Ahora, me surgio una duda. Que pasa si quiciera hacer el proceso inverso?? es decir, si segun la letra que introduzca, me devuelva al año que equivale, obviamente dentro de las 19 posibles letras.



function LetraAnio(Letra:string):string;
.....

...
//"2007"
Label1.Caption:=LetraAnio('T');


Saludos

MaMu
01-08-2007, 20:02:41
SOLUCIONADO

Gracias a todos por sus consejos. Ya he logrado hacerlo.

Saludos

egostar
01-08-2007, 20:11:37
Hola mamu, seria bueno y hasta cortés que postearas la solución para futuras consultas de compañeros que tengamos la misma duda.

Salud OS.

MaMu
01-08-2007, 22:11:59
Hola mamu, seria bueno y hasta cortés que postearas la solución para futuras consultas de compañeros que tengamos la misma duda.

Salud OS.

Si, mil disculpas, se me pasó.

Esta es la solución, mas bien, una variante, pero que se ajustó perfectamente a mi aplicación.


function LetraAnio(Letra: string;Orden:Boolean):string;
const
LETRAS = 'KLMNPRSTVXZABCDEFHJ';
var a,m,d:word;
i,cont:integer;
begin
cont:=0;
DecodeDate(now(),a,m,d);
for i:=1 to 19 do
begin
cont:=cont+1;
if Orden=True
then begin
if Letra=LETRAS[i]
then begin
cont:=cont-1;
if cont<=10 then Result:=IntToStr(2000+cont)
else Result:=IntToStr(2000+cont-19);
end;
end
else begin
if Letra=LETRAS[i]
then begin
cont:=cont-1;
if cont<=10 then Result:=IntToStr(2000+cont-19)
else Result:=IntToStr(2000+cont);
end;
end;
end;
end;



Saludos

luisgutierrezb
02-08-2007, 00:11:44
a lo mejor es un poco tarde, pero se me ocurrio esto para lo inverso:


// basado en el codigo de Delphius

function LetraAAnio(Letra: Char): Integer;
const
LETRAS = 'KLMNPRSTVXZABCDEFHJ';
var
i,j: integer;
begin
i := Pos(AnioALetra(Year(Now)), Letras);
j := Pos(Letra, Letras);
if i <= j then
Result := Year(Now) + (j-i)
else
Result := Year(Now) - (i-j)
end;

delphi.com.ar
02-08-2007, 00:37:08
Yo tambien quiero: :p


const
LETRAS = 'DEFHJKLMNPRSTVXZABC';
begin
Result := LETRAS[(MyYear) mod 19 + 1];


Otra aún mas simple:


const
LETRAS : array[0..19] of char = 'DEFHJKLMNPRSTVXZABC';
begin
Result := LETRAS[(MyYear) mod 19];