ロールオーバーカレンダー


17

これは、SandboxのDowngoatの質問の1つに触発され、日/月形式を使用する人には4月31日をPi日として含めることを提案しました。

日付文字列を 無効な月/日形式の指定すると、ロールオーバーを使用して正しい日付を出力します。(最初に月をロールオーバーし、次に日をロールオーバーします)。

例:

「15/43」 -これは、15か月目の43日目と読みます。最初に、月を翌年に繰り越すため、最終的に3(3月)になります。現在、3月は31日しかないため、余分な日を4月にロールオーバーし、実際の日付を「4/12」として出力します(4月12日)ます。

「3/16」 -これは有効な日付です(3月16日)。そのまま返してください。

「12/64」は -ああ、非常に多くの思い出12月第64回から... 12月31日を持って、1月には、私は本当に平均であるので、どのような31日間、持っている「2/2」(2月2日)を。

「19/99」 -最初に、19は7(7月)になります。7月には31日、8月には31日、9月には30日があるため、出力は「10/7」(10月7日)です。

「1/99999」 -1年は365日です。99999(mod 365)=354。年の354日は"12/20"です。

"9999999/10" -どうやら、9999999(mod 12)= 3なので、これは"3/10"(3月10日)です。

基準:

入力月は0より大きい整数です。入力日は0より大きい整数です。処理するうるう年がないため、年を指定する必要はありません。

更新:

私はそれが挑戦を過度に単純化すると思うので、Java Calendarクラスにあるようなカレンダー機能は禁止されています。ただし、日付の解析/書式設定機能は引き続き使用できます。



1
もう1つの重要なテストケースは、8年以上のロールオーバーに十分な日数があるもので、組み込みを使用する回答はうるう年を使用する組み込みに注意を払う必要があります。
マーティンエンダー

ああ、それは答えです...組み込みのを使用するMathematicaの答えを投稿しようとしていました。:/
マーティンエンダー

@Martinそれについてすみません;)。
geokavel

参考までに、Mathematicaソリューションの長さはまだ90バイトでした(ただし、文字列処理が大部分を占めていました)。それでもこのようなテストケースを追加したい場合1/99999は、12/19私が思うに得られるはずです。
マーティンエンダー

回答:


11

早かった。
アディソンクランプ

ここでカレンダー機能が使用されていないことを保証できますか?
geokavel

LabVIEWの良いところは、基本的に見た目が良いことです。まず、ストリング2モジュロから数値をスキャンします。ボックスは、28、30、または31を出力するスイッチケース構造で、その後再びストリングとしてまとめられます。
ユーメル

4

C#、269 223

string v(string n){var x=new[]{31,28,31,30,31,30,31,31,30,31,30,31};var s=n.Split('/');Func<string,int> p=int.Parse;var m=p(s[0]);var d=p(s[1]);m=m>=12?m%12:m;while(d>x[m]){d-=x[m];m=++m>=12?m%12:m;}return(m==0?1:m)+"/"+d;}

編集:24 / 1、36 / 1などのケースで動作するように修正され、少しゴルフをしました。コメントをありがとう、私が少し節約した場所がいくつかあります!

ゴルフをしていない:

string v(string n)
{
    var x = new [] { 31 ,28, 31, 30, 31, 30,31, 31, 30, 31, 30, 31 };

    var s = n.Split('/');
    Func<string,int> p = int.Parse;
    var m = p(s[0]);
    var d = p(s[1]);
    m = m >= 12 ? m % 12 : m;
    while (d > x[m])
    {
        d -= x[m];
        m = ++m >= 12 ? m % 12 : m;
    }
    return (m==0?1:m) + "/" + d;
}

まず第一に:コミュニティへようこそ!辞書をループで割り当てるか、スイッチ関数を使用することで、バイト数を節約できると思います(ただし、C#proはありません)。´m + "/" + d´を直接印刷することも少し役立つかもしれません。そして最後に(これは機能する場合と機能しない場合があります)引数に文字列ではなくchar *を使用します。
ユーメル

これは、特定のテストケースで失敗します24/1
LegionMammal978

@Eumelありがとう!直接印刷Console.Writeではを超えて使用しますがreturn、C#ではchar[]の代わりに使用しますstringが、同じ量の文字であり、分割が/より問題になります。しかし、辞書に関するあなたのメモは、私をより良いバージョンに導いた!
ドリュージョーダン

4

R、208 182バイト

m=c(31,28,31,30,31,30,31,31,30,31,30,31)
e=scan(sep="/");n=(e[1]/12-1)*12;if(!n%%12)n=12;if(n<0)n=e[1];j=e[2];while((j<-j-m[n])>0){n=n+1;if(n>12)n=1};j=m[n]+j;cat(n,j,sep="/")

12で割って月を取得し、ループして、負の数になるまで現在の月の日数を削除します。最後のステップを逆にして印刷します。

複数行(ファイルを使用してソースを作成する必要があります):

m=c(31,28,31,30,31,30,31,31,30,31,30,31)
e=scan(sep="/")
n=(e[1]/12-1)*12
if(!n%%12)n=12
if(n<0)n=e[1]
j=e[2]
while((j<-j-m[n])>0){n=n+1;if(n>12)n=1}
j=m[n]+j;cat(n,j,sep="/")

これはRでプログラムを実行しようとしたとき、私が得るメッセージです:pastebin.com/dPh1n64a
geokavel

奇妙な私は後で再確認します
Tensibai

私もこのメッセージを受け取りました。あなたのプログラムは数ヶ月で問題を抱えているようです。それ以外の場合は実行中です。pastebin.com/g3BCUDi8
geokavel

フィードバックをお寄せいただきありがとうございます。私は実際に道路にいます、私はそれを修正します
天柴

1
@Tensibaiはい、あなたは正しいです、私は悪いです(エラーメッセージが「本当」を期待していることを覚えているはずです)。
plannapus

3

PHP> = 5.5、181バイト

list($m,$d)=explode("/",$argv[1]);$m%=12;$d%=365;$i=0;while($d>100)$d-=[31,28,31,30,31,30,31,31,30,31,30,31][$i++];$m+=$i;echo date_create_from_format("m/d","$m/$d")->format("n/j");

PHP は、日付の解析とフォーマットの指示だけでのロールオーバーをほぼサポートしています。例えば:

echo date_create_from_format("m/d","12/64")->format("n/j"); // Output: 2/2

ただし、いずれかの数値が100を超えると、PHPは解析を拒否し、エラーを返します(おそらく何らかのarbitrary意的な理由により)。したがって、この答えの理論は、PHPが解析する場所に戻って、それを提出することですdate_create_from_format()です。

ゴルフをしていない:

list($month, $day) = explode("/", $argv[1]);
$month = $month % 12;
$day = $day % 365;
$i = 0;
$days = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
while($day > 31) $day -= $days[$i++];
$month += $i;
echo DateTime::createFromFormat("m/d", $month . "/" . $day)->format("n/j");

オンラインで試す


1
日付文字列を入力する方法、または関数にする方法を教えてください。
geokavel

GETパラメーターは、PHPの入力メソッドとして受け入れられません。これを関数にして、入力を関数パラメーターとして渡すか、$argvまたはSTDIN から入力を取得する必要があります。
Mego

@Mego Jeeze、OPには入力の要件が明記されていないため、回答を更新する時間を与えてください。変更$tするのは簡単で$argv[1]、コマンドライン入力から読み取るようになりました。
nickb

入力に関するOP記述要件は無関係です。チャレンジの作成者がすべてのチャレンジでそれらを指定する必要がないように、デフォルトの受け入れ可能なI / Oメソッドのリストがあります(リンクしました)。
メゴ

2

JavaScript(ES6)、106バイト

s=>eval('q="030101001010";p=s.split`/`;for(d=i=p[1],m=p[0]-1;i--;d>n&&(m++,d-=n))n=31-q[m%=12];m+1+"/"+d')

説明

s=>
  eval(`              // use eval to enable for loop without needing to write {} or return
    q="030101001010"; // q = array of 31 - days in each month
    p=s.split\`/\`;   // p = array of [ month, day ]
    for(
      d=i=p[1],       // d = day
        m=p[0]-1;     // m = month - 1
      i--;            // loop for each day, this is more iterations than needed but extra
                      //     iterations do not affect the result and it's the shortest way
                      //     to guarantee all months have been subtracted from d, it also
                      //     ensures the loop runs at least once to get m % 12
      d>n&&(m++,d-=n) // if too many days, subtract the month's days and increment month
    )
      n=31-q[m%=12];  // n = number of days in month, get m % 12
    m+1+"/"+d         // return the result
  `)

テスト


1

競合しない答え-Bash + coreutils、55

date -d1-$[(${1%/*}-1)%12+1]-1+$[${1#*/}-1]day +%-m/%-d

「日付の解析/フォーマット関数はまだ許可されています」 -これは、dateユーティリティが許可されることをます。

入力はコマンドラインから読み込まれます。例:

$ ./rollovercal.sh 15/43
4/12
$ 

dateコマンドは次のように展開され、日数が追加されるため、これは競合しません。

date -d1-3-1+42day +%-m/%-d

date.add(875)日付を875日間増やすようなことをしていない限り許可されます。それは主に私が望んでいたことです。
geokavel

@geokavelああ、なるほど。ここで完全に展開されたdateコマンドはdate -d1-3-1+42day +%-m/%-dですので、まさにそれを行います。私はこれが競合しない答えだと思う:(
デジタル外傷
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.