Unutulmuş Diyarlar tarih hesaplayıcısı


18

Yerleşik tarih kütüphaneleri olan ve olmayan diller arasındaki oyun alanını dengelemek için kurgusal bir takvim ile çalışalım. Unutulmuş Diyarlar, Zindanlar ve Ejderhalar için bir ( ? ) Kampanya ayarıdır. Tabii ki, her birinin kendi takvimi var.

Harptos'un Takvimi

Uygun bir şekilde, Unutulmuş Diyarlarda bir yılda 365 gün var. Ayrıca takvimin de 12 ayı var. Ancak, burada ilginç olur. Her ay tam olarak 30 gün sürüyor. Kalan 5 gün , aylar arasında kalan tatillerdir . İşte aylar ve tatiller sırayla (tatiller girintili olarak):

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

Köşeli parantez içinde altıncı bir tatil yaptığım dikkat edin. Bu sadece dört yılda bir gerçekleşen artık gündür (evet, işte bu - yüzyıllar boyunca ek shenanigans yoktur).

Ay adları hakkında yan not: her ayın resmi ve ortak bir adı vardır. Yukarıdaki ortak isimlerdir. Bunları seçtim çünkü daha ilginç bir sıkıştırmaya izin verdiklerini düşünüyorum.

Orada yıllardır çeşitli numberings vardır, ama en yaygın biridir Dalereckoning kısaltılır, DR . (Ayrıca, her yıl bir veya daha fazla isim var , ancak bununla uğraşmayacağız.)

Bir tarihin bileşenleri virgül ve boşlukla ayrılmalıdır. Sonuç olarak, geçerli bir tarih şöyle görünebilir:

4, The Melting, 1491 DR

veya

Shieldmeet, 1464 DR

Tatil gün sayısı yoktur. (Sanırım 4th of The Meltingayların günleri için daha iyi olurdu, ancak sıra sayılarını buna sürüklemek istemiyorum.)

Dipnot: Xnor, her bir tarih mücadelesinin artık yıl hesaplamasına ihtiyaç duyduğundan şikayet ettiğinde bunu buldum. Tamamen ortadan kaldırmakta başarısız oldum, ama en azından bu takvimdeki tek bir modülo.

Meydan okuma

Harptos Takviminin geçerli bir tarihi ve bir tamsayı verildiğinde, günler sonraki Dtarihi çıktılar D. Bunun Dnegatif olabileceğini unutmayın; bu durumda tarih Dgünlerini daha önce iade etmelisiniz .

STDIN (veya en yakın alternatif), komut satırı bağımsız değişkeni veya işlev bağımsız değişkeni ile girdi alarak ve sonucu STDOUT (veya en yakın alternatif), işlev dönüş değeri veya işlev (çıkış) parametresi aracılığıyla çıktı alarak bir program veya işlev yazabilirsiniz.

Yılın olumlu ve 2000'den az olduğunu varsayabilirsiniz.

Standart kuralları geçerlidir.

Test Durumları

İlk düzine kadar test vakası tatilleri ve artık yılları çevreleyen tüm uç vakaları test etmelidir. Bir sonraki set, çok yıllı çalışmalarda ve tüm aylarda ve tatillerin uygulandığını test etmek. İkinci yarı yine aynı test vakalarıdır, ancak negatif ofsetlerle.

"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, bir başka önemli AR&GE kampanyasıdır. Yörüngeleri bazı referans kitaplarında ayrıntılı olarak açıklanan üç ayı dışında takvimleri hakkında çok fazla hatırlayamıyorum.
CJ Dennis

Yanıtlar:


5

Yakut, 543 523 521 498 511 509 bayt

Bu soruya daha fazla cevap verebilmek için, daha kısa olacağını düşündüğümden Python cevabımın Ruby versiyonunu yayınlayacağım. Bu cevap daha kısa ama çok değil. Daha iyisini yapabilir misin ?

Düzenleme: için teşekkür grubu Martin Büttner ve onun önerisi burada .

Düzenleme: Ben önemli bir "aşağı gün sayısı" listesini golf.

Düzenleme: Ben nasıl ele aşağı golf iken d[10]=r%4<1?1:0için d[10]=0**(r%4)bir byte için, aşağı golf ederken bir hata tanıtıldı etmişti fark dShieldmeet kazara 30 gün vardı ki, günler listesinin sayısını. Ve böylece bayt sayımı geri geldi. Ayrıca bu hatayı düzeltmek için Python cevabını düzenleyeceğim.

Düzenleme: İşlevlerin bu soruda adlandırılması gerekmediğini unuttum.

->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"}

Ungolfed:

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

Python 3, 712 652 636 567 563 552 550 548 529 540 bayt

Sonunda, bu mükemmel soruya cevap yazmak için zaman buldum. Henüz çok golf değil (ay isimleri listesi ve gün sayısı listesi bu durumda özellikle berbattır ve negatif işlemenin Dayrı bir while döngüsü gerektirmesi gerçeği ), ancak en azından bir cevaptır.

Düzenleme: Bir hatayı düzeltme

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"

Ungolfed:

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"
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.