Jj's web stream

Javascript fun

El otro día Steve hizo un post muy interesante acerca de cómo se calcula la fecha en que debe caer semana santa cada año.

Lo entretenido fue que puso un pequeño formulario que calculaba la fecha de semana santa utilizando Javascript. Si se ve el algoritmo es muy explicativo y fácil de entender.

function calcular() {




    var ent = document.frm.year;




    var sal = document.frm.res;




    year = parseInt(ent.value);




    a = year % 19;




    b = year % 4;




    c = year % 7;




    if (year >= 1583 && year <= 1699) {




        m = 22;




        n = 2;




    } else {




        if (year >= 1700 && year <= 1799) {




            m = 23;




            n = 3;




        } else {




            if (year >= 1800 && year <= 1899) {




                m = 23;




                n = 4;




            } else {




                if (year >= 1900 && year <= 2099) {




                    m = 24;




                    n = 5;




                } else {




                    if (year >= 2100 && year <= 2199) {




                        m = 24;




                        n = 6;




                    } else {




                        if (year >= 2200 && year <= 2299) {




                            m = 25;




                            n = 0;




                        } else {




                            sal.value = "A\xF1o debe ser entre 1583 y 2299";




                            return;




                        }




                    }




                }




            }




        }




    }




d = (19 * a + m) % 30;




e = (2 * b + 4 * c + 6 * d + n) % 7;




    if (d + e < 10) {




        sal.value = (d + e + 22) + " de Marzo";




    } else {




        if ((d + e - 9) == 26) {




            sal.value = "19 de Abril";




        } else {




            if ((d + e - 9) == 25 && d == 28 && e == 6 && a > 10) {




                sal.value = "18 de Abril";




            } else {




                sal.value = (d + e - 9) + " de Abril";




            }




        }




    }




}

Sin embargo, simplemente por las ganas de jugar, se me ocurrio escribirlo al revez, comenzar por la asignacion final y terminar por las validaciones de los rangos de años. Terminé con esto:

var y = 2006;




alert(function(y, mn){




    if (mn) {




        var a = y % 19;




        var b = y % 4;




        var c = y % 7;




        var d = (19 * a + mn[0]) % 30;




        var e = (2 * b + 4 * c + 6 * d + mn[1]) % 7;




        var f = d + e;




        return (f < 10)?(d + 22) + 'de Marzo':(!(f - 35)?'19 de Abril':((f - 9) == 25 && d == 28 && e == 6 && a > 10)?'18 de Abril':(f - 9) + ' de Abril');




    } else {




        return 'Año inválido';




    }




}(y, function(y,d) {




    for (i in d) if (y < i) return d[i];




}(y, {1583:null, 1700:[22,2], 1800:[23,3], 1900:[23,4], 2100:[24,5], 2200:[24,6], 2300:[25,0]})));

No me gustó como quedaron todas las asignaciones, así que intenté hacer que todos los bloques sean de una sola línea (un one-liner), y terminé con esto:

var y = 2006;




alert(




    function(y, mn){




        return (mn)?




            function(a,b,c) {




                return function(a,b,c,d){




                    return function(a,b,c,d,e){




                        function(a,b,c,d,e,f){




                            return (f < 10)?(d+22) + 'de Marzo':(!(f-35)?'19 de Abril':((d + e - 9) == 25 && d == 28 && e == 6 && a > 10)?'18 de Abril':(f-9)+' de Abril');




                        }(a,b,c,d,e,d + e)




                    }(a,b,c,d,(2 * b + 4 * c + 6 * d + mn[1]) % 7);




                }(a,b,c,(19 * a + mn[0]) % 30);




            } (y % 19, y % 4, y % 7)




        :




            'El a\xF1o debe ser entre 1583 y 2299';




    }(y, function(y,d) {




        for (i in d) if (y < i) return d[i];




    }(y, {1583:null, 1700:[22,2], 1800:[23,3], 1900:[23,4], 2100:[24,5], 2200:[24,6], 2300:[25,0]}))




);

Cabe resaltar que el código original de Steve es más rápido y mas eficiente, debido a que no se hacen tantas llamadas a funciones ni hay que hacer tanto paso de variables por parámetros entre ellas. Simplemente lo hice para ver lo que se puede hacer con un lenguaje que tiene varias cualidades de lenguaje funcional :) .

Comments

dieguito: b00bgeneer.

yfyfyf: yryyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy