展期日历


17

这是受到Downgoat在Sandbox中提出的问题之一启发的,我建议他将使用日/月格式的用户将4月31日作为Pi日,只是让他通知我没有4月31日!

给定日期字符串(可能是无效的月/日格式),请使用过渡输出正确的日期。(首先将月份展期,然后将一天展期)。

例子:

“ 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” -一年有365天。99999(mod 365)=354。一年的354天是“ 12/20”

“ 9999999/10” -显然,9999999(mod 12)= 3,所以它是“ 3/10”(3月10日)。

条件:

输入月份是大于0的整数。输入日期是大于0的整数。不需要指定年份,因为没有leap年需要处理。

更新:

我认为这会过分简化挑战,因此禁止使用日历功能(例如Java Calendar类中的日历功能)。尽管日期解析/格式化功能仍然允许。



1
另一个重要的测试用例是具有足够的天数可以滚动8年以上的用例,因此使用内置的答案必须注意使用leap年的内置。
马丁·恩德

哦,那个答案...我正要发布一个使用内置的Mathematica答案。:/
马丁·恩德

@马丁对此表示抱歉;)。
geokavel

作为参考,Mathematica解决方案仍为90字节长(尽管在很大程度上由字符串处理所支配)。但是,如果您想添加这样的测试用例,1/99999应该12/19考虑一下。
马丁·恩德

Answers:



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 *而不是参数中的字符串。
Eumel 2015年

在某些测试用例(例如)上,此操作失败24/1
LegionMammal978 2015年

@Eumel谢谢!直接打印Console.Write大于的使用return,在C#中,我将使用char[]代替string,但是它是相同数量的字符,这使得分割/更麻烦。但是,您在词典中的注释确实使我获得了更好的版本!
DrewJordan

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 2015年

奇怪我稍后再检查
Tensibai

我也收到了此消息。您的程序似乎在几个月中出现了问题。否则它正在运行。pastebin.com/g3BCUDi8
geokavel 2015年

感谢您的反馈。我实际上在路上,我会纠正它
Tensibai 2015年

1
@Tensibai是的,您是对的,我不好(我应该记得错误消息说它期望“真实”)。
plannapus 2015年

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都会拒绝对其进行解析并返回错误(可能出于某些任意原因)。因此,具有此答案的理论是将其返回到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],现在可以从命令行输入中读取。
尼克

OP的输入说明要求无关紧要;我们有一个默认的可接受的I / O方法列表(我已链接了该方法),因此挑战作者不必在每个挑战中都指定它们。
Mego 2015年

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,因此其功能完全相同。我猜这是一个没有竞争力的答案:(
Digital Trauma
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.