月相を計算する


10

前書き

tl; dr

この課題では、特定の日付の月の位相を計算する必要があります。


このチャレンジは、ゲームの 心理社会的視聴覚実験Superbrothers:Sword&Sworcery EP」に触発されました。ではS:S&S EP一部のイベントは、時間内の特定のポイントでのみ起こるよう月の段階では冒険の成果にとって重要です。

Superbrothers:Sword&Sworcery EPのスクリーンショット

問題は、特定の日にどの月相が存在するかです。新月から第1四半期、満月から第3四半期までの各主要段階は、約7.38日です。月周期全体はおよそ29.52日です。これらの値に基づいて、さまざまな計算方法が存在します。1

入力

  • 1970年1月1日から2116年12月31日までのグレゴリオ暦に基づく日付。
  • あなたは、次のいずれかの形式を選択することができますyyyy-mm-dddd.mm.yyyydd/mm/yyyyyyyymmddまたは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

ほとんどの方法は科学的なレベルでは正確ではなく、また、この数日間、さまざまなWebサイトで混合結果が得られるため、結果が±1日の範囲内であれば問題ありません。

ボーナス

バイト数を減らして撤回する

  • 15% –セクション出力にリストされているフェーズの実際の名前を、インデックスの代わりに出力します。
  • 25% –空の入力で空白または改行で区切られた次の新月と満月の日付を印刷します。

1例:ウィキペディアの計算フェーズ
2すみませんMathematica


私のお金はJaptにあります。
リルトシアスト

各フェーズはどのくらい続きますか?約7日間続く4つの主要なフェーズを参照しますが、処理するフェーズは8つあります。
Sherlock9

1
各フェーズの所要時間を理解するのに役立つと思いますが、約5日間のテストケースを投稿できますか。たとえば、「ワックスギブス」から「ワンオフギブス」に変化するまでにどのくらい時間がかかりますか。たとえば、四分月は50%の照明の瞬間なので、定義に問題があります。そのため、「第1四半期」当日のみである必要があり、前日と前日に「三日月」と「三日月」が表示されます。あと。確信はないけど。
Sherlock9

それでは、ソリューションを開始します。この問題の一部を解消していただきありがとうございます。
Sherlock9

@ Sherlock9完全な月の周期と、毎日の照明を含むいくつかのランダムな値でテストケースを更新しました。うまくいけば、これは役に立ちます。
insertusernamehere

回答:


3

Pythonの2 3、255の 204 180 178バイト

これは、いくつかのテストケースを含め、いくつかの場所で1〜2日で回答が不正確ですが、ある程度の不正確さは許容できると言われました。とにかく、月の動きはそれほど正確ではなく、この関数は一般的に正しいままです(または、少なくとも、あまり変化しません)。

編集:私のコードを修正してより正確にする過程で、私はかなりそれを徹底的に調べてきました。

編集:このコードは1行の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)

非ゴルフ:

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これをXDで動作させるために何回マジックナンバーを試してみたかわかりません
Sherlock9
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.