感恩节什么时候?


38

背景

有些假期有固定的,容易记忆的日期,例如10月31日,12月25日等。但是,有些假期会很麻烦。它们被指定为“ 9月的第一个星期一”或“ 11月的第四个星期四”之类的东西。我应该怎么知道那是什么时候?

我所知道的是感恩节快到了,所以我需要一个程序来帮助我确定感恩节的时间。甚至有人说现在是明天,因此您的程序需要尽可能短,以确保我可以及时重新输入。

挑战

创建一个程序或功能,给定最多四位数的年份(例如2015或1984),该程序或功能输出或返回该年美国感恩节的日期。根据Wikipedia页面,感恩节定义为11月的第四个星期四。(提示:该页面还包含有关日期模式的一些有趣信息。)

输入:十进制数字,最多四位数字,代表共同时代(CE)中的一年。范例:987、1984、2101

输出:该年中感恩节降落的日期(包括月和日),如果存在的话,降落的日期。这可以是任何合理的格式;用你最好的判断。在所有情况下都应使用公历,即使当时未使用它也是如此。

(注意:确保正确处理handle年!)

测试用例 输入1:

2015

输出1:

Nov 26

输入2:

1917

输出2:

Nov 22

计分

提交内容将以字节计分。我建议您访问该网站,尽管您可以使用任何喜欢的计数器来跟踪您的字节数。

奖金

如果您将BCE日期处理为负数(例如-480将是Thermopylae战斗的年份),则得分的-25%

负测试用例输入:

-480

对应的输出:

Nov 25

这是,因此最低分获胜!

编辑:我将Thomas Kwa的TI-BASIC提交标记为已接受。不要让这种情况阻止您提交新条目!

排行榜

这是一个堆栈片段,用于按语言生成常规排行榜和获胜者概述。

为确保您的答案显示出来,请使用以下Markdown模板以标题开头。

# Language Name, N bytes

N您提交的文件大小在哪里。如果您提高了分数,则可以将旧分数保留在标题中,方法是将它们打掉。例如:

# Ruby, <s>104</s> <s>101</s> 96 bytes

如果要在标头中包含多个数字(例如,因为您的分数是两个文件的总和,或者您想单独列出解释器标志罚分),请确保实际分数是标头中的最后一个数字:

# Perl, 43 + 2 (-p flag) = 45 bytes

您还可以将语言名称设置为链接,然后该链接将显示在页首横幅代码段中:

# [><>](http://esolangs.org/wiki/Fish), 121 bytes


25
对于任何想知道今年感恩节何时到来的人:感恩节将在明天。
TheNumberOne

6
但是我在10月10日有感恩节吗?很抱歉,您的问题来晚了。
JimmyJazzx 2015年

5
@Downgoat使用所需的任何字节计数器。那只是我个人使用并推荐的。
bkul 2015年

22
“某些假期有固定且易于记忆的日期,例如10月31日,12月25日”,这些示例很容易记住,因为它们实际上是同一天:八进制31 ==十进制25。;-)
阿德里安·麦卡锡

7
对于有奖金的答案,是否应该在-1和1之间有0年?
feersum

Answers:


40

TI-BASIC,15字节* 0.75 = 11.25

在我的TI-84 +计算器上测试

