日期乘法挑战


19

(灵感来自上周的FiveRhirtyEight.com.Sandbox post的Riddler。)

给定2001年至2099年之间的一年,请计算并返回该日历年中的天数,其中mm * dd = yyyy2位数的年份)。

例如,2018年有5个:

  • 1月18日(1 * 18 = 18)
  • 2月9日(2 * 9 = 18)
  • 3月6日(3 * 6 = 18)
  • 6月3日(6 * 3 = 18)
  • 9月2日(9 * 2 = 18)

输入可以是2位数或4位数的数字年份。

输出应为整数。可选的尾随空格或回车符都可以。

完整的输入/输出列表:

Input = Output
 2001 = 1     2021 = 3     2041 = 0     2061 = 0     2081 = 2
 2002 = 2     2022 = 3     2042 = 4     2062 = 0     2082 = 0
 2003 = 2     2023 = 1     2043 = 0     2063 = 3     2083 = 0
 2004 = 3     2024 = 7     2044 = 3     2064 = 2     2084 = 5
 2005 = 2     2025 = 2     2045 = 3     2065 = 1     2085 = 1
 2006 = 4     2026 = 2     2046 = 1     2066 = 3     2086 = 0
 2007 = 2     2027 = 3     2047 = 0     2067 = 0     2087 = 1
 2008 = 4     2028 = 4     2048 = 6     2068 = 1     2088 = 3
 2009 = 3     2029 = 1     2049 = 1     2069 = 1     2089 = 0
 2010 = 4     2030 = 6     2050 = 3     2070 = 3     2090 = 5
 2011 = 2     2031 = 1     2051 = 1     2071 = 0     2091 = 1
 2012 = 6     2032 = 3     2052 = 2     2072 = 6     2092 = 1
 2013 = 1     2033 = 2     2053 = 0     2073 = 0     2093 = 1
 2014 = 3     2034 = 1     2054 = 4     2074 = 0     2094 = 0
 2015 = 3     2035 = 2     2055 = 2     2075 = 2     2095 = 1
 2016 = 4     2036 = 6     2056 = 4     2076 = 1     2096 = 4
 2017 = 1     2037 = 0     2057 = 1     2077 = 2     2097 = 0
 2018 = 5     2038 = 1     2058 = 0     2078 = 2     2098 = 1
 2019 = 1     2039 = 1     2059 = 0     2079 = 0     2099 = 2
 2020 = 5     2040 = 5     2060 = 6     2080 = 4

这是一个挑战,每种语言的最低字节数获胜。

通常,根据我们的漏洞规则不包括预先计算和简单查找答案的问题,但是我明确允许这样做以应对这一挑战。它允许一些有趣的替代策略,尽管它不可​​能是最短的98 99项查找列表。


如果使用您的语言更轻松,那么无论世纪多久,答案都是相同的。1924年和2124年与2024
。– BradC

如果mm * dd的结果大于100,则会自动过滤?
DanielIndie

@DanielIndie正确,不应该计算任何“环绕”日期。换句话说,即使12 * 12 = 144也不会算到2044年12月12日
。– BradC

由于我们只需要处理有限数量的输入,因此我已对其全部进行了编辑。请随时回滚或重新格式化。
毛茸茸的

1
@gwaugh只是您可以决定接受哪个输入作为有效输入(因此,您不必花费额外的字符在两者之间进行转换)。
BradC

Answers:


14

Excel,48个字节

万岁!最后,Excel确实很擅长。

=COUNT(VALUE(ROW(1:12)&"/"&A1/ROW(1:12)&"/"&A1))

从A1以整数1-99的形式表示年份,并输入到您输入此公式的任何位置。这是一个数组公式,因此请使用Ctrl-Shift-Enter而不是Enter进行输入。

这利用了以下事实: COUNT忽略错误,因此,由月份未除以年(导致Excel解析某些内容2/12.5/25或由无效日期(如)引起的任何错误)都将被2/29/58静默忽略。


1
非常好。可能值得一提的是,该年份需要2位数字的年份A1。输入4位数字的年份仅会返回0
BradC

真正!我将其编辑成描述。
Sophia Lechner '18

