2009-02-13 12 views
6

Ich möchte mit einem Jahr beginnen und Ereignisse von Freitag dem 13. berechnen können. Eine Brute-Force-Lösung ist einfach und offensichtlich. Ich habe etwas etwas besseres, aber ich habe keinen Zweifel, dass jemand anders einen eleganten Algorithmus dafür finden kann.Berechne zukünftige Vorkommen von Freitag, den 13.

Vielleicht ein wenig komplizierter, wäre ich daran interessiert, dem Programm einen Monat zu geben, und es das nächste Jahr zu finden, in dem dieser Monat einen Freitag den 13. hat.

Fühlen Sie sich frei, Pseudo-Code zu verwenden, aber ich erwarte, dass Leute mehr für funktionierende Codebeispiele in Ihrer Lieblingssprache wählen werden.

+1

Glücklich 1234567890 Unix Zeit Tag! –

+0

Vielleicht kann es eine schöne Golfherausforderung sein ... – Eineki

+1

Die Filme kommen jetzt ziemlich regelmäßig heraus, eine Schätzung von ungefähr 3 Jahren klingt nach rechts :) – cjk

Antwort

10

Jeder Monat, der mit einem Sonntag beginnt, hat einen Freitag am dreizehnten. Es sind nur 14 Kombinationen möglich, die wissen, an welchem ​​Tag der erste Tag des Jahres ist (mit oder ohne Schaltjahr und Sonne-Sat). Sie sollten es nur einmal berechnen und es hinter sich bringen. Sie würden nur 14 * 12 mögliche Monate prüfen, um damit anzufangen, und zwar mit gutem Grund.

resultierendes Tabellenelement (ab 2009, 2010):

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

die Tabelle füllen Sie einen generischen Monat Jan haben (31), Februar (28) .. und dann mit einem Samen eines jeden Tages iterieren der Woche, Monate, die mit Sonntag beginnen, und auch mit einem Schaltjahr und ohne. Ziemlich geradlinig, und einmal fertig, können Sie es mit uns teilen :)

+2

Dies ist die schnellste Tabellenmethode, afaict. Es gibt vierzehn Arten von Wochentagen - 7 für Nicht-Schaltjahre, 7 für Schaltjahre und 12 Monate. Ein 2D- oder 3D-Array liefert eine sehr schnelle Antwort, sobald Sie wissen, an welchem ​​Wochentag der 1. Januar fällt und ob es ein Schaltjahr ist - beide sind leicht zu berechnen. –

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

Da Ihr Brute-Force-Algorithmus offenbar die intuitiv wird von Tag zu Tag Iteration Option, vielleicht haben Sie die Doomsday Algorithm nicht berücksichtigt. Es würde Ihnen erlauben, einfach zu überprüfen, ob dieser 13. ein Freitag ist. Soweit ich weiß, ist es die effizienteste Lösung für das Problem.

2

Eine Sache, die ich bemerkte, ist, dass der erste des Monats an einem Sonntag während Monaten mit einem Freitag der 13. fällt. Sie können dies wahrscheinlich nutzen, um die Berechnung zu vereinfachen. Diese

1

ist, wie ich es tun würde:

  • Angenommen Jahr ist bekannt und ist eine ganze Zahl.

  • Schleife von 1 bis 12

    • erstellen Datum mit Schleifenindex, Jahr und 13 für den Tag

      • Tag der Woche fest, wie pro established algorithms

      • Wenn Tag der oben berechneten Woche ist Freitag, machen Sie Ihre Arbeit

Wenn Sie mit einem Monat und Jahr zu starten (Sie haben eine Art von Jahr zu übernehmen), Ihr Algorithmus wird

  • Angenommen Jahr bekannt ist und eine ganze Zahl

  • Angenommen Monat bekannt ist und eine ganze Zahl

  • Schleife

    • erstellen Datum mit dem Index der Schleife als Jahr bekannt Monat variabel und 13 für den Tag

    • Tag der Woche fest, wie pro established algorithms

    • Wenn Wochentag berechnet oben ist Freitag, Rückgabedatum, sonst

    • Else Zuwachs von Jahr 1

3

Here's some example PHP code das geht durch eine ziemlich direkte Schleife der Daten in einer Reihe. Ich würde dies ändern, um den 13. eines jeden Monats auf Freitagheit zu prüfen, anstatt jeden Freitag auf 13 zu prüfen, wie sie es im Beispiel tun.

+1

Die Überprüfung des 13. eines jeden Monats ist sicherlich der bessere Weg zu gehen. –

+2

Ja, schien mir etwa 4X effizienter. :) –

Verwandte Themen