title: Javascript fun
link: http://jj.isgeek.net/2006/06/javascript-fun/
author: Jj
description: 
post_id: 189
date: 2006/06/19 23:56:27
created_gmt: 2006/06/20 04:56:27
comment_status: open
slug: javascript-fun

El otro dÃ­a [Steve](http://steve.blogdns.org/) 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](http://en.wikipedia.org/wiki/One-liner_program)_), 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](#1423 "2006-06-20 08:52:55"):** b00bgeneer.

**[yfyfyf](#1800 "2006-07-21 13:29:28"):** yryyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy

