黄金周三


22

黄金周三

您的任务是计算在特定年份的每月黄金时段的星期三的数量。例如,7-13-16是黄金周三。为了保持一致性,请对所有日期使用公历

输入项

您的程序/功能的输入将是一年(例如2016),并且很灵活。年将是一个介于19122233之间的整数。

输出量

输出也很灵活,应为黄金周三的数量(例如18)。

计分

这是因此以字节为单位的最短代码胜出!

测试用例

输入- >输出
--------------------
1912 - > 19
1914 - > 16
1984 - > 17
1996 - > 19
2063 - > 19
2150 - > 16
2199 - > 18
2233- > 18

Answers:


7

MATL38 36 34字节

FT+"@llI$YO]q&:t8XO!s9\~)9#1$ZOZps

在线尝试!验证所有测试用例(花费几秒钟)。

说明

FT+     % Input year implicitly. Add [0 1] element-wise. Gives array with input year
        % and next year
"       % For each of those two years
  @     %   Push year
  ll    %   Push 1 twice. This indicates January 1.
  I$YO  %   Convert year, month, day to serial date number
]       % End for each. We now have the serial date number for January 1 of the input
        % year and that of the following year
q       % Subtract 1 to the latter, to yield December 31 of the input year
&:      % Inclusive range between those two numbers. This gives an array of serial date
        % numbers for the whole input year
t       % Push another copy of that array
8XO     % Convert to date string with format 8. This gives weekday as "Mon", "Tue" etc.
        % The result is a 3-column 2D char array, where each row is a day
!s      % Transpose, sum of each column. 'Wed' gives 288 (sum of ASCII codes)
9\~     % 288 gives 0 modulo 9, and is the only weekday to do so. So we compute modulo 9
        % and negate. This gives true for Wednesdays, false for the rest
)       % Apply as logical index into the array of serial date numbers
9#1$ZO  % Array of month numbers corresponding to those serial date numbers
Zp      % Array that contains true for prime numbers, false for the rest
s       % Sum of array. Display implicitly

我坚信不能在基于日期的挑战中击败MATL。我们应该创建DATL,并将其进一步优化以应对基于日期的挑战。
Suever

@Suever Haha,好听的名字
Luis

20

Python 2,95 93 68 67字节

lambda y:0x10ea2c8dbb06c5619/5**((y+((y-22)/99-y/2002)*16)%28)%5+16

感谢@Josay高尔夫球1个字节!

Ideone上进行测试


3
您可以使用0x10ea2c8dbb06c5619代替保存1个字符19501370182350951961
西尔文

我了解这样的想法,big_constant//5**long_expression但是您在地球上是如何获得这种常数和这种表达的呢?太疯狂了:D
Sherlock9

2
该常数是一个使用5位底数的简单查询表,但是将其转换为10位底数,因此可以数字方式提取数字,而不使用字符串索引。这种表情对我来说就像万年历。(如果限制在1901年到2099年之间,那么问题就太容易了,因为答案在该间隔内每28年重复一次,因此这只是将Year mod 28放在表中查找的情况。 )
尼尔

13

脑高射炮658823102308,2290个字节

首先,我没有编写几乎100%的程序,这可能由程序的庞大规模证明。大部分代码是由我自己的Brain-Flak打高尔夫球算法编写的。我编写了一个附加的python脚本来向正确的方向提示。

在线尝试!

