我的牛奶过期了吗?


98

噢,伙计,这个有效期不会用字母写月份!我不知道它是即将于3月10日或10月3日...等等,没有,没关系,今年说2012年(空中接力半使用的奶酪砖到垃圾桶可以像亲)

因此,让我们假设一下,您太忙了,无法尝试推断出这罐marinara应该何时过期。您只需要Cliff Notes版本:过期的可能性有多大?让我们写一些代码!

您知道制造商以以下三种格式之一将日期打印为整数的有序三元组:

YEAR  MONTH DAY
MONTH DAY   YEAR
DAY   MONTH YEAR

而且您知道某些日期只能用一种或两种方式来解释,而不能全部用三种方式来解释:55 55-11-5年份必须是一年,这意味着Twinkies的特殊包装盒已于1955年11月5日到期。年份有时用四位数字表示,而不是两个,可以排除一些选择。如果是两位数,则50..99表示1950..1999,0..49表示2000..2049。

您的工作是编写一个程序或函数,该程序或函数采用一个整数数组,在上述至少一种解释中,该整数是一个有效日期,并输出百分比表示还好。机会百分数只是在今天或之后的日期的有效解释日期的百分比。

如果整数数组是函数[Int]的参数,则它将是您语言的长度为3 的类型,并且如果用作STDIN上的输入,则以破折号,斜杠或以空格分隔(您可以选择)的整数形式给出完整程序。*

“今天的日期”可以是通过日期函数获得的今天的实际日期,也可以是STDIN中函数的额外参数或额外参数中给出的日期。可能以Unix纪元为单位,以上述三种方式之一输入另一个年月日三元组,或者以另一种更方便的方式输入。

让我们举一些例子!输入的到期日期将使用短划线分隔,并假设下面的示例今天的日期为2006年7月5日。

  • 14-12-14-对此的两种有效解释(DMY和YMD)都是等效的,2014年12月14日。输出为100,因为此产品绝对仍然不错。
  • 8-2-2006-当然,最后一个数字是一年,因为它有四个数字。可能是2月8日(过期)或8月2日(仍然良好)。输出为50
  • 6-7-5-可能是任何东西!“ 2006年7月5日”的解释仍然很好(仅一天),但是其余两个都在2005年,应该尽快抛弃。输出为33
  • 6-5-7-在这里,三分之二的解释是安全的。您可以向上或向下舍入小数,因此6667都可以。
  • 12-31-99-好的,这是世纪之交的明确定义(从50到99的年份是19XX,而31不可能是一个月)。大脂肪0,您确实应该更频繁地清洁冰箱。

您可以放心地假设任何不符合上述标准的输入都不属于上述输出规则。

没有网络请求或标准漏洞。允许使用日期处理库。这就是代码高尔夫:可能会以最短的程序获胜。

* 如果使用的是Brainfuck或类似的数据类型残障语言,则可以假定输入中前三个字符的ASCII值是日期的整数。当然,这不包括四位数的年份逻辑,但是我认为在Brainfuck上看到针对此问题的解决方案以至于对您不满意,我们会感到惊讶。


39
嗯...当前年份是2014年,而不是2006年。您的牛奶最多只能过期八年。
约翰·德沃夏克

11
@JanDvorak我只是不想非常努力地构造有意义的示例,所以我调整了今天的日期以使其变得更容易。
algorithmhark

7
@ Dgrin91不在乎,我仍然会吃掉它们:D
aditsu

6
在澳大利亚,牛奶会在使用日期之前一周左右过期
ni小贩(Gnibbler)2014年

5
您应该添加一个带有00的测试,因为这不能是合法的日期或月份。
MtnViewMark 2014年

Answers:


5

k4 (90) (88) (87)(82)

{100*(+/~d<x)%3-+/^d:{"D"$"."/:$|z,y,x+(x<100)*100*19+x<50}.'y@/:3 3#.:'$21020101}

