ปีที่พิเศษที่สุดที่ใกล้ที่สุดคือปีใด


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 ปีหลังจากนั้นเป็นอีก 6 ปี
Skidsdev

6
@Mayube ไม่มาก ลำดับจริงคือ "6, 11, 11, 6, 11, 11, 6, 11, 11, 6, 12, 11, 11, 11, 11, 11, 11, 11, 11, 11, 12, 11 , 6, 11, 11, 6, 11, 11, 6, 11, 6, 11, 6, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 6, 11 , 11, 6, 11, 11, 6 "(หมายเหตุ 12 และ 6, 11, 6, 6, 11, 6)
Martin Ender

1
เนื่องจากปฏิทินซ้ำทุก ๆ 400 ปีส่วนที่เกี่ยวข้อง (คาบ) ของลำดับคือ "6, 11, 11, 6, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11 , 6, 11, 11, 6, 11, 12, 11, 6, 11, 11, 6, 11, 11, 6, 11, 6, 11, 6, 11, 11, 11, 11, 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 วัน)
John Gordon

คำตอบ:


1

เยลลี่ 30 ไบต์

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

ลิงก์ monadic ที่ใช้และส่งคืนปีจำนวนเต็ม

ลองออนไลน์! หรือดูชุดทดสอบ

อย่างไร?

เช่นเดียวกับคำตอบอื่น ๆ สิ่งนี้จะสร้างรายการของปีที่ต้องการสำหรับโดเมนอินพุตจากการเพิ่มขึ้นและค้นหาปีสูงสุดของความแตกต่างน้อยที่สุดจากอินพุต

“Þıİ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 ครับเพิ่มคำอธิบายเล็กน้อย
Rod

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


4

Mathematica, 70 ไบต์

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

สร้างรายการของปีสามัญพิเศษทั้งหมดจนถึงปี 5040 (= 7!) จากนั้นค้นหารายการที่ใกล้เคียงที่สุดกับอินพุตโดยใช้ค่าสูงสุดในกรณีที่มีการเสมอกัน


นี่คือคำตอบที่ฉันคาดหวังสร้างรายการและเปรียบเทียบกับที่ มันน่าสนใจที่จะดูว่าใครสามารถใช้ "ลำดับ" เพื่อค้นหาคำตอบ
TheLethalCoder

4
Whaaaa ... PHP ชนะ Mathematica เหรอ?
บิชอป

ฉันกำลังเล่นกับรหัสของคุณและมากับสิ่งนี้: (n = 1; t = #; ในขณะที่ [! DayName @ {t} == วันจันทร์ || LeapYearQ @ {t}, n ++; t = # - (- 1 ) ^ n * ชั้น [n / 2]]; t) และคุณสามารถเล่นกอล์ฟนี้ได้โดยแทนที่ด้วย //.t/; etc? ฉันพยายาม แต่ฉันไม่สามารถ ...
J42161217

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;...}
Brian H.

@BrianH เนื่องจากฉันทำการโทรซ้ำซึ่งใช้xดังนั้นหากฉันรีเซ็ตเป็น1ทุกครั้งที่ด้านบนของวิธีการxนั้นไม่ถูกต้องและการโทรซ้ำจะล้มเหลว
Kevin Cruijssen


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

ทับทิม 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})}

กำหนดแลมบ์ดาที่ใช้ปีเริ่มต้นเป็นอินพุต - f[2017] => 2018

ต้องรักห้องสมุดมาตรฐานทับทิม! wday==1มีความยาวเท่ากันmonday?และเย็นน้อยกว่า :) การตรวจสอบปีสามัญพิเศษทำโดยข้อเท็จจริงที่ว่าในปีสามัญที่เริ่มวันจันทร์ที่ 1 มิถุนายนเป็นวันศุกร์ ("วันศุกร์" เป็นชื่อวันที่สั้นที่สุดเท่ากัน!)

น่าเสียดายที่การค้นหาทั้งสองทิศทางไม่ค่อยดีนัก

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.