({}<(((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((()()())){}{}){})[()()])())()())[()()()()])())()()())[()()()])()())[()()()])()())[()]))())()())[()()()()])())()()())[()()()])())())[()])[()])()()())[()()])()())[()()()()])()())())[()()])())()())[()()()()])()())[()])()()())[()()])()())[()()()()])()())())[()()])())()())[()()()()])())()()())[()()()])()())[()()()])()())[()]))())()())[()()()()])())()()())[()()()])())())[()])[()])()()())[()()])()())[()()()()])()())())[()()])())()())[()()()()])())()()())[()()()])()())[()()()])()())[()]))())()())[()()()()])())()()())[()()()])())())[()])[()])()()())[()()])()())[()()()()])()())())[()()])())()())[()()()()])())()()())[()()()])()())[()()()])()())[()]))())()())[()()()()])())()()())[()()()])())())[()])[()])()()())[()()])()())[()()()()])()())())[()()])())()())[()()()()])())()()())[()()()])())()())[()()()()])()())())[()()])())()())[()()()()])())()()())[()()()])()())[()()()])()())[()]))())()())[()()()()])())()()())[()()()])())())[()])[()])()()())[()()])()())[()()()()])()())())[()()])())()())[()()()()])())()()())[()()()])()())[()()()])()())[()]))())()())[()()()()])())()()())[()()()])())())[()])[()])()()())[()()])()())[()()()()])()())())[()()])())()())[()()()()])())()()())[()()()])()())[()()()])()())[()]))())()())[()()()()])())()()())[()()()])())())[()])[()])()()())[()()])()())[()()()()])()())())[()()])())()())[()()()()])())()()())[()()()])()())[()()()])()())[()]))())()())[()()()()])())()()())[()()()])())())[()])[()])()()())[()()])()())[()()()()])()())())[()()])())()())[()()()()])())()()())[()()()])()())[()()()])()())[()]))())()())[()()()()])())()()())[()()()])())())[()])[()])()()())[()()])()())[()()()()])()())())[()()])())()())[()()()()])())()()())[()()()])()())[()()()])()())[()]))())()())[()()()()])())()()())[()()()])())())[()])[()])()()())[()()])()())[()()()()])()())())[()()])())()())[()()()()])())()()())[()()()])()())[()()()])()())[()]))())()())[()()()()])())()()())>[(((((((((()()()()())){}{}){}){}){}){}[()]){}){}){}]){({}[()]<{}>)}{}({}<{{}}>)

虽然此程序对于代码高尔夫来说相当长,但对于Brain-Flak来说确实很短。当前,整数除法的世界记录超过1000个字节。

说明

该算法非常简单。因为可用的年数有限(321),所以它简单地以相反的顺序将答案推到输入下,并使用查找算法来找到正确的答案。尽管对321种可能性进行硬编码似乎效率不高,但任务如此复杂,而语言却像脑筋急转弯一样,但它可能是最好的解决方案。(我计划在下周找到答案)。

由于321个数字中的大多数平均大约为18个,并且每年之间差异很小,而不是逐个推送所有数字,因此我通常按第一年(2233),然后重复并逐年更改值后。这样一来,我不必为所有321年的年均付费推销〜18,而只支付每年的〜2。

输入所有答案后,它会从输入中减去1912 ({}[(((((((((()()()()())){}{}){}){}){}){}[()]){}){}){}])(这可能不是最佳选择,我重写了优化程序,以跳过某些我认为不是最佳值的值,因为硬编码数字是超指数过程,将其运行到完成可能需要花费了几天)。

然后,它从第一个元素中减去一个,然后弹出第二个元素,直到结果达到零{({}[()]<{}>)}

它弹出零,{}并且弹出所有在top元素之下的元素({}<{{}}>)


打高尔夫球的一般方法是什么?
尼尔

一个简单的想法是,如果您有一个数为n和m的数,则按n m-1次,然后弹出m-1次。初始推送的计算结果为n,而每个弹出操作的计算结果为附加n,使得(1 + m-1)(n)与mn相同。这是递归完成的,因为要推入n,我们还必须打高尔夫球n。由于此方法不适用于某些数字(尤其是质数),因此我们还环顾四周,看看附近是否有更有效的数字,如果有,我们将其表示为该数字与差之和。
小麦巫师

我看...因此,给定两个数字nm它们的长度为kl,我认为n+m长度为k+l?那n*m
尼尔

