Calculez la phase lunaire


10

introduction

tl; dr

Dans ce défi, vous devez calculer la phase de la lune pour une date donnée.


Ce défi est inspiré de l' expérience audiovisuelle psycho-sociale du jeu " Superbrothers: Sword & Sworcery EP ". Dans S: S&S EP, les phases de la lune sont importantes pour l'issue de l'aventure, car certains événements ne se produisent qu'à un moment précis.

Capture d'écran de Superbrothers: Sword & Sworcery EP

La question est: quelle phase lunaire est présente à une date précise. Chaque phase principale - de la nouvelle lune au premier trimestre à la pleine lune au troisième trimestre - dure environ 7,38 jours. L'ensemble du cycle lunaire dure environ 29,52 jours. Sur la base de ces valeurs, il existe différentes méthodes de calcul. 1

Contribution

  • Une date basée sur le calendrier grégorien, entre le 1er janvier 1970 et le 31 décembre 2116.
  • Vous pouvez choisir l' un des formats suivants: yyyy-mm-dd, dd.mm.yyyy, dd/mm/yyyy, yyyymmddou ddmmyyyy.

Production

Générez l'index [0-7]de la phase lunaire sur la base de ce tableau indexé zéro:

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

Exigences

  • Vous pouvez écrire un programme ou une fonction. Si vous utilisez une fonction anonyme, veuillez inclure un exemple de la façon de l'invoquer.
  • L'entrée est acceptée à partir des STDINarguments de ligne de commande, en tant que paramètres de fonction ou de l'équivalent le plus proche.
  • C'est le donc la réponse la plus courte en octets gagne.
  • Les bibliothèques intégrées ou externes qui calculent la phase de lune ne sont pas autorisées. 2
  • Les failles standard ne sont pas autorisées.

Les tests

Les valeurs sont: date | index of the phase | illumination | name

Un cycle lunaire complet:

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

Cas de test aléatoires:

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

Comme la plupart des méthodes ne sont pas précises à un niveau scientifique et que vous obtenez également des résultats mitigés sur différents sites Web pendant quelques jours, il est acceptable que vos résultats se situent dans une plage de ± 1 jour .

Prime

Réduisez votre nombre d'octets et retirez :

  • 15% - Imprime le nom réel de la phase comme indiqué dans la section Sortie au lieu de son index.
  • 25% - Imprimez les dates de la nouvelle et de la pleine lune à venir séparées par un espace ou une nouvelle ligne sur une entrée vide.

1 Par exemple: Phase de calcul sur Wikipédia.
2 Désolé Mathematica .


Mon argent est sur Japt.
lirtosiast

Combien de temps dure chaque phase? Vous vous référez à quatre phases principales d'une durée d'environ 7 jours, mais il y a 8 phases à traiter.
Sherlock9

1
Je pense que pour m'aider à comprendre la durée de chaque phase, pouvez-vous publier un scénario de test d'environ cinq jours consécutifs, ou quel que soit le temps qu'il faut pour passer de, disons, "cire gibbeuse" à "décroissante gibbeuse" selon votre calcul? J'ai des problèmes avec les définitions parce que, par exemple, les quarts de lune sont l' instant de 50% d'éclairage, donc le "premier trimestre" ne devrait être que le jour même, avec "croissant croissant" et "croissant décroissant" les jours précédents et après. Mais je ne suis pas sur.
Sherlock9

Bon alors, je vais commencer ma solution. Merci d'avoir clarifié une partie de cela.
Sherlock9

@ Sherlock9 J'ai mis à jour les cas de test avec un cycle lunaire complet et quelques valeurs aléatoires, y compris l'éclairage de chaque jour. J'espère que cela vous sera utile.
insertusernamehere

Réponses:


3

Python 2 3, 255 204 180 180 178 octets

Cette réponse est inexacte d'un jour ou deux à plusieurs endroits, y compris pour certains des cas de test, même si on m'a dit qu'une certaine inexactitude était acceptable. En tout cas, le mouvement de la lune n'est jamais très exact et cette fonction reste généralement correcte (ou du moins, elle ne varie pas trop).

Edit: Au cours de la correction de mon code et de le rendre plus précis, je l'ai considérablement minimisé.

Edit: Ce code est maintenant un programme Python 3 d'une ligne. (Crédit à TimmyD pour le nom "nombres magiques")

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)

Non golfé:

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 Vous n'avez aucune idée du nombre de nombres magiques que j'ai essayé et jeté pour que cela fonctionne XD
Sherlock9
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.