我还要提到它是特定于语言环境的。这取决于使用mm / dd / yy排序的语言环境。当然,在以dd / mm / yy排序的语言环境中,答案将是相同的字节数。
Sophia Lechner '18

1
超级聪明;我喜欢您只测试12个约会候选人(每月一个)的方式,而不是每年的每一天都在测试。
BradC

将年份固定为一个非跳跃的保存字节?
l4m2

6

Python 2 2,44字节

[k/32%13*(k%32)for k in range(96,509)].count

在线尝试!

作为方法对象给出的匿名函数。生产的所有产品(month, day)(m, d)通过作为编码k=32*m+d0≤m≤120≤d≤31的,环绕周围。通过从范围内排除它们来消除2月29日至31日。


5

Java(JDK 10),65字节

y->{int m=13,c=0;for(;m-->1;)if(y%m<1&y/m<29+m%2*3)c++;return c;}

在线尝试!

学分


没有leap年适合29*n,因此无需检查
l4m2 18-4-13

感谢您的输入。我可以一并删除其他总共27个字节。
奥利维尔·格雷戈尔

1
更改(m==2?29:32)29+m%2*3仍然可以得到所有OK结果。感谢@AsoneTuhid的红宝石答案
凯文·克鲁伊森

4

PowerShell,94字节

param($a)for($x=Date 1/1/$a;$x-le(Date 12/9/$a);$x=$x.AddDays(1)){$z+=$x.Month*$x.Day-eq$a};$z

在线尝试!

将输入作为两位数的年份,然后构造一个for1/1/year到的循环12/9/year(因为12/10及以后的循环将不再计数,因此将节省一个字节)。每次迭代中,我们增加$z且仅当.Month.Day等于我们输入的一年。在循环外部,$z留在管道上,输出是隐式的。

编辑-这取决于文化。上面的代码适用于en-us。对于其他区域性,日期格式可能需要更改。


2
“文化”?您是说“语言环境”吗?...
user202729 '18

1
@ user202729通俗地说,是的,但是PowerShell文档将其称为“区域性”。
AdmBorkBork

MS通常用“文化”这个词来谈论语言环境。.NET中的System.Globalization.CultureInfo
sundar-恢复莫妮卡




3

JavaScript(ES6),91字节

我很想知道硬编码与迭代计算的比较。这绝对更长(见@粗野的答案),但不是非常长。

编辑:但是,它比更直接的公式长得多(请参阅@ l4m2 answer)。

[1..99]中将输入作为整数。

n=>(k=parseInt('8ijkskercdtbnqcejh6954r1eb2kc06oa3936gh2k0d83d984h'[n>>1],36),n&1?k>>3:k&7)

在线尝试!

怎么样?

多年来有显著较少具有机会毫米* DD = YY比甚至几年。更具体地说,奇数年有03个匹配项,而偶数年有07个匹配项。这使我们可以仅用5位就可以编码每两年,这可以方便地用基数36表示为单个字符。




3

Bash + GNU实用程序,57

  • @SophiaLechner节省了1个字节
seq -f1/1/$1+%gday 0 365|date -f- +%m*%d-%y|bc|grep -c ^0

请注意 seq命令始终会生成366个日期的列表-对于非-年,将包含第二年的1月1日。但是,在日期范围2001..2099中,MM * DD在任何年份的下一年的1月1日永远都不会是YY,因此,这多余的一天不会影响结果。

在线尝试!


非常好-我什至都不知道date在解析时会做这样的日期数学运算。seq的后面不需要空格-f,因此您可以在其中保存一个字节。
Sophia Lechner '18

3

T-SQL,123字节

根据我们的IO规则,输入是通过预先存在的表t进行的,其中表t具有一个整数字段y,其中包含两位数的年份。

WITH c AS(SELECT 1m UNION ALL SELECT m+1FROM c WHERE m<12)
SELECT SUM(ISDATE(CONCAT(m,'/',y/m,'/',y)))FROM c,t WHERE y%m=0