调用x.z.D(内置)与今天进行比较,否则,请选择您选择的日期文字:

  f:{100*(+/~d<x)%3-+/^d:{"D"$"."/:$|z,y,x+(x<100)*100*19+x<50}.'y@/:3 3#.:'$21020101}
  .z.D f'(14 12 14;8 2 2006;6 7 5;6 5 7;12 31 99)
100 0 0 0 0f
  2006.07.05 f'(14 12 14;8 2 2006;6 7 5;6 5 7;12 31 99)
100 50 33.33333 66.66667 0

这基本上是@ Alex-l的Python解决方案的一部分,并添加了一些其他的高尔夫技巧:

  • 重排指令编码为字符串以节省几个字符。
  • 条件逻辑(ab)使用“真值整数”(但与Python解决方案不同)。
  • 有效性测试略有不同-k4 / q会愉快地将任何字符串解析为任何数据类型;如果它没有意义,它只会返回null。因此,我从内部函数返回了一个日期列表,该列表可以为null,也可以不为null。
  • 最终结果来自检查多少种可能的日期解释为空以及有多少种少于比较日期。在此重要的是,将空日期视为小于任何其他日期。

1
您可以通过从中删除最后一个0来保存char "012201210",因为#它周期性地获取其项目。实际上,您可以通过交换后两种情况来保存第二个字符:3 3#.:'"0122102"
algorithmhark

通过反转内部函数的args来剃除一个char,保存括号(但添加一个反向字符)。谁能帮我节省另外两个字符?APL打我!
亚伦·戴维斯

最后,通过重写数学将剃光次数减少了五个。回到领先!
亚伦·戴维斯

而且,如果我弯腰写严重的非功能性代码,那么可以通过污染全局名称空间来剃掉另一个字节:{c*(+/~d<x)%3-+/^d:{"D"$"."/:$|z,y,x+(c*19+x<50)*x<c::100}.'y@/:3 3#.:'$21020101}
亚伦·戴维斯

14

Ruby,115个字符

f=->a,t{[a,a.rotate(~s=r=0),a.reverse].map{|x,*y|(t>Time.gm(x<100?x+2e3-100*x/=50:x,*y)||r+=100
s+=1)rescue p}
r/s}

这定义了一个带有f两个参数的函数:一个包含输入的数组,以及“今天”的日期。

例子:

f[[14,12,14], Time.new]
100
f[[8,2,2006], Time.new]
0
f[[8,2,2006], Time.new(2006, 7, 5)]
50
f[[6,7,5], Time.new(2006, 7, 5)]
33

12

Python 2.7-172

我使用datetime模块进行有效性和日期比较。如果date无法从输入中输入有效的日期时间,则会引发ValueError。这种方式s是未过期日期的总和,t是有效日期的总数。我利用了这样一个事实,True == 1即出于Python中的加法和索引编制的目的。我还使用25 *(76,80)而不是(1900,2000)保存字符。

请注意,第二级缩进中的行使用制表符,而不是2个空格。

def f(e,c,s=0,t=3):
 for Y,M,D in(0,1,2),(2,0,1),(2,1,0):
  y=e[Y]
  try:s+=date(y+25*[[76,80][y<50],0][y>99],e[M],e[D])>=c
  except:t-=1
 return 100*s/t

将其添加到测试的末尾:

examples = [[14,12,14],[8,2,2006],[6,7,5],[6,5,7],[12,31,99]]
for e in examples:
 print f(e, date(2006,7,5))

10

PowerShell中,183 173 168

