Calcola la fase lunare


10

introduzione

tl; dr

In questa sfida devi calcolare la fase lunare per una determinata data.


Questa sfida è ispirata all'esperimento psico-sociale audiovisivo del gioco " Superbrothers: Sword & Sworcery EP ". In S: S&S EP le fasi lunari sono importanti per il risultato dell'avventura poiché alcuni eventi si verificano solo in un determinato momento.

Schermata di Superbrothers: Sword & Sworcery EP

La domanda è: quale fase lunare è presente in una data specifica. Ogni fase principale - dalla luna nuova al primo quarto alla luna piena al terzo trimestre - dura circa 7,38 giorni. L'intero ciclo lunare dura circa 29,52 giorni. Sulla base di questi valori esistono vari metodi di calcolo. 1

Ingresso

  • Una data basata sul calendario gregoriano, tra il 1 ° gennaio 1970 e il 31 dicembre 2116.
  • È possibile scegliere uno dei seguenti formati: yyyy-mm-dd, dd.mm.yyyy, dd/mm/yyyy, yyyymmddo ddmmyyyy.

Produzione

Emette l'indice [0-7]della fase lunare in base a questo array a indice zero:

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

Requisiti

  • È possibile scrivere un programma o una funzione. Se utilizzi una funzione anonima, includi un esempio di come invocarlo.
  • L'input è accettato dagli STDINargomenti della riga di comando, come parametri di funzione o dall'equivalente più vicino.
  • Questo è quindi la risposta più breve in byte vince.
  • Non sono consentiti built-in o librerie esterne che calcolano la fase lunare. 2
  • Le scappatoie standard non sono ammesse.

test

I valori sono: date | index of the phase | illumination | name

Un ciclo lunare completo:

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

Casi di test casuali:

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

Poiché la maggior parte dei metodi non è accurata a livello scientifico e si ottengono anche risultati contrastanti su diversi siti Web per un paio di questi giorni, è accettabile se i risultati rientrano nell'intervallo di ± 1 giorno .

indennità

Riduci il conteggio dei byte e ritira :

  • 15% - Stampa il nome effettivo della fase come elencato nella sezione Output anziché il suo indice.
  • 25% - Stampa le date della nuova luna piena e imminente separate da uno spazio bianco o da una riga nuova su input vuoto.

1 Ad esempio: fase di calcolo su Wikipedia.
2 Mi dispiace Mathematica .


I miei soldi sono su Japt.
lirtosiast,

Quanto dura ogni fase? Ti riferisci a quattro fasi principali della durata di circa 7 giorni, ma ci sono 8 fasi da affrontare.
Sherlock9,

1
Penso che mi possa aiutare a capire quanto dovrebbe essere lunga ogni fase, puoi pubblicare un caso di test di circa cinque giorni consecutivi, o per quanto tempo ci vuole per passare da "ceretta gibbosa" a "calante gibbosa" secondo i tuoi conti? Ho problemi con le definizioni perché, ad esempio, le lune di quarto sono l' istante di illuminazione del 50%, quindi il "primo trimestre" dovrebbe essere solo il giorno stesso, con "crescente luna" e "calante crescente" nei giorni precedenti e dopo. Ma non sono sicuro.
Sherlock9,

Bene allora, inizierò con la mia soluzione. Grazie per aver chiarito un po 'questo.
Sherlock9,

@ Sherlock9 Ho aggiornato i casi di test con un ciclo lunare completo e alcuni valori casuali, inclusa l'illuminazione di ogni giorno. Speriamo che sia utile
inserisci nomeutentequi

Risposte:


3

Python 2 3, 255 204 180 178 byte

Questa risposta è inaccurata da un giorno o due in diversi punti, incluso per alcuni dei casi di test, anche se mi è stato detto che una certa imprecisione era accettabile. Ad ogni modo, il movimento della luna non è mai molto esatto e questa funzione rimane generalmente corretta (o almeno non varia troppo).

Modifica: Nel corso della correzione del mio codice e di renderlo più accurato, l'ho ridotto notevolmente.

Modifica: questo codice è ora un programma Python 3 su una riga. (Ringraziamo TimmyD per il nome "numeri magici")

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)

@TimmyD Non hai idea di quanti numeri magici ho provato e buttato fuori per farlo funzionare XD
Sherlock9
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.