换行符仅用于可读性。灵感主要来自Sophia的Excel解决方案

  • 第一行生成一个12项数字表c,该表与输入表t相连
  • 如果通过,我将使用混搭日期候选者CONCAT(),这将进行隐式varchar数据类型转换。否则,我将不得不做一堆CASTor CONVERT语句。
  • 找到完善的评估功能 ISDATE(),该对于有效日期返回1,对于无效日期返回0。
  • 将其包装成SUM,我完成了。
  • 编辑:将整数除法检查(y%m=0)移到WHERE子句中以节省2个字节,谢谢@RazvanSocol。

不幸的是,它没有比查找表版本短很多(使用osdavison版本中的字符串):

T-SQL查找,129个字节

SELECT SUBSTRING('122324243426133415153317223416132126011504033106131204241006003213011306002122042005101305111014012',y,1)FROM t

编辑:将我的原始内容保留在上面,但是我们可以通过使用几个新函数来节省一些字节:

  • STRING_SPLIT 在MS SQL 2016及更高版本中可用。
  • CONCAT_WS 在MS SQL 2017及更高版本中可用。
  • 如上所述,替换IIFWHERE

MS-SQL 2017,121个 118字节

SELECT SUM(ISDATE(CONCAT_WS('/',value,y/value,y)))
FROM t,STRING_SPLIT('1-2-3-4-5-6-7-8-9-10-11-12','-')
WHERE y%value=0

MS-SQL 2017,额外的作弊版:109字节

SELECT SUM(ISDATE(CONCAT_WS('/',number,y/number,y)))
FROM t,spt_values WHERE number>0AND y%number=0AND'P'=TYPE

要求您位于master数据库中,该数据库包含一个系统表spt_values(当按过滤时TYPE='P'),该表可为您计数从0到2048的数字。


与其他答案类似,我组装日期(m/d/y)的顺序取决于SQL实例的位置设置。其他地区可能需要不同的顺序或不同的分隔符,但我认为这不会影响代码长度。
BradC

我想您已经意识到将“ 2/29/64”转换为日期会产生1964-02-29(而不是2064-02-29),但是考虑到2000和2100年被排除在外,这是缩短日期的好方法码。
拉兹万·索科尔

使用SPLIT_STRING而不是CTE将其减少到120个字节。使用CONCAT_WS而不是CONCAT保存另一个字符,将其保留为119个字节。
拉兹万·索科尔

@RazvanSocol是的,我不确定在映射到19xx与20xx的两位数日期之间的间隔在哪里,但是两者给出的答案相同。我将尝试其他两个建议,谢谢!
BradC

1
替换IIFWHERE
拉兹万·索科尔

3

朱0.649个 44 42字节

y->sum(y/i1:28+3(i%2i÷8)for i=1:12)

在线尝试!

-5个字节受Asone Tuhid的Ruby答案启发。
-2字节用总和替换计数

说明:

对于i从1到12的每个月,请计算y/i,然后检查是否是该月的一天之一。用31天的月份是1,3,5,7,8,10,12 -因此他们奇数低于8,甚至因此,无论在以上8 i%2i÷8(对于i为0 <8和1对于i> =这里的8)应该为1,但不能同时为两者-因此我们对它们进行XOR。如果xor结果为true,则检查日期,1:28+31:31,否则仅检查date 1:28

1:28接下来的几个月中就足够了(这项改进是受Asone Tuhid的Ruby answer启发的),因为:

  • 对于2月,唯一的可能性是2*29 = 58,但2058不是a年,因此我们可以假设2月始终有28天。

  • 其他30天的月份是第4个月及以上- i*29(和i*30)会大于100,可以忽略不计。

最后,我们计算出y/i属于该天数的次数(通过sum在此处使用布尔值),然后将其返回。


3

JavaScript, 91 85 82 81 77字节

将输入作为2位数的字符串(或1或2位数的整数)。

利用以下事实 new Date会滚动到下个月,并继续这样做,如果您将传递给它的日值超过传递给它的当月的天数,则在第一次迭代时,它将尝试构造yyyy-01-345成为的日期yyyy-12-11,或yyyy-12-10为leap年。我们不需要在此之后检查日期,因为12*11+结果是3位数字。

y=>(g=d=>d&&([,M,D]=new Date(y,0,d).toJSON().split(/\D/),D*M==y)+g(--d))(345)

