Algoritmo de Tomohiko Sakamoto: encontrar el día de la semana

Dada cualquier fecha según el calendario gregoriano, la tarea es devolver el día (lunes, martes, etc.) en ese día en particular. 
Ejemplos: 
 

Input :  Date: 13 July 2017 [13.07.2017]
Output : 4 i.e Thursday

Input : Date: 15 August 2012 [15.08.2012]
Output : 3 i.e Wednesday

Input : Date: 24 December 2456 [24.12.2456]
Output : 0 i.e Sunday

Aunque hay muchos métodos para resolver esta pregunta, uno de los métodos menos conocidos y más poderosos es el algoritmo de Tomohiko Sakamoto
Explicación 
Ene 1st 1 AD es un lunes en el calendario gregoriano. 
Consideremos el primer caso en el que no tenemos años bisiestos, por lo que el número total de días en cada año es 365. Enero tiene 31 días, es decir, 7*4+3 días, por lo que el día 1 de febrero siempre será 3 días anterior a el día 1 de enero. Ahora febrero tiene 28 días (excluyendo los años bisiestos) que es un múltiplo exacto de 7 (7*4=28) Por lo tanto, no habrá cambios en el mes de marzo y también estará 3 días por delante del día el 1 de enero de ese año respectivo. Teniendo en cuenta este patrón, si creamos una array del número principal de días para cada mes, se dará como t[] = {0, 3, 3, 6, 1, 4, 6, 2, 5, 0, 3, 5}. 
Ahora veamos el caso real cuando hay años bisiestos. Cada 4 años, nuestro cálculo ganará un día más. Excepto cada 100 años cuando no lo hace. Excepto cada 400 años cuando lo hace. ¿Cómo ponemos en estos días adicionales? Bueno, solo suma y/4 – y/100 + y/400. Tenga en cuenta que toda división es división entera. Esto agrega exactamente el número requerido de días bisiestos. Pero aquí hay un problema, el día bisiesto es el 29 de febrero y no el 0 de enero. Esto significa que el año actual no debe contarse para el cálculo de días bisiestos durante los dos primeros meses. Supongamos que si el mes era enero o febrero, restamos 1 al año. Esto significa que durante estos meses, el valor de y/4 sería el del año anterior y no se contabilizaría. ¿Si restamos 1 de los valores t[] de cada mes después de febrero? Eso llenaría el vacío, 
1.t[] ahora se convierte en {0, 3, 2, 5, 0, 3, 5, 1, 4, 6, 2, 4}. 
2.si m corresponde a enero/febrero (es decir, mes<3) decrementamos y en 1. 
3.el incremento anual dentro del módulo ahora es y + y/4 – y/100 + y/400 en lugar de y . 
 

A continuación se muestra la implementación de este algoritmo: 
 

C++

// A CPP program to implement
// the Tomohiko Sakamoto Algorithm
#include <bits/stdc++.h>
using namespace std;
 
// function to implement tomohiko
// sakamoto algorithm
int day_of_the_week(int y, int m, int d)
{
    // array with leading number of days values
    int t[] = { 0, 3, 2, 5, 0, 3, 5, 1, 4, 6, 2, 4 };
     
    // if month is less than 3 reduce year by 1
    if (m < 3)
        y -= 1;
     
    return ((y + y / 4 - y / 100 + y / 400 + t[m - 1] + d) % 7);
}
 
// Driver Code
int main(void)
{
    int day = 13, month = 7, year = 2017;
    cout<<(day_of_the_week(year, month, day));
    return 0 ;
}
 
// This code is contributed by Nikita Tiwari.

Java

// A java program to implement
// the Tomohiko Sakamoto Algorithm
 
class tomohiko_sakamoto
{
    // function to implement tomohiko sakamoto algorithm
    public static int day_of_the_week(int y, int m, int d)
    {
        // array with leading number of days values
        int t[] = { 0, 3, 2, 5, 0, 3, 5, 1, 4, 6, 2, 4 };
         
        // if month is less than 3 reduce year by 1
        if (m < 3)
            y -= 1;
         
        return (y + y / 4 - y / 100 + y / 400 + t[m - 1] + d) % 7;
    }
    // Driver Code
    public static void main(String args[])
    {
        int day = 13, month = 7, year = 2017;
        System.out.println(day_of_the_week(year, month, day));
    }
}

Python3

# A Python 3 program to implement
# the Tomohiko Sakamoto Algorithm
  
 
# function to implement tomohiko
# sakamoto algorithm
def day_of_the_week(y,  m, d) :
 
    # array with leading number of days values
    t = [ 0, 3, 2, 5, 0, 3, 5, 1, 4, 6, 2, 4 ]
          
    # if month is less than 3 reduce year by 1
    if (m < 3) :
        y = y - 1
          
    return (y + y // 4 - y // 100 + y // 400 + t[m - 1] + d) % 7
     
     
# Driver Code
day = 13
month = 7
year = 2017
 
print(day_of_the_week(year, month, day))
     
# This code is contributed by Nikita Tiwari.

C#

// A C# program to implement
// the Tomohiko Sakamoto Algorithm
using System;
 
class GFG {
     
    // function to implement tomohiko
    // sakamoto algorithm
    public static int day_of_the_week(int y,
                                 int m, int d)
    {
         
        // array with leading number of days
        // values
        int []t = { 0, 3, 2, 5, 0, 3, 5, 1,
                                4, 6, 2, 4 };
         
        // if month is less than 3 reduce
        // year by 1
        if (m < 3)
            y -= 1;
         
        return (y + y / 4 - y / 100 + y / 400
                          + t[m - 1] + d) % 7;
    }
     
    // Driver Code
    public static void Main()
    {
        int day = 13, month = 7, year = 2017;
         
        Console.WriteLine(day_of_the_week(year,
                                   month, day));
    }
}
 
// This code is contributed by vt_m.

PHP

<?php
// PHP program to implement
// the Tomohiko Sakamoto Algorithm
 
// function to implement tomohiko
// sakamoto algorithm
function day_of_the_week($y, $m, $d)
{
     
    // array with leading number
    // of days values
    $t = array(0, 3, 2, 5, 0, 3,
               5, 1, 4, 6, 2, 4);
     
    // if month is less than
    // 3 reduce year by 1
    if ($m < 3)
        $y -= 1;
     
    return (($y + $y / 4 - $y / 100 + $y /
             400 + $t[$m - 1] + $d) % 7);
}
 
    // Driver Code
    $day = 13;
    $month = 7;
    $year = 2017;
    echo day_of_the_week($year, $month, $day);
 
// This code is contributed by ajit.
?>

Javascript

<script>
 
// JavaScript  program to implement
// the Tomohiko Sakamoto Algorithm
 
// function to implement tomohiko sakamoto algorithm
    function day_of_the_week(y, m, d)
    {
        // array with leading number of days values
        let t = [ 0, 3, 2, 5, 0, 3, 5, 1, 4, 6, 2, 4 ];
           
        // if month is less than 3 reduce year by 1
        if (m < 3)
            y -= 1;
           
        return (y + y / 4 - y / 100 + y / 400 + t[m - 1] + d) % 7;
    }
   
  
// Driver code
 
        let  day = 13, month = 7, year = 2017;
         document.write(Math.round(day_of_the_week(year, month, day)));
 
</script>

Producción: 

 4 

Publicación traducida automáticamente

Artículo escrito por mohdanishh y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *