Berechnen Sie die Mondphase

10

Einführung

tl; dr

Bei dieser Herausforderung müssen Sie die Mondphase für ein bestimmtes Datum berechnen.


Diese Herausforderung wird durch die inspirierte Spiel psychosoziale audiovisuellen Experiment: Sword & Sworcery EP Superbrothers “. In S: S & S EP sind die Mondphasen für das Ergebnis des Abenteuers wichtig, da einige Ereignisse nur zu einem bestimmten Zeitpunkt auftreten.

Screenshot von Superbrothers: Sword & Sworcery EP

Die Frage ist: Welche Mondphase ist zu einem bestimmten Zeitpunkt vorhanden? Jede Hauptphase - vom Neumond über das erste Quartal bis zum Vollmond bis zum dritten Quartal - dauert etwa 7,38 Tage. Der gesamte Mondzyklus beträgt ungefähr 29,52 Tage. Basierend auf diesen Werten existieren verschiedene Berechnungsmethoden. 1

Eingang

  • Ein auf dem Gregorianischen Kalender basierendes Datum zwischen dem 1. Januar 1970 und dem 31. Dezember 2116.
  • Sie können eine der folgenden Formaten wählen: yyyy-mm-dd, dd.mm.yyyy, dd/mm/yyyy, yyyymmddoder ddmmyyyy.

Ausgabe

Geben Sie den Index [0-7]der Mondphase basierend auf diesem nullindizierten Array aus:

