Рассчитайте лунную фазу

10

Введение

ТЛ; др

В этом испытании вы должны рассчитать фазу луны на заданную дату.


Эта задача вдохновлена игровым психосоциальным аудиовизуальным экспериментом " Superbrothers: Sword & Sworcery EP ". В S: S & S EP фазы луны важны для исхода приключения, поскольку некоторые события происходят только в определенный момент времени.

Снимок экрана от Superbrothers: Sword & Sworcery EP

Вопрос в том, какая лунная фаза присутствует в конкретную дату. Каждая основная фаза - от новолуния до первой четверти, от полнолуния до третьей четверти - длится около 7,38 дней. Весь лунный цикл составляет примерно 29,52 дня. На основании этих значений существуют различные методы расчета. 1

вход

  • Дата, основанная на григорианском календаре, между 1 января 1970 года и 31 декабря 2116 года.
  • Вы можете выбрать один из следующих форматов: yyyy-mm-dd, dd.mm.yyyy, dd/mm/yyyy, yyyymmddили ddmmyyyy.

Вывод

Выведите индекс [0-7]лунной фазы на основе этого массива с нулевым индексом:

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

Требования

  • Вы можете написать программу или функцию. Если вы используете анонимную функцию, приведите пример того, как ее вызвать.
  • Ввод принимается из STDINаргументов командной строки, в качестве параметров функции или из ближайшего аналога.
  • Это поэтому выигрывает самый короткий ответ в байтах.
  • Встроенные модули или внешние библиотеки, которые рассчитывают фазу луны, не допускаются. 2
  • Стандартные лазейки запрещены.

тесты

Значения: date | index of the phase | illumination | name

Полный лунный цикл:

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

Случайные тестовые случаи:

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

Поскольку большинство методов не являются точными для научного уровня, и вы также получаете смешанные результаты на разных веб-сайтах в течение пары дней, допустимо, если ваши результаты находятся в пределах ± 1 дня .

бонус

Уменьшите количество байтов и снимите :

  • 15% - Напечатайте фактическое имя фазы, как указано в разделе « Вывод», вместо ее индекса.
  • 25% - печатать даты предстоящего новолуния и полной луны, разделенные пробелом или новой строкой, на пустом вводе.

1 Например: Расчет фазы в Википедии.
2 Извините, Математика .

insertusernamehere
источник
Мои деньги на Джапте.
lirtosiast
Как долго длится каждая фаза? Вы имеете в виду четыре основных этапа продолжительностью около 7 дней, но есть 8 этапов, которые необходимо решить.
Sherlock9
1
Я думаю, чтобы помочь мне понять, как долго должна длиться каждая фаза, можете ли вы опубликовать контрольный пример продолжительностью около пяти дней подряд, или сколько времени потребуется, чтобы перейти от, скажем, «растущего гиббуса» к «убывающему гиббозу» по вашим расчетам? У меня возникают проблемы с определениями, потому что, например, четверть луны - это момент 50% освещения, поэтому «первая четверть» должна быть только в день, с «растущим полумесяцем» и «убывающим полумесяцем» в предыдущие дни и после. Но я не уверен.
Sherlock9
Хорошо, тогда я начну с моего решения. Спасибо за разъяснение некоторых из этого.
Sherlock9
@ Sherlock9 Я обновил контрольные примеры с полным лунным циклом и некоторыми случайными значениями, включая освещенность каждого дня. Надеюсь, это полезно.
insertusername здесь

Ответы:

3

Python 2 3, 255 204 180 178 байт

Это ответ является неточным в течение одного или двух дней в нескольких местах, в том числе для некоторых тестовых случаев, хотя мне сказали, что некоторая неточность была приемлемой. Во всяком случае, движение луны никогда не бывает очень точным, и эта функция в целом остается правильной (или, по крайней мере, она не изменяется слишком далеко).

Редактировать: в процессе исправления моего кода и повышения его точности я значительно улучшил его.

Редактировать: Этот код теперь является однострочной программой Python 3. ( Благодарим TimmyD за название "магические числа")

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
источник
@TimmyD Вы не представляете, сколько магических чисел я попробовал и выбросил, чтобы заставить это работать XD
Sherlock9