1129-dayOfWk(Ans+ᴇ4,9,1

感恩节是11月29日,减去9月1日星期几,其中1是星期日,7是星期六。输出格式为MMDD

测试用例:2015-> 11261917-> 1122-480-> 1125已通过验证。TI-BASIC似乎在所有日期都使用公历。

TI-BASIC不支持负数年份,但这可以得到奖励,因为我们在输入中增加了10000。由于公历的期限为400年,因此这不会更改星期几。


5
哇靠。xD我从没想过会像+1这样工作。
Addison Crump 2015年

好主意加10000。不错。
agtoever

我数了23个字母。这怎么可能是15个字节?
Stephan Schinkel

1
@StephanSchinkel TI-BASIC使用存储在存储器计算器令牌,相信所有的字符这里是1个字节,除了令牌dayofWK(Ans其是2和1字节的每个。
FryAmTheEggman 2015年

您在计算器上测试过吗?哇。

23

PHP,65 48 42 41 36(+2表示-F)= 38字节

<?date(Md,strtotime("4thuXI$argn"));

将输入作为第一个命令行参数。运行带有警告的警告,这是我们的规则可以接受的。打印NovDDDD感恩节在哪里。

没有在线链接,因为ideone不支持命令行args,而且我不知道可以这样做的在线解释器。

感谢Alexander O'Mara教给我一个新的把戏,并感谢primo大大减少了我


2
这比Mathematica更有趣。
lirtosiast 2015年

2
@Tryth甚至更短:"4thuXI"。您甚至可以减少一年之间的间隔"4thuXI2015"
亚历山大·奥玛拉

1
使用命令行选项-F,输入可以缩短为"4thuXI$argn"
2015年

3
等等,这真的有效吗?那就是...那只是...我什至没有...
ETHproductions 2015年

1
为我工作。在执行此操作时,Md不需要引号,并且已E_NOTICE禁用。
primo

18

Mathematica,59 38字节

DayRange[{#,11},{#,12},Thursday][[4]]&

+1聪明。还有WolframAlpha["Thanksgiving " <> #] &在这里以字符串形式输入日期。
DavidC

WolframAlpha将美国的感恩节日期从1863年开始(林肯宣布日期为11月的最后一个星期四)开始。自1789
庆祝

@DavidCarraher但是,OP指出该程序必须至少工作0-9999 CE
LegionMammal978

17

JavaScript(ES6),42 40 31字节-25%= 23.25

a=>28.11-new Date(a,8).getDay()

由于日期“可以采用任何合理的格式”,因此此函数使用DD.MM。我用不同的技术写了一个TeaScript答案,但是这个公式比较短。

说明

由于月份是从零开始的,因此new Date(a,10)返回Date表示指定年份的11月1日的对象。

因为getDay()返回一个代表星期几的数字,所以0..6我们想从

Su Mo Tu We Th Fr Sa 
0  1  2  3  4  5  6  
to to to to to to to
4  3  2  1  0  6  5  

然后添加22。事实证明这(11 - new Date(a,10).getDay()) % 7可以解决问题。正如@Thomas Kwa所指出的,这与28-new Date(a,8).getDay()28减去9月1日的星期几相同。


不错的解决方案,我喜欢它的简短程度,而且它比大多数条目都更容易理解。
MarkoGrešak,2015年

16

Japt43 37 36 35 29字节-25%= 21.75

JaptJa vaScri pt的缩写。

`{28.11-?w D?e(U,8).getDay()}

哈哈哈,我发现了一个真正的骗术:解释器在解压缩字符串时会忽略字符串中的任何括号(用于插入代码),因此我们可以压缩整个源代码以保存>> D字节

这两个?s应该分别是Unicode不可打印的U + 0098和U + 0085。在线尝试!

解压缩后,代码将对此进行评估:

"{28.11-new Date(U,8).getDay()}"

计算结果为:

""+(28.11-new Date(U,8).getDay())+""

给出正确的输出。

使用intrepidcoder的技术,以format输出dd.mm。适当地支持负数年。建议欢迎!

编辑:从12月2日开始,您现在可以使用以下11字节代码(得分为8.25分):

28.11-ÐU8 e

(我希望我能早点实施!)


做得非常好。
bkul

现在,它比原始JavaScript更长。托马斯·夸(Thomas Kwa)的公式要短得多。
intrepidcoder

@intrepidcoder谢谢,已修复。
ETHproductions 2015年

12

Vitsy,44字节

我正在用纯数学公式计算!

打高尔夫球:

Ve2 * V2-V41m + Vaa * Dv1m-Vv4 * 1m + 7M-baa * / + N
/ D1M-

Ungolfed(将方法调用移至第一行以使其可读):

Ve2 * V2-V4 / D1M- + Vaa * Dv / D1M--Vv4 * / D1M- + 7M-baa * / + N

V将输入另存为最终变量。
 e2 *将28推入堆栈。
    V将输入推入堆栈。
     2-减去二。
       V4 / D1M-获取发言权(输入/ 4)。
              +将其添加到总数中。
               Vaa * Dv / D1M-获取发言权(输入/ 100),并保存100作为临时文件
                                    过程中的变量。
                          -从总数中减去。
                           Vv4 * / D1M-获取发言权(输入/ 400)。
                                    +将其添加到总数中。
                                     7M Modulo减7。
                                       -从28中减去结果。
                                        baa * / +添加.11
                                              N输出为数字。

可能有一个更好的算法(这很可能使人震惊),但是对于那些想知道的人,我的算法来自这里

在线尝试!

我是否可以通过计算并获得42字节的奖励积分?梦想破灭了。

感谢@ Hosch250指出我做错了。:D固定。


2
号,但是您从我这里获得+1的
奖励

它说,感恩节在2016年28月,是真的十一月24
Hosch250

@ Hosch250您说得对-已修复。
Addison Crump 2015年

10

Python,38 * 0.75 = 28.5字节

lambda x:28.11-(x-2+x/4-x/100+x/400)%7

尽管我注意到在格里高利历中没有年份0,所以这可以以问题中指定的方式与负年份一起使用,因此这种行为有点令人怀疑。


1
你可以放下f=
feersum

1
否定日期如何运作?Python中的模数是否适用于底片?:O
Addison Crump 2015年

使用字符串代表应该更短一些"Nov "+`...`
xnor 2015年

@VoteToClose Python模给出的答案与第二个参数的符号相同。因此,-40%7==2但是-40%-7==-5
quintopia 2015年

@quintopia等一下,等等,我是个白痴。好的。那讲得通。
艾迪生·克伦普

10

JavaScript(ES6),43.5

实际字节数为58。-25%的奖励适用=> 58 * 0.75 = 43.5

s=>new Date(s,10,(a=new Date(s,10).getDay())<5?26-a:a+21)

没有任何棘手的变通方法或计算,这可能是非常简单而愚蠢的

离线(ES5)+演示:

function t(s) {
    a = new Date(s, 10).getDay();
    alert(new Date(s,10,a<=4?26-a:a+21))
}

t(prompt())

请注意,输入0-100年会产生1900-2000年。但是,从其他答案来看,看起来0-100年与1900-2000年的日期相同。


替换a+1822,因为它仅在“ else”中调用,而“ else”仅在a既不大于也不小于4(即恰好为4)时出现。


替换a<4?26-a:a>4?a+21:22a<=4?26-a:a+21


2
如果我错了,请原谅我,但这不a<4?x:a>4?y:a+18等于a<4?x:a>4?y:22吗?
ETHproductions 2015年

顺便说一句,它告诉我输入0到99之间的年份错误。不过,不确定是否重要。
ETHproductions 2015年

@Eth LOL当然你是对的,并不认为总是4 + 18:D
nicael

@Eth hm,0到99确实是错误的,让我尝试解决这个问题。
nicael

@Eth从其他答案来看,0-100给出的日期与1900-2000相同。
nicael

8

TeaScript,35 33 24字节-25%= 18

28.11-new D(x,8).getDay¡

这与我的JavaScript答案(使用Thomas Kwa的聪明公式)的方法相同。

带有说明的替代版本

r(22,28)F(#/h/t(new D(x,10,l)))+'-11'

r(22,28)    // Range from 22 to 28
        F(    // filter, keeps elements for which the function returns true. 
          #    // Expands to function(l,i,a,b)
           /h/    // RegExp literal, Thursday is the only day with an 'h'.
              t(    // test, true if date string contains an 'h'.
                new D(x,10,l) // Create date object
                             ))+'-11' // Append '-11' for the month.

它是35个字符,但由于¡是36个字节:)
nicael

@nicael不是这个网站,不是;)
ETHproductions 2015年


@Downgoat通常使用这种格式,其中直到U + 00FF的所有字符均为1字节。
ETHproductions 2015年

5

Jython,141155字节

使用具有Python语法的Java Calendar和Scanner类。

import java.util.Scanner as s;import java.util.Calendar as c
d=c.getInstance();k=s(System.in);d.set(c.YEAR,k.nextInt());d.set(c.DAY_OF_WEEK,c.THURSDAY)

编辑:次要语法问题,添加了14个字节。

另请参阅我的Brainfuck版本。


5

Python,83 81 78字节

from datetime import*
lambda a:'Nov '+`((10-datetime(a,11,1).weekday())%7)+22`
  • -2个字节:添加了要导入的名称(感谢@ΚριτικσιΛίθος)
  • -1个字节:更改为* import **(感谢@FryAmTheEggman)
  • -2字节:更改为repr以转换日期(感谢@willem)

1
只是减少字节数的建议:使用import datetime as d,然后您可以d在每次datetime在程序中使用时使用。
Kritixi Lithos

2
您也可以尝试熊猫。import pandas;print'Nov '+`((10-pandas.datetime(input(),11,1).weekday())%7)+22`
威廉2015年

@ΚριτικσιΛίθος但datetime.datetime只能是d.datetime,不是吗?
TanMath

2
from datetime import*即使是短一点,因为你不会需要d.任何更多
FryAmTheEggman

5

Excel中,367 154 53 - 25%= 39.75字节

假定年份以日期格式保存在单元格A1中。返回感恩节的11月中一天的整数。

这仅占正常leap年。它不能说明2100、2200、2300年不是leap年的事实。

它仅设计用于1621年以后-即自感恩节开始以来。(尽管它肯定会一直工作到0 AD)。

=IF(MOD(YEAR(A1),4)=0,IF(WEEKDAY(305+DATEVALUE(("01/01/"&TEXT(A1,"yyyy"))))<6,1127-WEEKDAY(305+DATEVALUE(("01/01/"&TEXT(A1,"yyyy")))),1134-WEEKDAY(305+DATEVALUE(("01/01/"&TEXT(A1,"yyyy"))))),IF(WEEKDAY(304+DATEVALUE(("01/01/"&TEXT(A1,"yyyy"))))<6,1127-WEEKDAY(304+DATEVALUE(("01/01/"&TEXT(A1,"yyyy")))),1134-WEEKDAY(304+DATEVALUE(("01/01/"&TEXT(A1,"yyyy"))))))

精美印刷:

=IF(MOD(YEAR(A1),4)=0,
    IF(WEEKDAY(305+DATEVALUE(("01/01/"&TEXT(A1,"yyyy"))))<6,
       1127-WEEKDAY(305+DATEVALUE(("01/01/"&TEXT(A1,"yyyy")))),
       1134-WEEKDAY(305+DATEVALUE(("01/01/"&TEXT(A1,"yyyy"))))),
    IF(WEEKDAY(304+DATEVALUE(("01/01/"&TEXT(A1,"yyyy"))))<6,
       1127-WEEKDAY(304+DATEVALUE(("01/01/"&TEXT(A1,"yyyy")))),
       1134-WEEKDAY(304+DATEVALUE(("01/01/"&TEXT(A1,"yyyy"))))))

加!我应该以11月1日为基础,而不是基于1月1日的计算,然后进行大量的year年计算来应对2月29日的计算。nb现在可以正确处理2100、2200和2300年了,但实施取决于您Excel安装的默认日期格式。此版本专为dd / mm / yyyy设计:

 =IF(WEEKDAY(DATEVALUE(("01/11/"&TEXT(C1,"yyyy"))))<6,  
     1127-WEEKDAY(DATEVALUE(("01/11/"&TEXT(C1,"yyyy")))),
     1134-WEEKDAY(DATEVALUE(("01/11/"&TEXT(C1,"yyyy")))))

现在,我已经完成了有关在Smalltalk中进行简洁计算的工作,将其回传到Excel结果如下:

=DATE(A1,11,MOD(12-WEEKDAY(DATE(9600+A1,11,1)),7)+22)

(年份仍在A1中,但为整数)。使用Thomas Kwa的日期重复技巧,即使在2100、2200和2300年,也适用于从7700BC / E开始的所有日期。


1
当我尝试使用1900年之前的日期时,它在我的Excel副本中不起作用。
安吉洛·福克斯

长版本不起作用。
安杰洛·福克斯

对于旧日期,请使用Excel User 1900年之前的日期工作簿。< exceluser.com/downloads/examples/post_900_123/index.html >
Euan M

关于是否可以解决这个问题,我认为您不允许只输出11月的日期;您需要某种形式的“ 11月”或“ 11”。
lirtosiast

@Thomas Kwa以日期格式输入日期为年份。然后计算得出11月1日所在的星期几,然后计算11月第四个星期四的日期。
Euan M

4

PowerShell,67 64 84 72 58 45字节

param($a)'Nov';28-(date "00$a/9/1").DayOfWeek

我们将输入整数作为$a,然后立即输出Nov和换行符。然后$a00$a/9/1在生成一个新值date并确定DayOfWeek它是什么之前,将其加零,并在9月1 日前添加。如果9月1日是星期日(.DayOfWeek等于0),则感恩节是28日。如果9月1日是星期一(.DayOfWeek等于1),则感恩节是27号。等等。因此,我们从中减去星期几28以输出答案。

以双零开头的数字表示两位数年份,而不会中断三位数或四位数年份的解析。不适用于负数,因为.NET datetime不支持少于的年份0

感谢TessellatingHecklerToby Speight在此方面的帮助。


"{0:D3}/Nov/$_" -f $a短于"$($a.ToString("000"))/Nov/$_"并产生相同的结果,我想您可以使用11代替Nov
n0rd 2015年

@ n0rd啊,太好了!是的- Nov从我想让它正确识别两位数的年份起就是一个残余,所以我也将其替换掉。谢谢!
AdmBorkBork

@TessellatingHeckler该方法有效,但是您需要在两个零之前加上一位数字的年份,否则您将回到我遇到的20XX。感谢您的协助-我更新了答案。
AdmBorkBork 2015年

1
@TessellatingHeckler在我的系统上,至少要在date "11/1/$a"结果中输入个位数的年份Thursday, November 1, 2007 12:00:00 AM。这是因为我们没有编辑Calendar.TwoDigitYearMax属性,所以当它解析时,我们陷入了双重零填充的问题。
AdmBorkBork

是的是的。是双填充。
TessellatingHeckler,2015年

3

Golfscript,25 * 0.75 = 18.75字节

~.4/.25/.4/2---+7%28\--11

在星期几中使用坂本公式。由于有人在执行此操作,因此输出形式为dd-mm。我以前的提交可以在下面找到:

~.4/.25/.4/2---+7%"Nov "28@-

3

TSQL,478296字节

只是为了好玩。通常,您会使用日期维度表来简化此操作,select * from dimDate where [Year] = @Year and [Holiday] = 'Thanksgiving'但是缺少该功能...

create function a(@y varchar(4))returns date as begin declare @d date,@i int=0 set @d=convert(date,@y+'-11-01')declare @t table(d date,c int identity)while @i<28 begin if datepart(weekday,@d)=5 insert @t(d) select @d select @d=dateadd(d,1,@d),@i+=1 end select @d=d from @t where c=4 return @d end

取消高尔夫:

if exists(select * from sys.objects where name='a' and [type]='FN') drop function a
go

create function a(@y varchar(4))returns date
-- select dbo.a('2015')
as
begin
    declare @d date,@i int=0;

    set @d=convert(date,@y+'-11-01'); -- cannot golf out dashes for dates <year 1000

    declare @t table(d date,c int identity)

    while @i<28 
    begin -- populate "November" array
        if datepart(weekday,@d)=5 insert @t(d) select @d -- assumes @@datefirst = 7
        select @d=dateadd(d,1,@d),@i+=1
    end;

    select @d=d from @t where c=4 

    return @d

end

这真的是最短的方法吗?
lirtosiast

我想我可能不熟悉编码规则,但是答案创建了一个DB对象,该对象接受输入并返回输出以匹配OP。如果可以将输入接受到内联代码中,则可能会发生一些明显的缩短,但这是我对函数对象类型的考虑。我相信无论哪种情况,它都可以打得更远。@ThomasKwa,您有建议吗?
彼得·范迪维尔

好吧,在我看来,您可以使用此答案提及的纯数学公式,而不必理会所有日期对象。
lirtosiast

严格来说,这不是一个纯粹的解决方案,但是阅读该答案肯定给了我一些打出200个字符的想法。谢谢!!
彼得·范迪维尔

(我的意思是(28 - ( x - 2 + floor(x / 4) - floor(x / 100) + floor(x / 400) ) % 7)是的,阅读其他答案往往会有所帮助。
lirtosiast

3

Pyth,30 28 * 75%= 21字节

我100%肯定可以将其简化,但是,这是我的第一个Pyth程序!\ o /

-28.11%+-+-Q2/Q4/Q100/Q400 7

测试套件

dd.mm格式输出日期。

如果可以的话,提出打高尔夫球的方法!我想进一步了解Pyth。


2

Excel, 64 48

A1年

= DATE(A1,11,CHOOSE(WEEKDAY(DATE(A1,11,1)),26,25,24,23,22,28,27))

=DATE(A1,11,MOD(12-WEEKDAY(DATE(A1,11,1)),7)+22)

由于Excel基于本地化,因此我想对此进行测试。请解释这些功能的作用,以便我选择一种适合自己的语言。
安吉洛·福克斯

1
另外,这不适用于1900年以前的日期(至少在我的Excel副本中)
Angelo Fuchs 2015年

此外,保存13在字节TEXT=TEXT(DATE(A1,11,MOD(12-WEEKDAY(DATE(A1,11,1)),7)+22),"d mmm")-输出是不带格式的整数。
user3819867 2015年

@ user3819867,这就是excel存储日期的方式。格式由用户决定
SeanC 2015年

@ AngeloFuchs,DATE使用年,月,日作为参数返回日期值。MOD返回除法的余数(模)。WEEKDAY返回日期的星期几(1 =星期日,2 =星期一,等等)。
SeanC

2

Befunge,41字节

47*&:::4"d"*/\"d"/-\4/++5+7%-" voN",,,,.@

此解释器上运行。

说明: 一个常见年是365 = 1模7天,因此该年加上每4 年,减去每100 d在ASCII)年,加上每400 年占任何飞跃天(包括本年)。:::4"d"*/\"d"/-\4/++然后可以将结果视为3月5 ,即2月之后的第一天,与普通年份的一年的第一天相同。之后,我们通过5+7%-从11月28 47*较早存储)中减去一周中的天数来校准模式。然后打印。

目前,可以对BC年进行更正的版本比奖金规定的更长,为59 -25%= 44.25字节:

47*&v
!`0:<+*"(F"_v#
" voN",,,,.@>:::4"d"*/\"d"/-\4/++5+7%-

2

Matlab,78个字节

x=find(all(bsxfun(@eq,datestr(datenum(input(''),11,1:30),'ddd'),'Thu')'));x(4)

2

Ruby,60 58 57 * 0.75 = 42.75字节

->y{puts"Nov #{[5,4,3,2,1,7,6][Time.new(y,11).wday]+21}"}

58个字节

->y{puts "Nov #{[5,4,3,2,1,7,6][Time.new(y,11).wday]+21}"}

60字节

->y{puts "Nov #{[5,4,3,2,1,7,6][Time.new(y,11,1).wday]+21}"}

取消高尔夫:

-> y {
  puts "Nov #{[5,4,3,2,1,7,6][Time.new(y,11).wday]+21}"
}

用法:

->y{puts"Nov #{[5,4,3,2,1,7,6][Time.new(y,11).wday]+21}"}

=> Nov 26

0

VBA,124字节* 75%= 93字节

Function e(y)
For i = 1 To 7
x = DateSerial(y, 11, 21) + i
If Weekday(x) = 5 Then e = Format(x, "mmm dd")
Next
End Function

我不确定空格是否在102到124之间,可以随时进行编辑。
如果整数是有效的输出,我很乐意删除该Format部分。


空间计数;如果程序不需要它们,则可以将其删除。
lirtosiast

0

PHP 5.3 +,59个字节

这使用PHP内置函数strtotime来解析日期。

<?=gmdate('M d',strtotime("Next Thursday $_GET[Y]-11-19"));

这期望值将通过GET参数Y over 传递php-cli Y=<year>

它会尝试查找11月19日之后的下一个星期四。
到目前为止,通过我进行的测试,它可以正常工作。

请注意,两位数年份的解释可能有所不同。

我曾经gmdate避免时区问题,但是使用它date(至少在我居住的地方)同样有效。


1
答案不是讨论输入法有效性的适当地方。我已经在默认的I / O元帖子中创建了此选项(以便社区可以对其进行投票),并将您的对话移至聊天。(CC @Mego)
丹尼斯

0

T-SQL 215字节 248 * 0.75 = 186字节

create function t(@y int)returns table return select x=convert(char(6),x,107)from(select x=cast(dateadd(dd,d,dateadd(yy,@y-2015+7600,'20151101'))as date)from(select d=21+n from(values(0),(1),(2),(3),(4),(5),(6))b(n))c)t where datepart(weekday,x)=5

不打高尔夫球

set nocount on;
if object_id('dbo.t') is not null drop function dbo.t
go

create function t(@y int)returns table return
    select x=convert(char(6),x,107)
    from (
        select
        x=cast(dateadd(dd,d,dateadd(yy,@y-2015+7600,'20151101'))as date)
        from (
            select d=21+n 
            from (values (0),(1),(2),(3),(4),(5),(6))b(n)
        )c
    )t
    where datepart(weekday,x)=5
go

用这个测试支架

select 
  [ 2015 = Nov. 26]=(select x from dbo.t( 2015))
 ,[ 1917 = Nov. 22]=(select x from dbo.t( 1917))
 ,[ 1752 = Nov. 23]=(select x from dbo.t( 1752))
 ,[ 1582 = Nov. 25]=(select x from dbo.t( 1582))
 ,[ 1400 = Nov. 27]=(select x from dbo.t( 1400))
 ,[ -480 = Nov. 25]=(select x from dbo.t( -480))
 ,[-5480 = Nov. 28]=(select x from dbo.t(-5480))
;
go

所需产量

2015 = Nov. 26  1917 = Nov. 22  1752 = Nov. 23  1582 = Nov. 25  1400 = Nov. 27  -480 = Nov. 25 -5480 = Nov. 28
--------------- --------------- --------------- --------------- --------------- --------------- ---------------
Nov 26          Nov 22          Nov 23          Nov 25          Nov 27          Nov 25          Nov 28

0

派克(Pike87 91107 77 76字节-25%= 57

string t(int y){return"Nov "+((11-Calendar.Day(y,11,1)->week_day())%7+22);}

将旧版本留作比较,因为我发现在利用Calendar模块方面它更聪明,但是上面的代码更短了。

string t(int y){object n=Calendar.Month(y,11);return"Nov "+(n->weeks()->day(4)&n->days())[3]->month_day();}

这似乎没有输入。
彼得·泰勒

是的,我对此感到困惑,有些解决方案具有函数定义,有些仅使用未在任何地方定义的变量,因此我不确定字节数应该使用什么。
eMBee 2015年

我认为您看到的使用“ 未在任何地方定义的变量 ”的答案实际上是在使用非常短的函数声明语法。有一两个答案使用esolangs,它们对stdin进行了特殊处理,因此倾向于编写完整的程序。我不认识Pike,但是如果您可以删除空格并缩写函数名称以获取,string t(int y){object n=Calendar.Month(y,11);return"Nov "+(n->weeks()->day(4)&n->days())[3]->month_day();}那么我会将其计为107个字节。
彼得·泰勒

我以为我已经看到了一些不是函数声明的东西,但是它们似乎已经修复了,只有smalltalk的例子不合适。如果那是有效的,我可以再剃掉一个17字节……
eMBee

Smalltalk版本是作为程序编写的-特别是Workspace表达式。我们被告知,我们得到的是输入,而不是征求输入。
Euan M

0

Smalltalk-Squeak和Pharo69 57 54 49 35 34 33 32-25%= 24字节

“十一月nn”:69B 49B(-25%= 36.75B)
11nn(anInt):57 54 32B(-25%= 24B)

"Year supplied as an integer value, y  
 Result provided as an integer value, 11nn
 Methods Date>>y:m:d: and >>w created as duplicates 
 of year:month:day and weekdayIndex"
(12-(Date y:y m:11d:1)w)\\7+1122

之前的版本

11nn输出

"Year supplied as an integer value, y  
 Result provided as an integer value, 11nn"
(12-(Date year:y month:11 day:1) weekdayIndex)\\7+1122

"Year supplied as an integer value, y  
 Result provided as an integer value, d, prefixed by 11"
d:=(12-(Date year:y month:11 day:1) weekdayIndex)\\7+1122

11月nn输出

"Year supplied as an integer value, y  Result provided as a string, 'Nov nn'"
'Nov ', (12-(Date year:y month:11 day:1) weekdayIndex\\7+22) asString

nn输出

"Year supplied as an integer value, y  Result provided as an integer value, d"
d:=(12-(Date year:y month:11 day:1) weekdayIndex)\\7+22

nb它是作为程序(特别是Workspace表达式)而不是方法提供的。

它假定输入是给定的(按照短语“给定的最多四位数的年份”。
包括声明和给出输入将另外添加11个字符:

|y|y:=2015.(12-(Date y:y m:11 d:1)w)\\7+1122

感谢eMBee,它展示了如何删除又一个char-'w'之前的空格。

实际上,这启发了我尝试删除'd:'之前的空格:
|y|y:=2015.(12-(Date y:y m:11d:1)w)\\7+1122
起作用了!


根据OP的说明,日期编号版本无效。
Mego

我同意-但鉴于列表中有很多只限日数的版本,因此我将其放在了一个苹果对苹果的比较中
Euan M 2015年

0

GNU coreutils,35个字节

seq -f$1-11-2%g 2 8|date -f-|grep h

只需在11月22日至28日的星期中搜索星期四。在C或POSIX语言环境中运行它,因为我认为星期四是唯一包含'h'的缩写。


这是一个比较聪明的答案,尽管更长了一个字节:

echo Nov $((28-`date -d$1-5-5 +%w`))

我们检索3月到9月之间相当任意的一周中某个日期的星期几号(因此,日期和月份各为一位,并且不受可能的leap日的影响)。我们选择的日期是%w==0感恩节在28 日的星期天()。然后,我们可以从28中减去该值以获得适当的星期四。


2
除非运行Sean Connery,否则此方法有效。
bkul 2015年

0

TSQL,53 52字节

DECLARE @ CHAR(4)=2000

PRINT DATEADD(d,59,DATEDIFF(d,1,DATEADD(m,9,@))/7*7)

小提琴

计算9月2日之前或9月2日的星期一,并增加59天

(不如计算10月4日之前或10月4日的星期一并增加31天,因为10月是10月,因此节省了1个字节)


-1

Perl,92个字节

use Time::Local;(localtime(timelocal 0,0,0,$_,10,$ARGV[0]))[6]==4?print "Nov $_":0for 22..28

编辑:固定输出格式,固定错误,例如2012结果,使用较短的“ for”格式。多亏了msh210。


这是更短的代码,并且具有相同的作用:use Time::Local;(localtime(timelocal 0,0,0,$_,10,$ARGV[0]))[6]==4?print:0for 22..29。但是,两个脚本都有相同的缺陷:(1)它们没有按要求打印月份的表示;(2)他们的输出错误,例如2012
。– msh210
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.