感谢Arnauld节省了3个字节。


测试一下

f=
y=>(g=d=>d&&([,M,D]=new Date(y,0,d).toJSON().split(/\D/),D*M==y)+g(--d))(345)
o.innerText=[...Array(99)].map((_,x)=>(2001+x++)+` = `+f(x)).join`\n`
pre{column-count:5;width:480px;}
<pre id=o></pre>



2

Excel,83个字节

{=SUM(IF(MONTH(DATE(A1,1,0)+ROW(1:366))*DAY(DATE(A1,1,0)+ROW(1:366))=A1-2000,1,0))}

输入A1格式为yyyy。这是一个数组公式,用Ctrl+ Shift+ 输入Enter可获取大括号{}。它相当简单,没有任何聪明之处。

在数组公式中时,DATE(A1,1,0)+ROW(1:366)为我们提供366个日期值的数组。在非le年中,这将包括下一年的1月1日,但这不是问题,因为1*1=1并且仅在下一年是,2001但将被视为误报,因为所需的年份范围是2001 - 2099,因此永远不会出现问题。

如果将这一点简化为simple ~,则公式很容易遵循:

{=SUM(IF(MONTH(~)*DAY(~)=A1-2000,1,0))}

我尝试使用COUNTIF()代替,SUM(IF())但是Excel甚至不允许我输入它作为数组公式,更不用说给我结果了。我的确找到了使用Google表格解决方案的方法,CountIf()但方法相同,否则为91字节,主要是因为它使用ArrayFormula()而不是simple { }

=CountIf(ArrayFormula(Month(Date(A1,1,0)+Row(1:366))*Day(Date(A1,1,0)+Row(1:366))),A1-2000)

我尚未达成共识,但通常我的Excel字节数中并未包含外部花括号。他们感觉更像是Excel格式化其显示方式而不是公式的一部分。意见?
Sophia Lechner '18

@SophiaLechner我将它们包括在内,而不是决定如何包括将其作为数组公式输入所需的额外击键。对此有一个元问题唯一的答案是CTRL + ALT + ENTER命令将算作1次按键。如果您使用与vim相同的内容(每个meta),则该击键将计为1个字节。但是,在其他答案中,我通常不将输入公式结尾时的ENTER视为1个字节。
Engineer Toast

2

视网膜0.8.2,55字节

..
$*
(?<=^(1{1,12}))(?=(?(?<=^11$)\1{0,27}|\1{0,30})$)

在线尝试!年份为两位数;加1个字节以支持4位数的年份。说明:第一阶段只是转换为一元。第二阶段从匹配位置前面的1到12个字符(代表月份)开始,然后尝试向前看该月的重复次数。但是,前瞻包含一个条件,它可以根据月份在最多27个或30个其他重复之间进行选择。这样,匹配位置的计数就是所需的结果。


2

[R 22个 122字节

x=scan();substr("122324243426133415153317223416132126011504033106131204241006003213011306002122042005101305111014012",x,x)

在线尝试!

决定采用查找表方法。输入年份必须为2位数字。


1
同样在TIO上,您可以单击“链接”按钮,它将为您自动设置答案的格式。感谢Dennis进行设置!
朱塞佩

您可以删除最初if,因为输入可以是任意 2位或4位,你的选择(这样你就可以选择只接受2位数字输入)。但它看起来像代码考虑每个月包含31天,所以对于例如62(用于2062)返回1,它应该返回0
恢复莫妮卡-孙大信

2
我误解了。话虽如此,我很确定查找表必须包含在字节数中。
ngm

@ngm我也不确定是否需要包含查找表,但是为了安全起见,我会将其添加到字节数中。
罗伯特S.18年

我仍然不确定所有规则是什么!
ngm


2

J,29个字节

1#.(,x*i."+29+3*2~:x=.i.13)=]

在线尝试!

怎么运行的

1#.(,x*i."+29+3*2~:x=.i.13)=]    Input: year (2-digit, 1..99)
                   x=.i.13       array of 0..12; assign to x
                2~:              1 1 0 1 .. 1
              3*                 3 3 0 3 .. 3
           29+                   32 32 29 32 .. 32
       i."+                      for each item of above, generate a row 0 .. n
    ,x*                          each row times 0 .. 12 and flatten
                           =]    1 for each item == input, 0 otherwise
