คำนวณระยะทางจันทรคติ


10

บทนำ

TL; DR

ในการท้าทายนี้คุณจะต้องคำนวณระยะดวงจันทร์สำหรับวันที่กำหนด


ความท้าทายนี้ได้รับแรงบันดาลใจจากการทดลองโสตทัศนูปกรณ์เกม จิตวิทยา " 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, หรือyyyymmddddmmyyyy

เอาท์พุต

เอาต์พุตดัชนี[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ตัวอย่าง: การคำนวณเฟสบน Wikipedia
2ขออภัยMathematica


เงินของฉันอยู่ที่ Japt
lirtosiast

แต่ละเฟสใช้เวลานานเท่าใด คุณอ้างถึงสี่ขั้นตอนหลักยาวนานประมาณ 7 วัน แต่มี 8 ขั้นตอนที่ต้องจัดการ
Sherlock9

1
ฉันคิดว่าจะช่วยให้ฉันเข้าใจว่าแต่ละเฟสควรจะนานแค่ไหนคุณสามารถโพสต์กรณีทดสอบประมาณห้าวันติดต่อกันหรือนานกว่านั้นต้องเปลี่ยนจากพูดว่า "แว็กซ์ gibbous" เป็น "แรม gibbous" โดยการคำนวณของคุณ? ฉันกำลังมีปัญหากับคำจำกัดความเนื่องจากตัวอย่างเช่นดวงจันทร์ของควอเตอร์เป็นแสงสว่างทันที 50% ดังนั้น "ไตรมาสแรก" ควรอยู่ในวันเดียวเท่านั้นด้วย "จันทร์เสี้ยว" และ "จันทร์เสี้ยวจันทร์" ในวันก่อนและ หลังจาก. แต่ฉันไม่แน่ใจ.
Sherlock9

เอาล่ะฉันจะเริ่มแก้ปัญหาของฉัน ขอขอบคุณที่ล้างข้อมูลบางส่วน
Sherlock9

@ Sherlock9 ฉันได้อัปเดตกรณีทดสอบด้วยรอบดวงจันทร์เต็มและค่าสุ่มรวมถึงการส่องสว่างของแต่ละวัน หวังว่านี่จะเป็นประโยชน์
แทรกชื่อที่นี่

คำตอบ:


3

Python 2 3, 255 204 180 178 ไบต์

คำตอบนี้ไม่ถูกต้องในหนึ่งหรือสองวันในหลาย ๆ แห่งรวมถึงกรณีทดสอบบางกรณีถึงแม้ว่าฉันได้รับแจ้งว่ามีความไม่ถูกต้องบางอย่างที่ยอมรับได้ การเคลื่อนไหวของดวงจันทร์ไม่แน่นอนมากและฟังก์ชั่นนี้จะยังคงถูกต้อง (หรืออย่างน้อยก็ไม่แตกต่างกันมากเกินไป)

แก้ไข:ในระหว่างการแก้ไขรหัสของฉันและทำให้มันแม่นยำยิ่งขึ้นฉันได้ทำการวางลงอย่างมาก

แก้ไข:รหัสนี้เป็นโปรแกรม Python 3 แบบบรรทัดเดียว (มอบเครดิตให้TimmyDสำหรับชื่อ "magic numbers")

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 คุณไม่รู้หรอกว่าฉันได้ลองใช้เวทมนตร์จำนวนเท่าไหร่และโยนมันออกไปทำงาน XD
Sherlock9
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.