最近的特殊年份是什么时候?


11

一个常见的一年是一年不是闰年,并在今年的第一天和最后一天是在同一天。一个特殊的普通年是从星期一开始,到星期一也结束。

您面临的挑战是创建一个程序/功能,当给定年份作为输入时,它会查找最接近的特殊普通年份,如果是普通年份,则将自身输出。如果年份与前一年一样接近,则输出更大的年份。

输入值

一个整数,代表要测试的年份,范围为1600 <= x <= 2100

输出量

表示最接近的特殊公共年份的整数。

测试用例

2017 -> 2018
2018 -> 2018
1992 -> 1990
1600 -> 1601
2100 -> 2103
1728 -> 1731 (lies between 1725 and 1731)

笔记

给定范围内的所有54年都已显示在链接的Wikipedia文章中。我还将在这里提供它们以供参考:

1601, 1607, 1618, 1629, 1635, 1646, 1657, 1663, 1674, 1685, 1691
1703, 1714, 1725, 1731, 1742, 1753, 1759, 1770, 1781, 1787, 1798
1810, 1821, 1827, 1838, 1849, 1855, 1866, 1877, 1883, 1894, 1900
1906, 1917, 1923, 1934, 1945, 1951, 1962, 1973, 1979, 1990
2001, 2007, 2018, 2029, 2035, 2046, 2057, 2063, 2074, 2085, 2091
2103 (Needed for 2097 to 2100)

1
仅供参考,以帮助人们,该顺序似乎已过去6, 11, 11。IE浏览器在第一个之后是6年,在另一个之后是11年,在另一个之后是11年,在另一个之后是6年,等等
。– Skidsdev