n*m会是k+4m-4l+4n-4。这是因为乘法是硬编码的。我们先推n m-1时间。为了做到这一点,我们需要用k符号来表示n和用2m-2符号来表示推送(每个推送是2个符号)。然后我们弹出m-1时间,使我们花费额外的2m-2钱(弹出也要花费2个符号)。总计为k+4m-4。我们还可以乘以m*n(可交换属性)得到l+4n-4。结果将是两者中的较短者。
小麦巫师

1
好吧,如果是真的,那么+1成本2,*2成本4,*3成本8,*4成本12会比贵*2*2,因此不值得(在1000以下的数字中,我仅发现10个未使用的数量*2:1、2、3 ,4、5、9、15、27、45、135)。对于1912年,我能做的最好的是((((((1+1+1)*2+1)*2*2+1)*2+1)*2+1)*2+1)*2*2*2长度为52。–
Neil

7

Bash +通用工具,39

ncal $1|grep W|factor|egrep -c ': \S+$'

将输入年份作为命令行参数。通常将这样的消息输出到STDERR-根据此meta-answer,我认为这是合法的:

factor: We is not a valid positive integer

如果您想显式抑制STDERR输出,则可以用43代替:

ncal $1|grep W|factor 2>-|egrep -c ': \S+$'

请注意,这假定使用英语或C / POSIX语言环境。它不工作这么好gd_GB.utf8,所有的日名称缩写为Di
Toby Speight

6

八度,86字节

无论如何,这并不快。但这并不是代码高尔夫的目标,不是吗?

function r=p(y)r=0;for(i=698346:7:815953)d=datevec(i);r+=d(1)==y*isprime(d(3));end;end

八度可以通过“日期编号”(经过1天1月1日是第1天经过的天数)来跟踪日期。按此度量,1912年1月3日(我们设置的第一个星期三)为698 346天。从此处开始,并每隔第7天(所有星期三)进行迭代,直到2233结束,如果年份是目标年份,而月份是素数,则加1。


5

Python 2.7版,166165,150个字节

from datetime import*
y=input()
d,c=date(y,1,1),0
while d.year==y:n=d.day;c+=n>1<2==d.weekday()>0<all(n%x for x in range(2,n));d+=timedelta(1)
print c

这里肯定还有改进的空间。我对使用python打高尔夫球相当陌生。这将使用datetime模块。如果符合条件,它将遍历一年中的所有天,将一个天添加到累加器中。然后打印结果。大部分繁重的工作都在模块中,因此代码可以很短。

一个字节保存得益于摩根Thrapp和保存的15个字节Pietu1998


1
切换n%x==0到可以节省一个字节n%x<1
Morgan Thrapp '16

2
-1是没有必要像range的最终指标是排他性的。此外,您可以将转换filter为生成器。[0for x in range(2,n)if n%x<1]
PurkkaKoodari

您可以使用any(...)all(...)代替not filter(...)
kennytm

1
通过组合链接的比较,all您可以节省一大堆。c+=n>1<2==d.weekday()>0<all(n%x for x in range(2,n))
PurkkaKoodari

3

J,44个字节