1#.                              sum

试图获得低于2倍的果冻溶液:)

边注

如果有人真的想对99位数据进行硬编码,请参考以下信息:

将99位数字分成2位数字。然后,第一个数字是<4,第二个数字<8,这意味着五个位可以编码两个数字。然后可以将整个数据编码为250位或32个字节。


2

Python 3中,158个162 215 241字节

已删除4感谢Stephen帮助打高尔夫球。

删除53感谢Stephen指出空白

由于caird提供的链接,删除了26

我对此很陌生。如果没有描述一个月中的几天,就无法想到如何执行此操作。

r=range
def n(Y):
 a,b,c=31,30,0
 for x in r(12):
  for y in r([a,(28if Y%4else 29),a,b,a,b,a,a,b,a,b,a][x]):
   if(x+1)*(y+1)==int(str(Y)[2:]):c+=1
 return c

在线尝试!


5
欢迎来到该网站,并且帖子不错!您可以通过多种方式打高尔夫球,例如删除一些空格,因此请务必查看Python中打高尔夫球的这些技巧
caird coinheringaahing

@cairdcoinheringaahing感谢您的建议,该链接非常有用!
akozi

1
158个字节 -打了一些球,但是大多数情况下,您在第三行上有一排很长的空格,不知道这些是怎么到达的
Stephen

@Stephen谢谢:)我将您的内容添加为两个编辑。一个用于白色空间,另一个用于打高尔夫球。
akozi

(28if Y%4else 29)可以缩短为[29,28][Y%4>0]。另外,长列表可以缩短为[a,...]+2*[a,b,a,b,a]a,b,c可以添加到参数列表中以保存行。int(str(Y)[2:])可以缩短为Y%100。最后,计数器变量通常可以缩短为lens的列表理解,这也可以n设为a lambda。这使得118
黑猫头鹰Kai

2

第四(gforth)60 59字节

: f 0 13 1 do over i /mod swap 32 i 2 = 3 * + 0 d< - loop ;

在线尝试!

该版本利用了以下事实:每月匹配的天数不能超过1个,并且年份必须被月份整除才能匹配。

说明

在月份中进行迭代,检查年份是否可以按月整除,并且商是否小于31(2月为28)3月之后的月份不能匹配大于25的天,因此我们可以假设所有月份(除2月)有31天的拼图时间。

代码说明

: f                   \ start new word definition
  0                   \ set up counter
  13 1 do             \ start a counted loop from 1 to 12
    over i /mod       \ get the quotient and remainder of dividing year by month
    swap              \ default order is remainder-quotient, but we want to swap them
    32 i 2= 3 * +     \ we want to compare to 32 days unless month is Feb
    0 d<=             \ treat the 4 numbers on the stack as 2 double-length numbers
                      \ and compare [1]
    -                 \ subtract result from counter (-1 is true in Forth)
  loop                \ end loop
;                     \ end word definition    

[1]-Forth具有双倍长度数字的概念,它以两个单倍长度数字(以xy的形式存储在堆栈中,其中double的值= y * 2^(l) + x,其中l是单字节长度的大小)。您正在使用的第四实施)。

在这种情况下,我将商和余数与32(或29)0进行了比较。如果余数大于0(年份不能按月整除),则第一个双精度数将自动大于32(或29)0,并且结果会是错误的。如果余数为0,则它​​决定有效地定期检查商数<= 32(或29)

第四(gforth),61字节

: f 0 13 1 do i 2 = 3 * 32 + 1 do over i j * = - loop loop ; 

在线尝试!

通过意识到只有2月才对一个月中的天数有影响才节省了一些字节

说明

第四个(至少gforth个)比较返回-1(代表真)和0(代表假)

