2009-02-13 15 views
6

Me gustaría ser capaz de comenzar con un año, y el cálculo de las apariciones de Viernes 13. Una solución de fuerza bruta es fácil y obvia. Tengo algo un poco mejor, pero no tengo ninguna duda de que otra persona puede subir con un elegante algoritmo para esto.Cálculo de futuras ocurrencias del Viernes 13

Tal vez un poco más complicado, me gustaría dar el programa un mes, y hacer que encuentre el próximo año en el que ese mes tenga un viernes 13.

no dude en utilizar pseudo código, pero espero que la gente va a votar más por trabajar ejemplos de código en el que el lenguaje preferido.

+1

Feliz 1234567890 unix time day! –

+0

Tal vez puede ser un bonito desafío de golf ... – Eineki

+1

Las películas salen ahora con bastante regularidad, una estimación de unos 3 años suena bien :) – cjk

Respuesta

10

Cualquier mes que comienza con un domingo tiene un viernes en la decimotercera. Solo hay 14 combinaciones posibles, sabiendo qué día está el primero del año (con o sin año bisiesto, y sun-sat). Deberías calcularlo una vez y terminarlo de nuevo. Solo verificaría 14 * 12 meses posibles para comenzar, bien con justificación.

elemento resultante mesa (de 2009, 2010):

[Thursday,false] => Feb, March, Nov 
[Friday,false] => Aug 

para llenar la tabla que tiene un mes de enero genérico (31), febrero (28) .. y luego repetir con una semilla de cada día de la semana, teniendo en cuenta los meses que comienzan con el domingo, y también con un año bisiesto y sin él. Muy sencillo, y una vez hecho, puedes compartirlo con nosotros :)

+2

Este es el método de mesa más rápido, afaict. Hay catorce tipos de días de la semana: 7 para años no bisiestos, 7 para años bisiestos y 12 meses. Una matriz en 2D o 3D brinda una respuesta muy rápida una vez que sepa en qué día de la semana entra el 1 de enero, y si es un año bisiesto, ambos son fáciles de calcular. –

1
initialize startDate to 13th of the month given in the current year 
while (true) { 
    if (startDate.dayOfWeek == Date.FRIDAY) 
     break; 
    else 
     startDate.year ++; 
} 
return startDate.year; 
10

Debido a que su algoritmo de fuerza bruta es aparentemente la intuitiva día a día iteración opción, tal vez no han considerado la Doomsday Algorithm. Te permitiría simplemente verificar si ese día 13 es un viernes. Hasta donde yo sé, es la solución más eficiente para el problema.

2

Una cosa que noté es que el primero del mes cae en domingo durante meses con un viernes 13. Probablemente pueda aprovechar esto para que sea más fácil de calcular.

1

Esta es la forma en que lo haría:

  • Supongamos años es conocida y es un entero.

  • bucle de 1 a 12

    • Fecha de creación con el índice de bucle, año y 13 para el día

      • Determine día de la semana según established algorithms

      • Si el día de la semana calculada arriba es el viernes, haga su trabajo

Si desea comenzar con un mes y año (hay que asumir algún tipo de ejercicio), el algoritmo se vuelve

  • Supongamos años es conocido y un entero

  • Supongamos meses es conocida y es un número entero

  • Loop

    • fecha de creación con el índice de bucle como el año, variable conocida mes, y 13 para el día

    • Determinar día de la semana según established algorithms

    • Si el día de la semana cálculo anterior es viernes fecha de vuelta, de lo contrario

    • Else año se incrementan en 1

3

Here's some example PHP code que pasa por un bucle bastante directo de las fechas en un rango. Me gustaría modificar esto para verificar el día 13 de cada mes para el viernes, en lugar de revisar todos los viernes para saber si hay 13, como lo hacen en el ejemplo.

+1

Revisar el día 13 de cada mes es sin duda la mejor manera de hacerlo. –

+2

Sí, me pareció 4 veces más eficiente. :) –