Khi nào là năm chung đặc biệt gần nhất?


11

Một năm chung là một năm không phải là năm nhuận và trong đó ngày đầu tiên và ngày cuối cùng của năm là cùng một ngày. Một năm chung đặc biệt là một năm bắt đầu vào thứ Hai và do đó cũng kết thúc vào thứ Hai.

Thách thức của bạn là tạo ra một chương trình / chức năng mà khi được đưa ra một năm khi đầu vào tìm thấy năm chung đặc biệt gần nhất, sẽ tự xuất nếu đó là một năm chung. Nếu năm gần với năm trước thì năm đó sẽ xuất ra năm lớn hơn.

Đầu vào

Một số nguyên biểu thị năm để kiểm tra trong phạm vi 1600 <= x <= 2100.

Đầu ra

Một số nguyên đại diện cho năm chung đặc biệt gần nhất.

Các trường hợp thử nghiệm

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

Ghi chú

Tất cả 54 năm trong phạm vi nhất định đã được hiển thị trong bài viết Wikipedia được liên kết. Tôi cũng sẽ cung cấp chúng ở đây để tham khảo:

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
chỉ để tham khảo để giúp mọi người, trình tự xuất hiện 6, 11, 11. IE 6 năm sau cái đầu tiên là cái khác, 11 năm sau đó là cái khác, 11 năm sau đó là cái khác, 6 năm sau đó là cái khác, v.v.
Skidsdev

6
@Mayube Không hẳn. Trình tự thực tế là "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 "(lưu ý 12 và 6, 11, 6, 6, 11, 6)
Martin Ender

1
Vì lịch lặp lại sau mỗi 400 năm, phần liên quan (định kỳ) của chuỗi là "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 ". Tôi sẽ rất ấn tượng nếu bất cứ ai cũng có thể lưu byte bằng điều này, do ba điều bất thường.
Martin Ender

5
Chúc mừng 2k cho tôi! : 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 dayPhần thứ hai của định nghĩa đó là dư thừa. Tất cả các năm không nhảy vọt đều bắt đầu và kết thúc vào cùng một ngày, chính xác là 52 tuần và một ngày (365 ngày).
John Gordon

Câu trả lời:


1

Thạch , 30 byte

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

Một liên kết đơn âm lấy và trả về một năm nguyên.

Hãy thử trực tuyến! hoặc xem một bộ thử nghiệm .

Làm sao?

Giống như các câu trả lời khác, điều này xây dựng danh sách các năm cần thiết cho miền đầu vào từ số gia và tìm ra năm tối đa của chênh lệch tuyệt đối tối thiểu so với đầu vào.

“Þıİ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 byte

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

Hãy thử trực tuyến!

hoặc là

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

Hãy thử trực tuyến!

Mở rộng

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

ngày


1
Lưu một byte:$i=($i<1)-$i;
Christoph

8

Python 2 , 129 124 118 byte

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)

Hãy thử trực tuyến! hoặc Thử tất cả các trường hợp kiểm tra
Đầu tiên, chuỗi được tạo (đảo ngược) trên a, sau đó 2401 - input_yearđược sử dụng làm giá trị bắt đầu để được trừ trên chuỗi.
Bằng cách này, danh sách osẽ chứa sự khác biệt giữa tất cả các năm chung và đầu vào, năm gần nhất sẽ là số gần nhất với 0 (dương hoặc âm), sau đó sẽ được trích xuất (min, key=abs)và thêm lại vào đầu vào.

Với datetime, 119 byte

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*

Hãy thử trực tuyến!


Điều này có tạo ra danh sách các năm dựa trên trình tự không?
TheLethalCoder

@TheLethalCoder kinda, thêm một lời giải thích
Rod

7

05AB1E , 41 byte

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

Hãy thử trực tuyến!

Giải trình

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 byte

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

Toán học, 70 byte

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

Tạo danh sách tất cả các năm phổ biến đặc biệt cho đến năm 5040 (= 7!) Và sau đó tìm danh sách gần nhất với đầu vào, lấy mức tối đa trong trường hợp hòa.


Đây là loại câu trả lời tôi đang mong đợi, tạo danh sách và so sánh với nó. Sẽ rất thú vị để xem liệu có ai có thể sử dụng "trình tự" để tìm câu trả lời hay không.
TheLethalCoder

4
Whaaaa ... PHP đánh bại Mathicala?
giám mục

Tôi đã chơi xung quanh với mã của bạn và đã đưa ra mã này: (n = 1; t = #; While [! DayName @ {t} == Thứ hai | | LeapYearQ @ {t}, n ++; t = # - (- 1 ) ^ n * Tầng [n / 2]]; t) & bạn có thể đánh gôn này bằng cách thay thế trong khi bằng //.t/; Vân vân? Tôi đã thử nhưng tôi không thể ...
J42161217

3

Java 7, 217 byte

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));}

Giải trình:

Hãy thử nó ở đây.

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)

nếu x luôn luôn là 1, tại sao không xóa int c () {} và đổi int d(int y, int x){}thànhd(int y){int x = 1;...}
Brian H.

@BrianH. Bởi vì tôi thực hiện một cuộc gọi đệ quy sử dụng x, vì vậy nếu tôi đặt lại cuộc gọi đó 1mỗi lần ở đầu phương thức thì xkhông chính xác và cuộc gọi đệ quy sẽ thất bại.
Kevin Cruijssen


1

C #, 183 byte

Để làm cho quả bóng lăn một chút, đây là một triển khai tôi đã thực hiện. Tôi khá chắc chắn rằng nó vẫn có thể được chơi golf vì vậy nếu bất cứ ai muốn cảm thấy thoải mái để đăng như một câu trả lời mới.

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();}

Hãy thử trực tuyến!

Phiên bản đầy đủ / được định dạng, điều này cũng hiển thị tất cả các kết quả đầu ra cho phạm vi nhất định khi chạy.

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 byte

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})}

Xác định lambda lấy năm bắt đầu làm đầu vào - f[2017] => 2018

Phải yêu thư viện tiêu chuẩn Ruby! wday==1có cùng độ dài monday?và vô cùng ít mát mẻ :). Việc kiểm tra năm chung đặc biệt được thực hiện bởi thực tế là trong một năm chung bắt đầu từ thứ Hai, ngày 1 tháng Sáu là thứ Sáu ("thứ sáu" là tên ngày ngắn nhất bằng nhau!)

Thật không may, nó không tốt trong việc tìm kiếm theo cả hai hướng.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.