Oblicz fazę księżycową

10

Wprowadzenie

tl; dr

W tym wyzwaniu musisz obliczyć fazę księżyca dla danej daty.


To wyzwanie jest inspirowany przez gry psycho społecznego eksperymentu audiowizualnySuperbrothers: Sword & Sworcery EP ”. W S: S&S EP fazy księżyca są ważne dla wyniku przygody, ponieważ niektóre wydarzenia mają miejsce tylko w określonym momencie.

Zrzut ekranu z Superbrothers: Sword & Sworcery EP

Pytanie brzmi: która faza księżycowa jest obecna w określonym dniu. Każda główna faza - od nowiu przez pierwszy kwartał do pełni księżyca i trzeci kwartał - trwa około 7,38 dnia. Cały cykl księżycowy trwa około 29,52 dni. W oparciu o te wartości istnieją różne metody obliczania. 1

Wejście

  • Data oparta na kalendarzu gregoriańskim, między 1 stycznia 1970 r. A 31 grudnia 2116 r.
  • Można wybrać jeden z następujących formatów: yyyy-mm-dd, dd.mm.yyyy, dd/mm/yyyy, yyyymmddlub ddmmyyyy.

Wynik

Wyprowadza indeks [0-7]fazy księżycowej na podstawie tej tablicy o indeksie zerowym:

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

Wymagania

  • Możesz napisać program lub funkcję. Jeśli korzystasz z funkcji anonimowej, podaj przykład jej wywołania.
  • Dane wejściowe są akceptowane z STDINargumentów wiersza poleceń jako parametrów funkcji lub z najbliższego odpowiednika.
  • To jest więc wygrywa najkrótsza odpowiedź w bajtach.
  • Wbudowane lub zewnętrzne biblioteki obliczające fazę księżyca są niedozwolone. 2)
  • Standardowe luki są niedozwolone.

Testy

Wartości są następujące: date | index of the phase | illumination | name

Pełny cykl księżycowy:

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

Przypadkowe przypadki testowe:

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

Ponieważ większość metod nie jest dokładna na poziomie naukowym, a przez kilka dni otrzymujesz mieszane wyniki na różnych stronach internetowych, dopuszczalne jest, aby wyniki mieściły się w zakresie ± 1 dnia .

Premia

Zmniejsz liczbę bajtów i wycofaj :

  • 15% - Wydrukuj rzeczywistą nazwę fazy zgodnie z listą w sekcji Wyjście zamiast jej indeksu.
  • 25% - Wydrukuj daty nadchodzącego nowiu i pełni księżyca oddzielone białymi spacjami lub znakami nowej linii na pustych danych wejściowych.

1 Na przykład: Faza obliczania na Wikipedii.
2 Przepraszam Mathematica .

wstawić nazwę tutaj
źródło
Moje pieniądze są na Japt.
lirtosiast
Jak długo trwa każda faza? Odwołujesz się do czterech głównych faz trwających około 7 dni, ale masz do czynienia z 8 fazami.
Sherlock9
1
Myślę, że aby pomóc mi zrozumieć, jak długo powinna trwać każda faza, czy możesz napisać testowy przypadek trwający około pięciu kolejnych dni, lub jak długo zajmie przejście od, powiedzmy, „woskowatej gibki” do „słabnącej gibki” według twojego obliczenia? Mam problem z definicjami, ponieważ na przykład ćwierć księżyca to moment 50% iluminacji, więc „pierwszy kwadrans” powinien być tylko w tym samym dniu, z „powiększającym się półksiężycem” i „zanikającym półksiężycem” w dniach poprzedzających i po. Ale nie jestem pewien.
Sherlock9,
W porządku, zacznę od mojego rozwiązania. Dziękuję za wyjaśnienie części tego.
Sherlock9
@ Sherlock9 Zaktualizowałem przypadki testowe o pełny cykl księżycowy i kilka losowych wartości, w tym oświetlenie każdego dnia. Mam nadzieję, że jest to pomocne.
inserttusernamehere

Odpowiedzi:

3

Python 2 3, 255 204 180 178 bajtów

Ta odpowiedź jest niedokładna w ciągu jednego lub dwóch dni w kilku miejscach, w tym w niektórych przypadkach testowych, chociaż powiedziano mi, że pewne niedokładności są dopuszczalne. W każdym razie ruch księżyca nigdy nie jest bardzo dokładny, a funkcja ta pozostaje ogólnie poprawna (a przynajmniej nie zmienia się zbyt daleko).

Edycja: W trakcie poprawiania mojego kodu i zwiększania jego dokładności znacznie go poprawiłem.

Edycja: Ten kod jest teraz jednowierszowym programem w języku Python 3. ( Podziękowania dla TimmyD za nazwę „magiczne liczby”)

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)

Nie golfowany:

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
źródło
@TimmyD Nie masz pojęcia, ile magicznych liczb próbowałem i wyrzuciłem, żeby to zadziałało XD
Sherlock9