6
@Mayube不完全是。实际顺序是“ 6、11、11、6、11、11、6、11、6、12、11、11、6、11、11、6、11、11、6、11、12、11 ,6,11,11,6,11,11,6,6,6,6,11,11,11,6,11,11,6,6,11,11,6,6,11,11,6,11 ,11、6、11、11、6”(请注意12和
6、11、6、6、11、6

1
由于日历每400年重复一次,因此序列的相关(周期性)部分为“ 6、11、11、6、11、6、11、11、6、12、11、11、6、11、11 ,6,11,11,6,11,12,11,6,11,11,6,11,11,6,11,6,6,11,6,11,11,11,6,11,11,6 ,11,11“。由于三处违规行为,如果有人可以用它保存字节,我会印象深刻。
Martin Ender

5
为我祝贺2k!:P
TheLethalCoder

1
a year that is not a leap year and where the first and last day of the year are on the same day该定义的第二部分是多余的。所有非-年都在同一天开始和结束,正好是52周零一天(365天)。
约翰·高登

Answers:


1

果冻,30 个字节

“Þıİs|9ṗ[¿¶F’ṃ“©€¿‘⁽£d;+\ạÐṂ⁸Ṁ

取并返回整数年份的单子链接。

在线尝试!或查看测试套件

怎么样?

就像其他答案一样,这会根据增量构建输入域所需的年份列表,并从输入中找到最小绝对差的最大年份。

“Þıİs|9ṗ[¿¶F’ṃ“©€¿‘⁽£d;+\ạÐṂ⁸Ṁ - Main link: number y
                   ⁽£d         - augmented base 250 literal = 1601
“Þıİs|9ṗ[¿¶F’                  - base 250 literal = 20129386383114231907032071
              “©€¿‘            - code page index list = [6,12,11]
             ṃ                 - base decompression = [6,11,11,6,11,11,6,11,11,6,12,11,11,6,11,11,6,11,11,6,11,12,11,6,11,11,6,11,11,6,11,6,6,11,6,11,11,6,11,11,6,11,11,6,11,11,6,11,11,6,11,11,6,12]
                      ;        - concatenate = [1601,6,11,11,6,11,11,6,11,11,6,12,11,11,6,11,11,6,11,11,6,11,12,11,6,11,11,6,11,11,6,11,6,6,11,6,11,11,6,11,11,6,11,11,6,11,11,6,11,11,6,11,11,6,12]
                       +\      - reduce with addition = [1601,1607,1618,1629,1635,1646,1657,1663,1674,1685,1691,1703,1714,1725,1731,1742,1753,1759,1770,1781,1787,1798,1810,1821,1827,1838,1849,1855,1866,1877,1883,1894,1900,1906,1917,1923,1934,1945,1951,1962,1973,1979,1990,2001,2007,2018,2029,2035,2046,2057,2063,2074,2085,2091,2103]
                            ⁸  - link's left argument, y
                          ÐṂ   - filter keep if maximal:
                         ạ     -   absolute difference
                             Ṁ - maximum (alternatively tail, Ṫ, since increasing)

9

PHP,67字节

for(;date(LN,mktime(0,0,0,1,1,$y=$argn+$i))>1;)$i=($i<1)-$i;echo$y;

在线尝试!

要么

for(;date(LN,strtotime("1/1/".$y=$argn+$i))>1;)$i=($i<1)-$i;echo$y;

在线尝试!

展开式

for(;
date(LN,mktime(0,0,0,1,1,$y=$argn+$i)) # N is 1 for Monday and L is 0 for Non leap year
>1;) # loop so long as expression is not 1
  $i=($i<1)-$i; # set $i 0,1,-1,2,-2 ...
echo$y; # Output Year

日期


1
节省一个字节:$i=($i<1)-$i;
Christoph

8

Python 2中129个 124 118字节

a=[11,11,6]*13
a[29:29]=a[19:19]=12,
a[10:10]=6,6
n=input()
o=[2401-n]
for i in a*2:o+=o[-1]-i,
print n+min(o,key=abs)

在线尝试!尝试所有测试用例
首先,在上生成(反转)序列a,然后2401 - input_year将其用作要减去序列的起始值。
这样,列表o将包含所有常见年份与输入之间的差,最近的年份将是最接近零(正或负)的数字,然后将其提取(min, key=abs)并加回到输入中。

datetime119字节

lambda i:i+min([y-i for y in range(2200,1500,-1)if datetime(y,1,1).weekday()<1and y%400],key=abs)
from datetime import*

在线尝试!


这是否会根据序列生成年份列表?
TheLethalCoder

@TheLethalCoder有点,加一点解释

7

05AB1E,41个字节

6xD<Š)•HΘ%A°,SΔA)u•3вè.pO0¸ì1601+DI-ÄWQϤ

在线尝试!

说明

6xD<Š)                                     # push the list [11,6,12]
      •HΘ%A°,SΔA)u•                        # push the number 20129386383114231907032071
                   3в                      # convert to a base-3 digit list
                     è                     # use this to index into the first list
                      .p                   # get list of prefixes
                        O                  # sum each sublist
                         0¸ì               # prepend 0
                            1601+          # add 1601 to each
                                 D         # duplicate
                                  I-       # subtract input from each
                                    Ä      # calculate absolute value
                                     WQÏ   # keep only the years that have the 
                                           # smallest absolute difference from input
                                        ¤  # get the last one

5

JavaScript(ES6),77个字节

f=(y,z=y,d=m=>new Date(y,m,!m||31).getDay()-1)=>d(0)|d(11)?f(z<y?z-1:z+1,y):y
<input type=number value=2001 oninput=o.textContent=f(+this.value)><pre id=o>2001


4

Mathematica,70个字节