[int](100*(($d=@(($a,$b,$c=$args[0]),($c,$a,$b),($c,$b,$a)|%{$_[0]+=1900*($_[0]-le99)+100*($_[0]-le49)
.{date($_-join'-')}2>$x}|sort -u))-ge(date)+'-1').Count/$d.Count)
  • int[]通过参数输入,例如

    PS> ./milk.ps1 5,6,7
    
  • 只要不知道是否允许在stderr上输出,错误消息就会通过try/ 静音catch
  • 使用+"-1"date,它被解释为.AddDays(-1)将当前日期移动一天,以便我们可以与昨天(而不是今天)进行比较。这解决了一个问题,我们获得一个以0:00作为日期的日期,但需要与一个从今天开始具有时间的日期进行比较。
  • 现已大量内联
  • 使用一种新的技巧来消除错误,该错误要短得多

6

R,269

我原以为这在R中会很容易,但是个位数的年份是一个很大的曲线球。我觉得这可能比现在好得多。

lubridate是CRAN的软件包,您可能需要使用进行安装install.packages("lubridate")

require(lubridate)
f = function(d){
d=sapply(d,function(l)if(nchar(l)==1)sprintf("%02d",l)else l)
d=paste0(d,collapse="-")
t=ymd(Sys.Date())
s=na.omit(c(ymd(d),mdy(d),dmy(d)))
s=lapply(s,function(d){
if(year(d)>2049){year(d)=year(d)-100;d}
else d})
sum(s>t)/length(s)}

用法:f(c(d1,d2,d3))其中c(d1,d2,d3)是整数的向量。

例如 f(c(6,10,14))返回0.3333333

lubridate软件包具有一系列包装器功能,用于按不同顺序解析日期。我用它们来查看哪些格式产生有效的日期,扔掉无效的日期,然后查看尚未发生的日期。


6

数学,163个 153 164字节

编辑:固定日期在1950年-2049年范围之外)