+/@(valdate*3=weekday)@,.&(,/(>:,"0/p:)i.12)

我刚刚发现J具有用于日期操作的内置函数。

用法

额外的命令用于格式化多个输入/输出。

   f =: +/@(valdate*3=weekday)@,.&(,/(>:,"0/p:)i.12)
   (,.f"0) 1912 1914 1984 1996 2063 2150 2199 2233
1912 19
1914 16
1984 17
1996 19
2063 19
2150 16
2199 18
2233 18

说明

+/@(valdate*3=weekday)@,.&(,/(>:,"0/p:)i.12)  Input: year
                                       i.12   The range [0, ..., 11]
                              >:              Increment each to get the months [1, ..., 12]
                                    p:        Get the first 12 primes [2, ..., 37]
                                ,"0/          Make a table between each month and prime
                           ,/                 Join the rows
                       ,.&                    Prepend the year to each
                                              The date format is YYYY MM DD
            3=weekday                         Check if each date occurs on Wednesday
    valdate*                                  and is a valid date
+/@                                           Count the number of true values and return

1

PowerShell v3 +,99 95字节

蛮力法-

param($y)(1..12|%{$m=$_;2,3,5,7,11,13,17,19,23,29,31|?{(date "$m-$_-$y").DayofWeek-eq3}}).Count

接受输入$y,从1到循环12,将月份临时存储到$m,然后从2到循环每个素数31。对于其中的每一个,我们构造Get-Date该特定日期的a,然后仅选择与DayOfWeek -equal相同的日期3(即,星期三)。将所有内容封装在括号中以公式化数组,然后采用数组.Count


另外,数学方法-

PowerShell v3 +,105字节

param($y)(16,19,18,20,16,18,19)[($a=(date "1-1-$y").DayOfWeek)]+(1,-3,0,1,2)[$y%5]*($a-in0,2,3,4)*!($y%4)

结束时的头发要比蛮横的方法长,但我将其包括在这里,因为它可能对其他人有益。

再次将输入$y作为年份。这次,我们将根据一年的第一天进行严格的数学运算。我们首先计算星期几,然后将其存储以$a备后用。该索引到第一个数组中,这使我们得到通常正确的数字。我们必须根据是否是潜在的leap年,是否是星期日,星期二,星期三或星期四,并根据年份来添加第二个索引。

这是基于以下观察。第一列是1月1日是星期几,第二列是通常的输出。除非年份是中间数字之一,否则将改为括号中的数字。最后一栏介绍了%5索引的工作方式。

Jan-1 -> #  ... Except if $y=       (then it's this number) | $y % 5 =
Sun   -> 16 ... 1928 1956 1984 etc. (17)                    |    3
Mon   -> 19
Tue   -> 18 ... 1924 1952 1980 etc. (20)                    |    4
Wed   -> 20 ... 1936 1964 1992 etc. (17)                    |    1
Thur  -> 16 ... 1920 1948 1976 etc. (17)                    |    0
Fri   -> 18
Sat   -> 19

注意:这两个假定均en-us是区域性/日期信息的当前PowerShell设置。DayOfWeek对于其他文化变体,可能需要相应地调整日期格式和数字。


1

Ruby,83 + 15(-rdate -rprime标志)= 98字节

在线尝试!(导入的模块是内联的,因为如果我可以在repl.it中使用标志,则为idk)

->y{k=0;Prime.each(31){|d|k+=(1..12).count{|m|Date.new(y,m,d).wday==3 rescue p}};k}

1

JavaScript的ES6,187个 182 181 179字节

179 在for循环中交换为while循环

z=y=>{D=new Date("1/3/1912");N=0;a=()=>D.getFullYear();b=()=>D.getDate();c=()=>D.setDate(b()+7);for(;a()<=y;c())N+=y-a()?0:-1<[2,3,5,7,11,13,17,19,23,29,31].indexOf(b());return N}

181 压实三元

z=y=>{D=new Date("1/3/1912");N=0;a=()=>D.getFullYear();b=()=>D.getDate();c=()=>D.setDate(b()+7);while(a()<=y){N+=y-a()?0:-1<[2,3,5,7,11,13,17,19,23,29,31].indexOf(b());c()}return N}

182 结合了两个循环

z=y=>{D=new Date("1/3/1912");N=0;a=()=>D.getFullYear();b=()=>D.getDate();c=()=>D.setDate(b()+7);while(a()<=y){N+=a()==y?-1<[2,3,5,7,11,13,17,19,23,29,31].indexOf(b()):0;c()}return N}

187

z=y=>{D=new Date("1/3/1912");N=0;a=()=>D.getFullYear();b=()=>D.getDate();c=()=>D.setDate(b()+7);while(a()<y)c();for(;a()==y;c())N+=-1<[2,3,5,7,11,13,17,19,23,29,31].indexOf(b());return N}

在此示例中,我认为这不算您为特定年份指定的第一个初始星期三。行动

“您的程序/功能的输入将是一年” –但是您要指出的不是那样。我将1912年的第一个星期三用作种子,因为它在OP给定的时间段内隔一个星期三或在每个其他星期三之前,但我也可以很容易地使用1911年或之前的任意星期三进行播种。我函数的输入仍然是一年,并且该函数仍会在OP建议的时间范围内计算任何给定年份的主要星期三的数量,因此我不确定这是否适合挑战。
Pandacoder

抱歉,抱歉……起初我没有意识到您是将其用作播种组件……好主意……尤其是考虑到您的解决方案比我的解决方案快30

1
谢谢。我从Eamon Olive的Brain-Flak实现中汲取了灵感,根据他的解释,该实现实际上已经预先编程了所有答案。
Pandacoder '16

1

批处理,248字节

@set/ad=0,l=1,n=20
@for /l %%i in (1913,1,%1)do @set/ad=(d+l+1)%%7,l=!(%%i%%4)-!(%%i%%100)+!(%%i%%400)
@goto %l%%d%
:03
:06
@set/an-=1
:12
:13
:16
@set/an-=1
:01
:04
:14
@set/an-=1
:00
:05
:10
:15
@set/an-=1
:02
:11
@echo %n%

说明:d是星期几,0周一是星期一,通常是1912年1月1日。l是1912年是否为a年的标志1。然后,我们从1913年循环到输入年份,更新日期。一周,然后重新计算the年标志。最后,我们使用the年标志和星期几来索引确定有效的大切换语句n,即星期三的数量。设置n为20并随秋天递减会比使用流控制逻辑便宜,但结果是,如果非-年的1月1日是星期四或星期日,则在其他情况下会有16个主要星期三,依此类推。


1

JavaScript的ES6 206 203 199 197 195 183 182 179

不是最短的,但我现在能做的最好的。

p=n=>--d-1?n%d&&p(n):1;v=Date;D=(x,y)=>new v(x.setDate(x.getDate()-y));W=a=>eval('for(Z=0,z=D(w=new v(a,11,31),(w.getDay()+4)%7);z>new v(a,0,1);)Z+=~~p(d=z.getDate()),z=D(z,7);Z')

变化:

  1. 从改变三元组分:3>=x?3-x:10-x6-(x+10)%7,节省:3次变更声明位置;
  2. 合并x=w.getDay();z=D(w,6-(x+10)%7)z=D(w,6-(w.getDay()+10)%7),保存:4
  3. 转变Z=0for环路日期声明并推z=D(w,6-(x+10)%7)for环整理,保存:2
  4. w=new Date(a,Z=0,1)声明移入for循环,与现有w声明合并,节省:2
  5. 将主要发现功能重写为主要测试功能,节省:12
  6. 更改+!!~~减少并仍p(d=1)从转换NaN0,从而允许Prime Test功能仍然有效,节省:1
  7. 将所有其他功能移出主调用函数W,重新定义for循环-从12月31日开始相反,将Date对象作为单独的变量写出,然后将for循环重新编写为eval调用;节省3。

@PandaCoder,伙计,我正在赶上你!


1

R,149147字节

y=function(x){s=strftime;b=ISOdate
a=seq(b(x,1,1),t=b(x,12,31),b='d')
length(a[s(a,'%u')==3&trimws(s(a,'%e'))%in%c(2,3,5,7,11,13,17,19,23,29,31)])}

Ideone上进行测试


0

Groovy,126岁

Groovy没有质数验证,因此也必须进行构建。

{n->p={x->x<3||(2..Math.sqrt(x)).every{x%it}};(new Date("1/1/$n")..new Date("12/31/$n")).collect{it[7]==4&&p(it[5])?it:0}-[0]}
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.