0                     \ place 0 on top of the stack to use as a counter
13 1 do               \ begin the outer loop from 1 to 12
  i 2 = 3 *           \ if i is 2 place -3 on top of the stack, otherwise 0
  32 + 1 do           \ begin the inner loop from 1 to 31 (or 28)
    over              \ copy the year from stack position 2 and place it on top of the stack
    i j * = -         \ multiply month and day compare to year, subtract result from counter 
  loop                \ end the inner loop
loop                  \ end the outer loop


1

JavaScript(Node.js),108字节

a=>'0122324243426133415153317223416132126011504033106131204241006003213011306002122042005101305111014012'[a]

f=a=>'0122324243426133415153317223416132126011504033106131204241006003213011306002122042005101305111014012'[a]
o.innerText=[...Array(99)].map((_,x)=>(2001+x++)+` = `+f(x)).join`\n`
pre{column-count:5;width:480px;}
<pre id=o></pre>


蛮力查找,很好!
BradC

欢迎来到PPCG!
Shaggy


1

Python 3,132个字节

这确实是一个程序的相当长的时间,但是我认为它可能很有趣。

所有值都在0到7之间,因此我将每个数字用3位长二进制字符串编码。我尝试将原始二进制字符串粘贴到我的python程序中,但无法使其正常工作,因此我选择了文件中的base64。

我使用以下字符串作为查找表(结尾的7用于填充): 01223242434261334151533172234161321260115040331061312042410060032130113060021220420051013051110140127

程序将使用此字符串并将其解码为数字,然后使用位移来提取结果。

import base64
lambda n:int.from_bytes(base64.b64decode(b'pNRRxYtw01s9Jw4tFYE0QNkYsoRQgYBosEsYBFIRAUgsUkgwFQM='),'big')>>(6306-3*n)&7

66个字节+ 37个字节的文件= 103个字节

这将读取一个名为的二进制文件,e并避免使用base64。

lambda n:int.from_bytes(open('e','rb').read(),'big')>>(6306-3*n)&7

这是读取文件的十六进制转储(不带填充):

00000000  a4 d4 51 c5 8b 70 d3 5b  3d 27 0e 2d 15 81 34 40  |..Q..p.[='.-..4@|
00000010  d9 18 b2 84 50 81 80 68  b0 4b 18 04 52 11 01 48  |....P..h.K..R..H|
00000020  2c 52 48 30 0a                                    |,RH0.|


1

Oracle SQL,115字节

select count(decode(sign(decode(l,2,29,32)-y/l),1,1))from t,
xmltable('1to 12'columns l int path'.')where mod(y,l)=0

我们可能会注意到,由于100/4 <28,所以4月(及以后的几个月)中的多少天并不重要。也不必检查年份是否是year年。我们只需要指定2月有28天(而不是29天,因为验证仅针对2058年才执行,这不是leap跃),否则任何月份可能只有31天。

其他方法

Oracle SQL(12c版本2和更高版本),151字节

select count(to_date(y/l||'-'||l||'-1' default '' on conversion error,'dd-mm-y'))from t,
(select level l from dual connect by level<=12)where mod(y,l)=0

Oracle SQL(12c第2版及更高版本),137字节

select sum(validate_conversion(y/l||'-'||l||'-1'as date,'dd-mm-y'))from t,
(select level l from dual connect by level<=12)where mod(y,l)=0

如果将其替换为(select level l from dual connect by level<=12),则两种解决方案的长度都可能缩短了8个字节,xmltable('1to 12'columns l int path'.')但Oracle会由于该错误而引发异常(已在版本12.2.0.1.0、18.3.0.0.0上进行了测试)。

SQL> select count(to_date(y/l||'-'||l||'-1' default '' on conversion error,'dd-mm-y'))from t,
  2  xmltable('1to 12'columns l int path'.')where mod(y,l)=0
  3  /
select count(to_date(y/l||'-'||l||'-1' default '' on conversion error,'dd-mm-y'))from t,
*
ERROR at line 1:
ORA-00932: inconsistent datatypes: expected DATE got DATE


SQL> select sum(validate_conversion(y/l||'-'||l||'-1'as date,'dd-mm-y'))from t,
  2  xmltable('1to 12'columns l int path'.')where mod(y,l)=0
  3  /
select sum(validate_conversion(y/l||'-'||l||'-1'as date,'dd-mm-y'))from t,
*
ERROR at line 1:
ORA-43909: invalid input data type

在这两种解决方案中,当年份确实重要时,唯一的情况是2058,这是非-年,因此使用文字“ -1”来指定非ap年。

Oracle SQL,128字节

select count(d)from t,(select date'1-1-1'+level-1 d from dual connect by level<365)
where to_char(d(+),'mm')*to_char(d(+),'dd')=y

Oracle SQL,126个字节

select substr('122324243426133415153317223416132126011504033106131204241006003213011306002122042005101305111014012',y,1)from t

更新资料

Oracle SQL,110字节

select-sum(least(sign(y/l-decode(l,2,29,32)),0))from t,
xmltable('1to 12'columns l int path'.')where mod(y,l)=0

Oracle SQL,108个字节

select sum(decode(sign(decode(l,2,29,32)-y/l)*mod(y+1,l),1,1))from t,
xmltable('1to 12'columns l int path'.')

Spark SQL,137个字节

select count(cast(regexp_replace(concat_ws('-','2001',l,y/l),'.0$','')as date))
from(select explode(array(1,2,3,4,5,6,7,8,9,10,11,12))l),t

Spark 2.3+ SQL,126字节

replace功能可用)

