Forgotten Realms日付計算機


18

日付ライブラリが組み込まれている言語と組み込まれていない言語の間で競争の場を平準化するために、架空のカレンダーを使用してみましょう。Forgotten Realmsは、Dungeons&Dragonsの(the?)キャンペーン設定です。もちろん、それぞれに独自のカレンダーがあります。

ハプトスのカレンダー

便利なことに、忘れられた領域の1年も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

括弧内に6番目の休日を挿入したことに注意してください。これは4年ごとにのみ発生するうるう日です(はい、そうです-何世紀にもわたって追加のシェナンガンはありません)。

月の名前に関する補足事項:各月には正式名と共通名があります。上記は一般的な名前です。それらを選んだのは、それらがより興味深い圧縮を可能にしていると思うからです。

年の番号付けはいくつかありますが、最も普及しているのはDRに短縮されたDalereckoningです。(また、毎年1つ以上の名前がありますが、それを気にするつもりはありません。)

日付の構成要素は、コンマとスペースで区切る必要があります。全体として、有効な日付は次のようになります。

4, The Melting, 1491 DR

または

Shieldmeet, 1464 DR

休日には日番号がないことに注意してください。(4th of The Melting月の数日間はもっといいと思うが、序数をこの中にドラッグしたくない。)

脚注:日付のすべてのチャレンジにうるう年の計算が必要であるとxnorが不平を言ったとき、私はこれを思いつきました。私はそれを完全に削除することに失敗しましたが、少なくともこのカレンダーではモジュロは1つだけです。

チャレンジ

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はもう1つの主要なD&Dキャンペーン設定です。軌道については、参考書で詳しく説明されている3つの月を除いて、彼らのカレンダーについてはあまり覚えていません。
CJデニス

回答:


5

ルビー、543 523 521 498 511 509バイト

この質問に対するより多くの回答を促すために、Pythonの回答のRubyバージョンを投稿します。この答え短いですが、それほどではありません。もっと良くできますか?

編集:MartinBüttnerと彼の提案に感謝します

編集:「月の日数」リストをかなり下げました。

編集:私はどのように処理したかダウンゴルフ間d[10]=r%4<1?1:0d[10]=0**(r%4)バイトのために、私がダウンしてゴルフをしながら、私はバグを導入しましたのだ気づいdShieldmeetが事故で、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

Python 3、712 652 636 567 563 552 550 548 529 540バイト

最後に、この素​​晴らしい質問に対する答えを書く時間を見つけました。まだあまりゴルフされていません(この場合月名リストと日数リストは特にひどく、ネガを処理Dするためには個別のwhileループが必要です)でも、少なくともそれは答えです。

編集:バグの修正

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"
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.