Max@Nearest[Select[Range[7!],!LeapYearQ@{#}&&DayName@{#}==Monday&],#]&

生成直到5040年(= 7!)的所有特殊普通年份的列表,然后找到与输入最接近的年份,如果出现平局,则取最大值。


这就是我所期望的答案,生成列表并进行比较。看看是否有人可以使用“序列”来找到答案会很有趣。
TheLethalCoder

4
哇... PHP胜过Mathematica?
主教

我正在研究您的代码,并提出了以下建议:(n = 1; t =#;而[!DayName @ {t} == Monday || LeapYearQ @ {t},n ++; t =#-(-1 )^ n * Floor [n / 2]]; t)&可以通过用//.t/;代替while来打高尔夫球 等等?我尝试了但我做不到...
J42161217 '17

3

Java 7,217个字节

import java.util.*;int c(int y){return d(y,1);}int d(int y,int x){Calendar c=Calendar.getInstance(),d=Calendar.getInstance();c.set(y,0,1);d.set(y,11,31);return c.get(7)==d.get(7)&c.get(7)==2?y:d(y+x,x>0?-++x:-(--x));}

说明:

在这里尝试。

import java.util.*;                   // Required import for Calendar

int c(int y){                         // Method with integer parameter and integer return-type
  return d(y,1);                      //  Call second method with additional parameter
}                                     // End of method (1)

int d(int y,int x){                   // Method (2) with two integer parameters and integer return-type
  Calendar c=Calendar.getInstance(),  //  Create two Calendar instances
           d=Calendar.getInstance();
  c.set(y,0,1);                       //  Set one to 01 January yyyy
  d.set(y,11,31);                     //  and one to 31 December yyyy
  return c.get(7)==d.get(7)           //  If both are the same day of the week
         &c.get(7)==2?                //  and it is a Monday:
          y                           //   Return the input-year
         :                            //  Else:
          d(y+x,                      //   Recursive-call with year + `x`
                x>0?-++x:-(--x));     //   and change `x` to the next to check
                                      //   +1,-2,+3,-4,+5,-6,etc.
}                                     // End of method (2)

如果X是始终将是1,为什么不直接删除INT C(){}和变化int d(int y, int x){}d(int y){int x = 1;...}
布莱恩H.

@BrianH。因为我执行了一个使用的递归调用x,所以如果我1每次在方法顶部将其重置为,x都是不正确的,并且递归调用将失败。
凯文·克鲁伊森


1

C#,183个字节

为了使工作顺利进行,这是我自己完成的一个实现。我很确定它仍然可以打下去,所以如果有人想随意发布它作为新答案。

namespace System.Linq{n=>Enumerable.Range(1,9999).Where(y=>!DateTime.IsLeapYear(y)&(int)new DateTime(y,1,1).DayOfWeek==1).GroupBy(y=>Math.Abs(n-y)).OrderBy(g=>g.Key).First().Last();}

在线尝试!

完整/格式化版本,运行时还会显示给定范围的所有输出。

namespace System.Linq
{
    class Program
    {
        static void Main(string[] args)
        {
            Func<int, int> f = n =>
                Enumerable.Range(1, 9999)
                          .Where(y => !DateTime.IsLeapYear(y)
                                    & (int)new DateTime(y, 1, 1).DayOfWeek == 1)
                          .GroupBy(y => Math.Abs(n - y))
                          .OrderBy(g => g.Key)
                          .First()
                          .Last();

            for (int y = 1600; y <= 2100; ++y)
            {
                Console.WriteLine($"{y} -> {f(y)}");
            }

            Console.ReadLine();
        }
    }
}

1

Ruby,145个字节

f=->i{i+(1.upto(i).map{|m|Time.new(y=i+m).monday?&&Time.new(y,6).friday?? m:Time.new(y=i-m).monday?&&Time.new(y,6).friday?? -m :nil}.find{|a|a})}

定义一个以开始年份为输入的lambda- f[2017] => 2018

一定喜欢Ruby标准库!wday==1的长度monday?与酷一样长:)。特殊的普通年检查是通过以下事实进行的:在一个普通年中,从6月1日星期一开始是星期五(“星期五”是最短的同等日期名称!)

不幸的是,它不能很好地双向搜索。

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.