['New moon', 'Waxing crescent', 'First quarter', 'Waxing gibbous', 'Full moon', 'Waning gibbous', 'Third quarter', 'Waning crescent`]

Bedarf

  • Sie können ein Programm oder eine Funktion schreiben. Wenn Sie sich für eine anonyme Funktion entscheiden, geben Sie bitte ein Beispiel für den Aufruf an.
  • Die Eingabe wird von STDINBefehlszeilenargumenten, als Funktionsparameter oder vom nächsten Äquivalent akzeptiert .
  • Dies ist so dass die kürzeste Antwort in Bytes gewinnt.
  • Eingebaute oder externe Bibliotheken, die die Mondphase berechnen, sind nicht zulässig. 2
  • Standardlücken sind nicht zulässig.

Tests

Die Werte sind: date | index of the phase | illumination | name

Ein vollständiger Mondzyklus:

08.02.2016 | 0 |   0% | New moon
07.02.2016 | 7 |   2% | Waning crescent
07.02.2016 | 7 |   2% | Waning crescent
06.02.2016 | 7 |   6% | Waning crescent
05.02.2016 | 7 |  12% | Waning crescent
04.02.2016 | 7 |  19% | Waning crescent
03.02.2016 | 7 |  28% | Waning crescent
02.02.2016 | 7 |  37% | Waning crescent
01.02.2016 | 6 |  47% | Third quarter
31.01.2016 | 5 |  56% | Waning gibbous
30.01.2016 | 5 |  65% | Waning gibbous
29.01.2016 | 5 |  74% | Waning gibbous
28.01.2016 | 5 |  82% | Waning gibbous
27.01.2016 | 5 |  89% | Waning gibbous
26.01.2016 | 5 |  94% | Waning gibbous
25.01.2016 | 5 |  98% | Waning gibbous
24.01.2016 | 4 | 100% | Full moon
23.01.2016 | 3 | 100% | Waxing gibbous
22.01.2016 | 3 |  97% | Waxing gibbous
21.01.2016 | 3 |  93% | Waxing gibbous
20.01.2016 | 3 |  86% | Waxing gibbous
19.01.2016 | 3 |  77% | Waxing gibbous
18.01.2016 | 3 |  67% | Waxing gibbous
17.01.2016 | 3 |  56% | Waxing gibbous
16.01.2016 | 2 |  45% | First quarter
15.01.2016 | 1 |  33% | Waxing crescent
14.01.2016 | 1 |  23% | Waxing crescent
13.01.2016 | 1 |  14% | Waxing crescent
12.01.2016 | 1 |   7% | Waxing crescent
11.01.2016 | 1 |   2% | Waxing crescent
10.01.2016 | 0 |   0% | New moon

Zufällige Testfälle:

14.12.2016 | 4 | 100% | Full moon
16.10.1983 | 3 |  75% | Waxing gibbous
04.07.1976 | 2 |  47% | First quarter
28.11.1970 | 0 |   0% | New moon

Da die meisten Methoden nicht auf wissenschaftlichem Niveau genau sind und Sie für einige Tage auch auf verschiedenen Websites gemischte Ergebnisse erhalten, ist es akzeptabel, wenn Ihre Ergebnisse innerhalb eines Bereichs von ± 1 Tag liegen.

Bonus

Reduzieren Sie Ihre Byteanzahl und ziehen Sie ab :

  • 15% - Gibt den tatsächlichen Namen der Phase aus, wie im Abschnitt Ausgabe aufgeführt, anstelle des Index.
  • 25% - Drucken Sie die Daten des bevorstehenden Neu- und Vollmonds durch Leerzeichen oder Zeilenumbrüche bei leerer Eingabe.

1 Zum Beispiel: Berechnungsphase bei Wikipedia.
2 Entschuldigung Mathematica .

insertusernamehere
quelle
Mein Geld ist auf Japt.
Lirtosiast
Wie lange dauert jede Phase? Sie beziehen sich auf vier Hauptphasen, die ungefähr 7 Tage dauern, aber es gibt 8 Phasen, mit denen Sie sich befassen müssen.
Sherlock9
1
Ich denke, um zu verstehen, wie lange jede Phase dauern sollte, können Sie einen Testfall von ungefähr fünf aufeinander folgenden Tagen veröffentlichen oder wie lange es dauert, bis Sie nach Ihrer Berechnung von "Wachsen von Gibbous" zu "Abnehmen von Gibbous" wechseln? Ich habe Probleme mit den Definitionen , weil zum Beispiel Viertelmonde das sind sofort von 50% Beleuchtung, so „erstes Quartal“ sollte nur am Tag selbst, mit „Wachsen sichel“ und „abnehmenden Mond“ an den Tagen vor und nach. Aber ich bin mir nicht sicher.
Sherlock9
Also gut, ich werde mit meiner Lösung beginnen. Vielen Dank, dass Sie einiges geklärt haben.
Sherlock9
@ Sherlock9 Ich habe die Testfälle mit einem vollständigen Mondzyklus und einigen zufälligen Werten aktualisiert, einschließlich der Beleuchtung jedes Tages. Hoffentlich ist das hilfreich.
Insertusernamehere

Antworten:

3

Python 2 3, 255 204 180 178 Bytes

Diese Antwort ist an mehreren Stellen um ein oder zwei Tage ungenau, auch für einige der Testfälle, obwohl mir gesagt wurde, dass eine gewisse Ungenauigkeit akzeptabel sei. In jedem Fall ist die Bewegung des Mondes niemals sehr genau und diese Funktion bleibt im Allgemeinen korrekt (oder variiert zumindest nicht zu weit).

Bearbeiten: Im Zuge der Korrektur und Genauigkeit meines Codes habe ich ihn erheblich reduziert.

Bearbeiten: Dieser Code ist jetzt ein einzeiliges Python 3-Programm. ( Dank an TimmyD für den Namen "magische Zahlen")

p,q,r=(int(i)for i in input().split("-"));t=q<3;y=p-2000-t;i,j=divmod(((r+(153*(q+12*t-3)+2)//5+365*y+y//4-y//100+y//400+11010)*86400-74100)%2551443,637861);print((86400<=j)+2*i)

Ungolfed:

def jul(p,q,r):
    '''
    The Julian Day Number (JDN) of the input minus the JDN of January 7, 1970,
    the first new moon after January 1, 1970.
    '''
    t=q<3
    y=p-2000-t  # -2000 years to push day 0 to January 1, 2000
    return r+(153*(q+12*t-3)+2)//5+365*y+y//4-y//100+y//400+11010
    # +11010 days to push day 0 to January 7, 1970

def moon(s):
    '''
    Input format: yyyy-mm-dd

    An attempt at explaining the "magic numbers"
    - 29.53059 days is close to 2551443 seconds, so I used that
    - The offset of +12300 seconds because the new moon of 1970-01-07 was at 2035 UTC 
      or 12300 seconds before midnight. For those of you saying that this pushes 
      the beginning of my calendar to 2035, *6* January 1970, yes it does.
      But if I need to the calendar to recognize 1970-01-07 as the day of the new moon 
      which means that midnight needed to be a positive number of seconds, 0 <= x < 86400.
      Basically, I hacked it together, and +12300 worked.        
    '''
    d = 86400
    p,q,r = map(int, s.split("-"))
    z=(jul(p,q,r)*d+12300)%2551443  # 2551443 is about the number of seconds in a lunar month
    div, mod = divmod(z, 637861)    # 637861 seconds is about a quarter of a lunar month
                                    # div is what part of the lunar month this is (0 - 3)
                                    # mod is seconds since the start of the main phase
    return 2*div + (86400 <= mod)   # 2*div for the main phase, and 
                                    # is mod >= the number seconds in a day?
                                    # (+0 if within a day of the main phase, +1 otherwise)
Sherlock9
quelle
@TimmyD Sie haben keine Ahnung, wie viele magische Zahlen ich versucht und rausgeworfen habe, damit dies funktioniert XD
Sherlock9