Калькулятор дати забутих царств


18

Прагнучи вирівняти ігрове поле між мовами із вбудованими бібліотеками дат і без них, давайте попрацюємо з вигаданим календарем. Забуті королівства - це (( ? ) Кампанія для Dungeons & Dragons. Звичайно, у кожного свій календар.

Календар арфов

Зручно, що рік у Забутих Царствах також має 365 днів. Крім того, календар також має 12 місяців. Однак саме тут стає цікаво. Кожен місяць триває рівно 30 днів. Решта 5 днів свята , які потрапляють між місяцями. Ось місяці та відпустки по порядку (з відступними відпусками):

1   Deepwinter
        Midwinter
2   The Claw of Winter
3   The Claw of the Sunsets
4   The Claw of the Storms
        Greengrass
5   The Melting
6   The Time of Flowers
7   Summertide
        Midsummer
        [Shieldmeet]
8   Highsun
9   The Fading
        Highharvestide
10  Leaffall
11  The Rotting
        The Feast of the Moon
12  The Drawing Down

Зауважте, що я вставив шостий відпочинок у дужки. Це високосний день, який відбувається лише кожні чотири роки (так, саме так - немає додаткових шенагіганів із століттями).

Побічна примітка про назви місяців: кожен місяць має офіційну та загальну назву. Вище наведені загальні назви. Я вибрав їх, тому що я думаю, що вони дозволяють отримати більш цікаве стиснення.

Існує кілька нумерацій років, але найпоширенішим є Далеречконінг , скорочений до ДР . (Крім того, кожен рік має одне або більше імен , але ми не збираємося цим займатися.)

Компоненти дати повинні бути розділені комою та пробілом. Загалом, дійсна дата може виглядати так:

4, The Melting, 1491 DR

або

Shieldmeet, 1464 DR

Зауважте, що для свят немає номера дня. (Я вважаю, що 4th of The Meltingбуло б приємніше для днів місяців, але я не хочу перетягувати порядкові числа до цього.)

Виноска: я придумав це, коли xnor поскаржився, що кожен виклик на дату потребує обчислення високосного року. Я не зміг її повністю усунути, але принаймні це лише один модуль у цьому календарі.

Змагання

З огляду на дійсну дату Календаря Harptos, а також ціле число D, виведіть дату Dдні пізніше. Зауважте, що це Dможе бути негативно, і в цьому випадку ви повинні повернути дату на Dдні раніше.

Ви можете написати програму або функцію, взявши введення через STDIN (або найближчу альтернативу), аргумент командного рядка або аргумент функції та вивівши результат через STDOUT (або найближчу альтернативу), значення повернення функції або параметр функції (out).

Ви можете припустити, що рік є позитивним і менше 2000 року.

Діють стандартні правила .

Випробування

Перший десяток тестових випадків повинен перевірити всі кращі випадки, пов’язані зі святами та високосними роками. Наступний набір полягає в тому, щоб перевірити, що діапазон протягом декількох років роботи і всі місяці та канікули були виконані. Друга половина - знову ж тестові випадки, але з негативними компенсаціями.

"30, Summertide, 1491 DR" 1                 => "Midsummer, 1491 DR"
"30, Summertide, 1491 DR" 2                 => "1, Highsun, 1491 DR"
"Midsummer, 1491 DR" 1                      => "1, Highsun, 1491 DR"
"30, Summertide, 1492 DR" 1                 => "Midsummer, 1492 DR"
"30, Summertide, 1492 DR" 2                 => "Shieldmeet, 1492 DR"
"30, Summertide, 1492 DR" 3                 => "1, Highsun, 1492 DR"
"Midsummer, 1492 DR" 1                      => "Shieldmeet, 1492 DR"
"Midsummer, 1492 DR" 2                      => "1, Highsun, 1492 DR"
"Shieldmeet, 1492 DR" 1                     => "1, Highsun, 1492 DR"
"1, Highsun, 1490 DR" 365                   => "1, Highsun, 1491 DR"
"1, Highsun, 1491 DR" 365                   => "Shieldmeet, 1492 DR"
"Shieldmeet, 1492 DR" 365                   => "Midsummer, 1493 DR"
"Midsummer, 1493 DR" 365                    => "Midsummer, 1494 DR"
"Shieldmeet, 1500 DR" 365                   => "Midsummer, 1501 DR"

"14, Deepwinter, 654 DR" 5069               => "The Feast of the Moon, 667 DR"
"Midwinter, 17 DR" 7897                     => "15, The Fading, 38 DR"
"3, The Claw of Winter, 1000 DR" 813        => "25, The Claw of the Storms, 1002 DR"
"Greengrass, 5 DR" 26246                    => "9, The Claw of the Sunsets, 77 DR"
"30, The Melting, 321 DR" 394               => "29, The Time of Flowers, 322 DR"
"17, The Time of Flowers, 867 DR" 13579     => "20, Highsun, 904 DR"
"Highharvestide, 1814 DR" 456               => "30, The Drawing Down, 1815 DR"
"23, The Rotting, 1814 DR" 3616             => "16, Leaffall, 1824 DR"
"1, Deepwinter, 1 DR" 730499                => "30, The Drawing Down, 2000 DR"

"Midsummer, 1491 DR" -1                     => "30, Summertide, 1491 DR"
"1, Highsun, 1491 DR" -2                    => "30, Summertide, 1491 DR"
"1, Highsun, 1491 DR" -1                    => "Midsummer, 1491 DR"
"Midsummer, 1492 DR" -1                     => "30, Summertide, 1492 DR"
"Shieldmeet, 1492 DR" -2                    => "30, Summertide, 1492 DR"
"1, Highsun, 1492 DR" -3                    => "30, Summertide, 1492 DR"
"Shieldmeet, 1492 DR" -1                    => "Midsummer, 1492 DR"
"1, Highsun, 1492 DR" -2                    => "Midsummer, 1492 DR"
"1, Highsun, 1492 DR" -1                    => "Shieldmeet, 1492 DR"
"1, Highsun, 1491 DR" -365                  => "1, Highsun, 1490 DR"
"Shieldmeet, 1492 DR" -365                  => "1, Highsun, 1491 DR"
"Midsummer, 1493 DR" -365                   => "Shieldmeet, 1492 DR"
"Midsummer, 1494 DR" -365                   => "Midsummer, 1493 DR"
"Midsummer, 1501 DR" -365                   => "Shieldmeet, 1500 DR"

"The Feast of the Moon, 667 DR" -5069       => "14, Deepwinter, 654 DR"
"15, The Fading, 38 DR" -7897               => "Midwinter, 17 DR"
"25, The Claw of the Storms, 1002 DR" -813  => "3, The Claw of Winter, 1000 DR"
"9, The Claw of the Sunsets, 77 DR" -26246  => "Greengrass, 5 DR"
"29, The Time of Flowers, 322 DR" -394      => "30, The Melting, 321 DR"
"20, Highsun, 904 DR" -13579                => "17, The Time of Flowers, 867 DR"
"30, The Drawing Down, 1815 DR" -456        => "Highharvestide, 1814 DR"
"16, Leaffall, 1824 DR" -3616               => "23, The Rotting, 1814 DR"
"30, The Drawing Down, 2000 DR" -730499     => "1, Deepwinter, 1 DR"

1
DragonLance - ще одна велика настройка науково-дослідної кампанії. Я не можу пригадати багато їхнього календаря, за винятком їх трьох лун, орбіти яких були детально пояснені в деякому довіднику.
CJ Dennis

Відповіді:


5

Рубі, 543 523 521 498 511 509 байт

Щоб заохотити більше відповідей на це запитання, я збираюся опублікувати рубінову версію моєї відповіді Python, оскільки я вважав, що вона буде коротшою. Ця відповідь є коротше , але не набагато. Чи можете ви зробити краще?

Редагувати: Завдяки Мартіну Бюттнеру та його пропозиціям тут .

Редагувати: Я суттєво знизив список "кількість днів у місяці".

Edit: В той час як гра в гольф вниз , як я звертався d[10]=r%4<1?1:0до d[10]=0**(r%4)за байтом, я помітив , що я ввів помилку в той час як гра в гольф вниз d, кількість списку днів, так що Шілдміт було 30 днів випадково. І ось, кількість байтів повернулася. Я також відредагую відповідь Python, щоб виправити цю помилку там.

Редагувати: я забув, що функції в цьому питанні не потрібно називати.

->s,n{x=s[0..-4].split(", ");x=x[2]?x:[1,*x];t=(["Deepwinter,Midwinter","Winter","Sunsets","the Storms,Greengrass,The Melting,The Time of Flowers,Summertide,Midsummer,Shieldmeet,Highsun,The Fading,Highharvestide,Leaffall,The Rotting,The Feast of the Moon,The Drawing Down"]*',The Claw of ').split(?,);p,q,r=x[0].to_i+n,t.index(x[1]),x[2].to_i;d=[30,1,30,30]*4+[1,30];d[10]=0**(r%4);(a=p<1?1:-1;q=(q-a)%18;p+=a*d[a<0?q-1:q];r-=a*0**q;d[10]=0**(r%4))until(1..d[q])===p;z=d[q]<2?[t[q],r]:[p,t[q],r];z*", "+" DR"}

Безголівки:

def h(s,n)
  x=s[0..-4].split(", ")
  x=x[2]?x:[1,*x]
  t=["Deepwinter,Midwinter","Winter","Sunsets","the Storms,Greengrass,The Melting,The Time of Flowers,Summertide,Midsummer,Shieldmeet,Highsun,The Fading,Highharvestide,Leaffall,The Rotting,The Feast of the Moon,The Drawing Down"]
  t=t*',The Claw of '           # turns the above array into a string with "Claw"s inserted
  t=t.split(?,)                 # then splits that string back up again by ","
  p=x[0].to_i+n
  q=t.index(x[1])
  r=x[2].to_i
  d=[30,1,30,30]*4+[1,30]
  d[10]=0**(r%4)
  until(1..d[q])===p
    a=p<1?1:-1
    q=(q-a)%18
    p+=a*d[a<0?q-1:q]
    r-=a*0**q
    d[10]=0**(r%4)
  end
  z=d[q]<2?[t[q],r]:[p,t[q],r]  # putting z=[t[q],r] on another line saved me no bytes
  z*", "+" DR"
end

5

Пітон 3, 712 652 636 567 563 552 550 548 529 540 байт

Нарешті я знайшов час написати відповідь на це відмінне запитання. Це ще не дуже гольф (перелік назв місяця та кількість днів у цьому випадку особливо жахливий , і той факт, що для обробки негативу Dпотрібен окремий цикл ), але принаймні це відповідь.

Редагувати: виправлення помилки

def h(s,n):
 x=s[:-3].split(", ");x=[1]*(len(x)<3)+x;t="Deepwinter,Midwinter,The Claw of Winter,The Claw of the Sunsets,The Claw of the Storms,Greengrass,The Melting,The Time of Flowers,Summertide,Midsummer,Shieldmeet,Highsun,The Fading,Highharvestide,Leaffall,The Rotting,The Feast of the Moon,The Drawing Down".split(",");p,q,r=int(x[0])+n,t.index(x[1]),int(x[2]);d=[30,1,30,30]*4+[1,30];d[10]=r%4<1
 while p>d[q]or p<1:a=[-1,1][p<1];q=(q-a)%18;p+=a*d[q-(a<0)];r-=a*0**q;d[10]=r%4<1
 return', '.join([str(p)]*(d[q]>2)+[t[q],str(r)])+" DR"

Безголівки:

def harptos(date, num):
    t = "Deepwinter,Midwinter,The Claw of Winter,The Claw of the Sunsets,The Claw of the Storms,Greengrass,The Melting,The Time of Flowers,Summertide,Midsummer,Shieldmeet,Highsun,The Fading,Highharvestide,Leaffall,The Rotting,The Feast of the Moon,The Drawing Down"
    t = t.split(",")        # split up the names of the months
    x = date[:-3]           # removes " DR"
    x = x.split(", ")
    if len(x) < 3:
        x = [1] + x         # if we have two items (holiday), append a "day of the month"
    p = int(x[0]) + num     # initialize the "date" by adding num to it
    q = t.index(x[1])
    r = int(x[2])
    d=[30,1,30,30]*4+[1,30] # all the month lengths
    d[10] = r%4 < 1         # leap year toggle
    while p > d[q]:         # while the "date" > the number of days in the current month
        p -= d[q]           # decrement by number of days in current month
        q = (q+1)%18        # increment month
        r += 0**q           # increment year if the incremented month == the first month
        d[10] = r%4 < 1     # leap year toggle
    while p < 1:            # while the "date" is negative
        q = (q-1)%18        # decrement month first
        p += d[q]           # add the number of days in the decremented month
        r -= 0**q            # decrement year if the decremented month == the first month
        d[10] = r%4 < 1     # leap year toggle
    m = [t[q],str(r)]       # start the result array
    if d[q] > 2:
        m = [str(p)] + m    # if the month is NOT a holiday, add the day
    return ", ".join(m) + " DR"
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.