Calcular a fase lunar


10

Introdução

tl; dr

Neste desafio, você deve calcular a fase da lua para uma determinada data.


Este desafio é inspirado no experimento psicológico social audiovisual do jogo " Superbrothers: Sword & Sworcery EP ". No S: S&S EP, as fases da lua são importantes para o resultado da aventura, pois alguns eventos ocorrem apenas em um momento específico.

Captura de tela do Superbrothers: Sword & Sworcery EP

A questão é: Qual fase lunar está presente em uma data específica. Cada fase principal - da lua nova ao primeiro trimestre da lua cheia ao terceiro trimestre - dura cerca de 7,38 dias. Todo o ciclo lunar é de aproximadamente 29,52 dias. Com base nesses valores, existem vários métodos de cálculo. 1

Entrada

  • Data baseada no calendário gregoriano, entre 1 de janeiro de 1970 e 31 de dezembro de 2116.
  • Você pode escolher um dos seguintes formatos: yyyy-mm-dd, dd.mm.yyyy, dd/mm/yyyy, yyyymmddou ddmmyyyy.

Resultado

Emita o índice [0-7]da fase lunar com base nesta matriz indexada em zero:

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

Exigências

  • Você pode escrever um programa ou uma função. Se você optar por uma função anônima, inclua um exemplo de como invocá-la.
  • A entrada é aceita de STDIN, argumentos de linha de comando, como parâmetros de função ou do equivalente mais próximo.
  • Este é o pelo que a resposta mais curta em bytes vence.
  • Bibliotecas internas ou externas que calculam a fase da lua não são permitidas. 2
  • As brechas padrão não são permitidas.

Testes

Os valores são: date | index of the phase | illumination | name

Um ciclo lunar 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

Casos de teste aleatórios:

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

Como a maioria dos métodos não é precisa para um nível científico e você também obtém resultados variados em sites diferentes por alguns dias, é aceitável se os resultados estiverem dentro de um intervalo de ± 1 dia .

Bônus

Reduza a contagem de bytes e retire :

  • 15% - Imprima o nome real da fase, conforme listado na seção Saída em vez de seu índice.
  • 25% - Imprima as datas da próxima lua nova e cheia, separadas por um espaço em branco ou nova linha na entrada vazia.

1 Por exemplo: Fase de cálculo na Wikipedia.
2 Desculpe, Mathematica .


Meu dinheiro está no Japt.
lirtosiast

Quanto tempo dura cada fase? Você se refere a quatro fases principais, com duração aproximada de 7 dias, mas há 8 fases para lidar.
Sherlock9

11
Penso que, para me ajudar a entender quanto tempo deve durar cada fase, você pode postar um caso de teste de cerca de cinco dias consecutivos, ou o tempo que for necessário para mudar, digamos, de "crescente gibbous" para "minguante gibbous" pelo seu julgamento? Estou tendo problemas com as definições porque, por exemplo, as quarto-luas são o instante de 50% de iluminação, portanto, o "primeiro quarto" deve ocorrer apenas no próprio dia, com "crescente crescente" e "crescente crescente" nos dias anteriores e depois de. Mas eu não tenho certeza.
Sherlock9

Tudo bem então, eu vou começar a minha solução. Obrigado por esclarecer um pouco disso.
Sherlock9

@ Sherlock9 Atualizei os casos de teste com um ciclo lunar completo e alguns valores aleatórios, incluindo a iluminação de cada dia. Espero que isso seja útil.
usar o seguinte comando

Respostas:


3

Python 2 3, 255 204 180 178 bytes

Essa resposta é imprecisa em um dia ou dois em vários lugares, inclusive em alguns casos de teste, embora me disseram que alguma imprecisão era aceitável. De qualquer forma, o movimento da lua nunca é muito exato e essa função geralmente permanece correta (ou pelo menos, não varia muito).

Edit: No curso de corrigir o meu código e torná-lo mais preciso, eu o reduzi consideravelmente.

Edit: Este código agora é um programa Python 3 de uma linha. (Agradecemos a TimmyD pelo nome "números mágicos")

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 Você não tem idéia de quantos números mágicos Eu tentei e jogou para fora para chegar a este XD trabalho
Sherlock9
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.