f=100.Count[#,x_/;x<1]/Length@#&[DateDifference[#,Date[]]&/@Cases[{If[#<100,Mod[#+50,100]+1950,#],##2}&@@@{{##},{#3,#2,#},{#3,#,#2}}&@@#,d_/;DateList@d~Take~3==d]]&

这定义了一个可以调用的函数

f[{6,7,5}]

目前,该百分比尚未四舍五入(等待OP澄清)。

这里有一个稍微长的解释,应该是可以理解的,没有任何数学知识(注意,&让一切留给它的一个匿名函数,它的参数被称为##2#3...):

{{##},{#3,#2,#},{#3,#,#2}}&

这定义了一个函数,该函数将3个参数a,b,c转换为3个列表{{a,b,c},{c,b,a},{c,a,b}。请注意,这##只是所有参数的序列。

{{##},{#3,#2,#},{#3,#,#2}}&@@#

应用于到期日期,这给出了{y,m,d}三个可能排列中的每个排列的列表。

{If[#<100,Mod[#+50,100]+1950,#],##2}&

这是一个匿名函数,有三个参数a,b,c和返回三个,第一个已被转换到一年按照给定的规则列表:与数字5099(模100)的之间变成了20世纪以来,数字049(模数100)变成21世纪的一年,其他所有的都留下了。这里##2是从第二个开始的一系列参数,即b,c

{If[#<100,Mod[#+50,100]+1950,#],##2}&@@@{{##},{#3,#2,#},{#3,#,#2}}&@@#

应用于之前的三个结果中的每一个,这仅能规范年份格式。我们称其canonicalDates为以下表达式:

Cases[canonicalDates,d_/;DateList@d~Take~3==d]

这样可以过滤掉无效的解释。DateList@d可以用{y,m,d,h,m,s}各种日期格式完整表示。它将以相同的顺序解释列表,但是要注意的是,您可以{8,2,2006}在这种情况下进行计算那样传递它8 years + 2 months + 2006 days。因此,我们检查返回列表的前三个元素是否与输入相同(仅当月份和日期在适当范围内时才会发生)。

为了缩短以下几行,validDates从现在开始,我将引用该表达式的结果:

DateDifference[#,Date[]]&

另一个匿名函数,它带有一个日期并返回到今天为止的天数差(从中获取Date[])。

DateDifference[#,Date[]]&/@validDates

将其映射到有效的日期解释。

100.Count[#,x_/;x<1]/Length@#&

给定列表(#)的另一个匿名函数返回该列表中非正数的百分比。该.值不是乘法,而只是十进制数,以免出现有理数(结果是100/3而不是33.333-我实际上不知道这是否有问题)。

100.Count[#,x_/;x<1]/Length@#&[DateDifference[#,Date[]]&/@validDates]

应用于日期差异列表,这为我们提供了尚未过期的部分解释。


我觉得你错误地转换几年如2999或2099至1999年
Ventero

@Ventero是的。我有点以为我们处理1950年至2049年(及其1或2位数字的版本),但是重新阅读挑战并没有提及这一点。
Martin Ender 2014年

@Ventero固定(但是您无论如何都已经击败了我;)
Martin Ender 2014年

我很惊讶地看到您在Mathematica上有一个帐户,但是还没有发布任何问题或解答。有什么让你退缩的吗?
维扎德先生2014年

@Wizard先生,很抱歉,完全忘了回复您。问题:到目前为止,我所遇到的每个问题都可以通过谷歌搜索/其他SE问题解决。答案:我不知道。。。我想我不认为自己在熟练使用Mathematica方面是如此精通。另外,我想回答一些问题,我必须积极观察新问题,才能看到我可以回答的问题,目前,我所有的SE时间都分配给了PPCG。;)如果您想让我说服我,请随时聊天!:)
Martin Ender 2014年

4

的JavaScript(E6)159 164 172

编辑感谢nderscore的提示并促使我重新考虑。重组D避免参数并削减一些字符。

编辑2 nderscore的另一个技巧,将2个函数合并为1。然后用两个括号将合并的逗号分隔的表达式合并为一个。可读性接近0。旁注:不进行四舍五入可以节省另外2个字符(| 0)。

F=(a,t)=>t?100*(3-((i=F([y,m,d]=a))<t)-((j=F([m,d,y]=a))<t)-((k=F([d,m]=a))<t))/(3-!i-!j-!k)|0:(q=new Date(y<50?y+2e3:y,--m,d)).getMonth()==m&q.getDate()==d&&q

在FireFox控制台中测试

;[[14,12,14],[8,2,2006],[6,7,5],[6,5,7],[12,31,99]]
.map(x=>x + ' ' + F(x, new Date(2006,6,5)))

输出:

["14,12,14 100", "8,2,2006 50", "6,7,5 33", "6,5,7 66", "12,31,99 0"]

不打高尔夫球

NB D函数尝试使用给定的年,月,日创建日期,但如果创建的日期不是预期的日期,则返回false(!=天或月)

F=(d,t)=>
(
  D=(y,m,d)=>(
    q=new Date(y<50?y+2000:y, --m, d), // decr m as javascript (like java) counts months starting at 0
    q.getMonth() == m & q.getDate() == d && q
  ),
  [a,b,c] = d, 
  x=D(...d), // three ways of express the date ...
  y=D(c,a,b),
  z=D(c,b,a),
  100 * (3-(x<t)-(y<t)-(z<t)) / (3-!x-!y-!z) | 0  
)   

@nderscore对于D的更改可以,其他的sintax错误。但是无论如何保存得更多
edc65

奇怪的。当我将其粘贴到评论中时,一定发生了某些事情。您的最新优化使其无关紧要:)
nderscore 2014年

1
将其粘贴,因为我不再相信SE的评论了:(-3)pastie.org/private/6bemdweyndcaiseay70kia
nderscore 2014年

4

C#中LINQPad - 446 408 272个字节

第三编辑:感谢Le Canard fou指出DateTime.Today是正确的,而不是DateTime.Now。 第二编辑:感谢VisualMelon这个聪明的解决方案!

void g(int[]d){var p=".";int a=d[2],b=d[1],e=d[0],y=a+(a<100?a>49?1900:2000:0),q=0,s=0;DateTime c;Action<string>z=x=>{if(DateTime.TryParse(x,out c)){s++;if(c>=DateTime.Today)q+=100;}};z(e+p+b+p+y);z(b+p+e+p+y);z(a+p+b+p+(e<100?‌​e>49?1900+e:2000+e:e));(q/(s>0?s:1)).Dump();}

编辑:感谢podiluska和edc65帮助我缩短了代码!我还注意到,如果年份输入为4个字节长,我的解决方案将不正确,因此我提供了针对该问题的解决方案。该解决方案的分数是408字节。

即使我没有击败任何先前的答案,我仍然想分享我的C#解决方案。任何帮助/建议表示赞赏!;)

void g(int[]d){var q=new List<DateTime>();var p=".";int s=0,a=d[2],b=d[1],e=d[0],y=0;var c=new DateTime();y=(a<100)?(a>49)?1900+a:2000+a:a;if(DateTime.TryParse(e+p+b+p+y,out c)){q.Add(c);s++;}if(DateTime.TryParse(b+p+e+p+y,out c)){q.Add(c);s++;}y=(e<100)?(e>49)?1900+e:2000+e:e;if(DateTime.TryParse(a+p+b+p+y,out c)){q.Add(c);s++;}q=q.Where(i=>i>=DateTime.Now).ToList();if(s==0){s=1;}(q.Count*100/s).Dump();}

格式化的版本:

void g(int[] d)
    {
        var q = new List<DateTime>();
        var p = ".";
        int s = 0, a = d[2],b = d[1],e = d[0], y=0;
        var c = new DateTime();
        y = (a < 100) ?((a > 49) ? 1900 + a : 2000 + a) : a;

        if (DateTime.TryParse(e + p + b + p + y, out c))
        {
            q.Add(c);
            s++;
        }
        if (DateTime.TryParse(b + p + e + p + y, out c))
        {
            q.Add(c);
            s++;
        }
        y = (e < 100) ? ((e > 49) ? 1900 + e : 2000 + e) : e;

        if (DateTime.TryParse(a + p + b + p + y, out c))
        {
            q.Add(c);
            s++;
        }
        q = q.Where(i => i >= DateTime.Now).ToList();
        if (s == 0)
        {
            s = 1;
        }
        (q.Count*100/s).Dump();
    }

我试图提供一种解决方案,其中不重复此解决方案中的“ DateTime.TryParse” -Part,但是它长了21个字节。

不重复“ DateTime.TryParse”的解决方案:467字节

void g(int[]d){var q=new List<DateTime>();int s=0;int a=d[2];int b=d[1];int e=d[0];int y=0;if(a<100){if(a>49){y=1900+a;}else{y=2000+a;}}if(z(e,b,y,q)){s++;}if(z(b,e,y,q)){s++;}if(e<100){if(e>49){y=1900+e;}else{y=2000+e;}}if(z(a,b,y,q)){s++;}q=q.Where(i=>i>=DateTime.Now).ToList();if(s==0){s=1;}(q.Count*100/s).Dump();}bool z(int a,int b,int d,List<DateTime> q){var c=new DateTime();var p=".";if(DateTime.TryParse(a+p+b+p+d,out c)){q.Add(c);return true;}return false;}

非高尔夫版本:

private void g(int[] d)
    {
        var q = new List<DateTime>();
        int s = 0;
        int a = d[2];
        int b = d[1];
        int e = d[0];
        int y = 0;
        if (a < 100)
        {
            if (a > 49)
            {
                y = 1900 + a;
            }
            else
            {
                y = 2000 + a;
            }
        }
        if (z(e, b, y, q))
        {
            s++;
        }
        if (z(b, e, y, q))
        {
            s++;
        }
        if (e < 100)
        {
            if (e > 49)
            {
                y = 1900 + e;
            }
            else
            {
                y = 2000 + e;
            }
        }
        if (z(a, b, y, q))
        {
            s++;
        }
        q = q.Where(i => i >= DateTime.Now).ToList();
        if (s == 0)
        {
            s = 1;
        }
        (q.Count*100/s).Dump();
    }

    private bool z(int a, int b, int d, List<DateTime> q)
    {
        var c = new DateTime();
        string p = ".";
        if (DateTime.TryParse(a + p + b + p + d, out c))
        {
            q.Add(c);
            return true;
        }
        return false;
    }

2
int s=0;int a=d[2];int b=d[1];int e=d[0];->int s=0,a=d[2],b=d[1],e=d[0];
podiluska,2014年

2
建议:尽可能使用三元(?:)代替if / else
edc65

1
@ThomasW。我不认为y具有2个不同的值,一次取决于a,另一次取决于e。不管怎么说,还是要谢谢你!
tsavinho 2014年

1
删除DateTime.TryParse电话是我的第一个本能,用lambda代替了它,这也使值重新回到q中。还执行了一些其他步骤(pastebin)以获取328个字符:void g(int[]d){var q=new List<DateTime>();var p=".";int a=d[2],b=d[1],e=d[0],y;DateTime c;y=(a<100)?(a>49)?1900+a:2000+a:a;Action<string>z=(x)=>{if(DateTime.TryParse(x,out c))q.Add(c);};z(e+p+b+p+y);z(b+p+e+p+y);y=(e<100)?(e>49)?1900+e:2000+e:e;z(a+p+b+p+y);(q.Where(i=>i>=DateTime.Now).Count()*100/(q.Any()?q.Count:1)).Dump();}
VisualMelon 2014年

1
@VisualMelon哇,您真的很擅长代码搜索!我以前从未见过Action<string>,所以我可以向您学习一些东西;)通过替换为q.Where(i=>i>=DateTime.Now).Count,我可以使您的答案降至318个字符 q.Count(i=>i>=DateTime.Now。我还卸下了方括号,x这样我可以再保存2个字符!
tsavinho 2014年

3

Haskell,171165个字符

l=length
r y|y<100=(y+50)`mod`100+1950|y>0=y
q d m y z|d<32&&m<13&&d*m>0=(r y,m,d):z|1<3=z
v(a,b,c)=q c b a$q b a c$q a b c[]
t%d=(l$filter(>t)(v d))*100`div`l(v d)

该函数的名称为%。将测试日期作为具有实际年份的规范(y,m,d)顺序的元组运行,并将纸箱邮票作为三个数字的元组运行:

λ: (2006,6,5)%(14,12,14)
100

λ: (2006,6,5)%(8,2,2006)
50

λ: (2006,6,5)%(6,7,5)
33

λ: (2006,6,5)%(6,5,7)
66

λ: (2006,6,5)%(12,31,99)
0

λ: (2006,6,5)%(0,1,7)
0

2

埃尔朗(146)

f([A,B,C]=U,N)->F=[T||T<-[{(Y+50)rem 100+1950,M,D}||[Y,M,D]<-[U,[C,A,B],[C,B,A]]],calendar:valid_date(T)],100*length([1||T<-F,T>=N])div length(F).

测试功能为:

t() ->
    0 = f([12,31,99],{2006,6,5}),
    66 = f([6,5,7],{2006,6,5}),
    33 = f([6,7,5],{2006,6,5}),
    100 = f([14,12,14],{2006,6,5}),
    50 = f([8,2,2006],{2006,6,5}),
    100 = f([29,2,2],{2006,6,5}).

不打高尔夫球

f([A,B,C]=U,Today)->
    Perms = [U,[C,A,B],[C,B,A]],
    WithYears = [{(Y+50) rem 100+1950,M,D} || [Y,M,D] <- Perms],
    ValidDates = [T || T <- WithYears, calendar:valid_date(T)],
    100*length([1 || T <- ValidDates, T >= Today]) div length(ValidDates).

该解决方案依赖于列表理解。它从Haskell解决方案中借用了当年的模数技巧。calendar:valid_date/1由于给定月份的天数,它还用于处理不可能的日期(例如,“ 29-2-2”只能采用YMD格式)。另外,Today是Erlang的date()格式(YMD元组)。


2

杀伤人员地雷(85)

这使用了Dyalog APL 14的一些新功能,但没有外部库。对于更改,它可以在TryAPL运行

{100×(+/÷⍴)⍺≤{(3/100)⊥⍵+(99≥⊃⍵)×3↑1900+100×50>⊃⍵}¨Z/⍨{∧/12 31≥1↓⍵}¨Z←(⊂⌽⍵),(⊂2⌽⍵),⊂⍵}

该函数将3元素数组作为其右侧()参数,并将要检查的日期作为其左侧()参数,YYYYMMDD格式为整数。即,日期2014-07-09用数字表示20140709

测试:

      20060705 {100×(+/÷⍴)⍺≤{(3/100)⊥⍵+(99≥⊃⍵)×3↑1900+100×50>⊃⍵}¨Z/⍨{∧/12 31≥1↓⍵}¨Z←(⊂⌽⍵),(⊂2⌽⍵),⊂⍵} 14 12 14
100
      20060705 {100×(+/÷⍴)⍺≤{(3/100)⊥⍵+(99≥⊃⍵)×3↑1900+100×50>⊃⍵}¨Z/⍨{∧/12 31≥1↓⍵}¨Z←(⊂⌽⍵),(⊂2⌽⍵),⊂⍵} 8 2 2006
50
      20060705 {100×(+/÷⍴)⍺≤{(3/100)⊥⍵+(99≥⊃⍵)×3↑1900+100×50>⊃⍵}¨Z/⍨{∧/12 31≥1↓⍵}¨Z←(⊂⌽⍵),(⊂2⌽⍵),⊂⍵} 6 7 5
33.3333
      20060705 {100×(+/÷⍴)⍺≤{(3/100)⊥⍵+(99≥⊃⍵)×3↑1900+100×50>⊃⍵}¨Z/⍨{∧/12 31≥1↓⍵}¨Z←(⊂⌽⍵),(⊂2⌽⍵),⊂⍵} 12 31 99
0

说明:

  • Z←(⊂⌽⍵),(⊂2⌽⍵),⊂⍵:通过将给定日期翻转(⊂⌽⍵),向左旋转2 (⊂2⌽⍵)或不执行任何操作,将其转换为YMD格式⊂⍵。现在,其中至少有一个是YMD格式的正确日期,如果日期不明确,则可能多个。
  • {∧/12 31≥1↓⍵}¨Z:测试每个日期是否有效:删除年份(第一个元素),然后月份必须不大于12,日期必须不大于31。
  • Z/⍨:从中过滤有效日期Z
  • {... :每个有效日期:
    • ⍵+(99≥⊃⍵)×3↑1900+100×50>⊃⍵:如果年份不大于99,则加1900,如果年份小于50,则加100。
    • (3/100)⊥:将其解码为好像是一组以100为底的数字。(年份大于100,但这并不重要,因为它是第一个元素。)这将为每个有效日期提供一个数字,格式与left参数相同。
  • ⍺≤:对于每个日期,请查看日期是否不少于。这将给出一个二进制矢量,其中1表示OK0表示spoiled
  • 100×(+/÷⍴):将二进制矢量的总和除以其长度,然后乘以100。

保存7个字节(和一个不错的余量击败K)与搁浅,使内部功能默契:{100×(+/÷⍴)⍺≤((3/100)⊥⊢+(99≥⊃)×3↑1900+100×50>⊃)¨Z/⍨{∧/12 31≥1↓⍵}¨Z←(⌽⍵)(2⌽⍵)⍵}
亚当

0

Java:349个字符(3个空格)

int e(int[]n,Date t){int a=n[0],b=n[1],c=n[2];Date[]d=new Date[3];if(b<13&&c<32)d[0]=new Date((a<50?100:(a>100?-1900:0))+a,b-1,c);if(b<13&&a<32)d[1]=new Date((c<50?100:(c>100?-1900:0))+c,b-1,a);if(a<13&&b<32)d[2]=new Date((c<50?100:(c>100?-1900:0))+c,a-1,b);int v=0,g=0;for(int i=0;i<3;i++)if(d[i]!=null){if(!d[i].before(t))g++;v++;}return 100*g/v;}

这是一个可以用来对其进行测试的包含类,其中包括该方法的(略过)去版本化的版本:

import java.util.*;
class i{

   int e(int[]n,Date t){
      int a=n[0],b=n[1],c=n[2];
      Date[]d=new Date[3];
      if(b<13&&c<32)d[0]=new Date((a<50?100:(a>100?-1900:0))+a,b-1,c);
      if(b<13&&a<32)d[1]=new Date((c<50?100:(c>100?-1900:0))+c,b-1,a);
      if(a<13&&b<32)d[2]=new Date((c<50?100:(c>100?-1900:0))+c,a-1,b);
      int v=0,g=0;
      for(int i=0;i<3;i++)
         if(d[i]!=null){
            if(!d[i].before(t))
               g++;
            v++;
         }
      return 100*g/v;}

   public static void main(String[] args){
      int[]i=new int[3];
      for(int k=0;k<3;k++)
         i[k] = Integer.parseInt(args[k]);
      int j = new i().e(i,new Date());
      System.out.println(j+"%");
   }   
}

这是我的第一轮代码高尔夫,我想我想出了为什么我通常不会看到很多Java高尔夫球手的原因。


1
您需要接受一个int[]as参数,而不是3 ints。
2014年

好的,我修复了它。
shieldgenerator7 2014年

0

C#287字节

namespace System{class E{static float a,o,l;void M(int[]i){int d=i[0],m=i[1],y=i[2],t;if(l<3)try{if(l==1){t=y;y=d;d=t;}if(l++==0){t=d;d=m;m=t;}if(y<100&&(y+=1900)<1950)y+=100;o+=new DateTime(y,m,d)>=DateTime.Today?1:0;a++;if(l<3)i[9]=9;}catch{M(i);throw;}Console.Write(o/a);}}}

第一次打高尔夫球,寻求建议。值得注意的是,由于命名空间而删除了字节。

滥用仅需要功能而不是实际程序的事实。同样,该函数总是导致未捕获的异常。

不打高尔夫球

namespace System {
    class E {
        static float a, o, l;
        void M(int[] i) {
            int d = i[0], m = i[1], y = i[2], t;
            if (l < 3)
                try {
                    if (l == 1) { 
                        t = y; y = d; d = t; 
                    } 
                    if (l++ == 0) { 
                        t = d; d = m; m = t; 
                    } 
                    if (y < 100 && (y += 1900) < 1950)
                        y += 100; 
                    o += new DateTime(y, m, d) >= DateTime.Today ? 1 : 0; // # not expired
                    a++; // # valid dates
                    if (l < 3)
                        i[9] = 9; // throw new Exception()
                } 
                catch { 
                    M(i);
                    throw; // fail after the first Console.Write()
                } 
            Console.Write(o / a); 
        } 
    } 
}

0

数学家 118

以m.buettner的代码为起点,我进行了一些改进:

⌊100Mean@UnitStep@Cases[DateDifference@{If[#<100,Mod[#+50,100]+1950,#],##2}&@@@{#,RotateRight@#,Reverse@#},_Integer]⌋&

高尔夫可以是将三整数列表作为参数的函数。
algorithmhark

@algorithmshark谢谢。我不知道我怎么想念它。正在更新...
Wizard先生2014年
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.