select count(cast(replace(concat_ws('-','2001',l,y/l),'.0')as date))
from(select explode(array(1,2,3,4,5,6,7,8,9,10,11,12))l),t

1

PHP,73字节

使用管道输入和php -nR

for(;++$m<13;$d=1)while($d<25+($m-2?$m>4?:7:4))$c+=$argn==$m*$d++;echo$c;

在线尝试!

PHP,76字节

使用命令行arg输入php dm.php 18

for(;++$m<13;$d=1)while($d<25+($m-2?$m>4?:7:4))$c+=$argv[1]==$m*$d++;echo$c;

在线尝试!

迭代方法。由于要查看的唯一leap年是2 * 29 = 58,而2058不是not年,因此无需在2月中考虑leap年。而且,由于不必担心周折问题-从4月起,大于25天的任何一天都将超过100天,我们只说剩下的几个月只有25天。

通过命令行输入的是2位数字的年份(程序为-10个字节,@ Titus表示为thx)。

要么:

PHP,101字节

$y=$argv[1];for($d=strtotime("$y-1");date(Y,$d)==$y;$d+=86400)eval(date("$\x+=j*n=='y';",$d));echo$x;

在线尝试!

仍然迭代,但是使用PHP的时间戳函数。接受年份为四位数。向@Titus致谢,以提出使用strtotime()代替的建议mktime()


第一个版本失败4位数字年份,第二个版本失败两位数。但是好主意。尝试$m<5?$m-2?31:28:25第一次和$d=strtotime("$y-1")第二次
Titus

嗯...您为什么y在报价中加上引号?
泰特斯

@Titus because PHP7 now treats digits preceeded with 0 as octal, so 08 and 09 are actually not valid. tio.run/##K8go@G9jXwAkU5Mz8hUMFWxtFQwsrP//BwA Using the date() function you can only get a 2 digit, zero-padded year.
640KB

Bummer! of course.
Titus

1
@Titus, updated second version using strtotime() instead of mktime() and re-implemented as program, -7 bytes. Also, I looked at the majority of the submissions, including the top voted ones, will only accept year as either 2 or 4 digits, so I'm going to take that to mean it is up to submitter. Thx again for the suggestions!
640KB

0

PHP, 74 70 bytes

while(++$m<13)for($d=$m<5?$m-2?31:28:25;$d;)$n+=$d--*$m==$argn;echo$n;

accepts two-digit years only.

I adopted gwaugh´s considerations and golfed them; my 1st approach was longer than his (92 bytes):

for($y=$argn%100;++$m<13;)for($d=$m-2?30+($m+$m/8)%2:29-($y%4>0);$d;)$n+=$d--*$m==$y;echo$n;

%100 allows to use 4-digit years.


Run as pipe with -nR or try them online.


You can save 4 bytes by removing the %100 and only taking 2 digit input, which is OK: codegolf.stackexchange.com/questions/162137/…
640KB
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.