En yakın özel ortak yıl ne zaman?


11

Bir ortak yıl artık yıl ve nerede yılın ilk ve son günü aynı gün olan olmayan bir yıldır. Bir özel ortak yıl biri o Pazartesi günü uçlarında Pazartesi günü ve böylece başlar yanı olduğunu.

Zorluğunuz, girdi olarak bir yıl verildiğinde en yakın özel ortak yılı bulan ve ortak bir yıl olması durumunda çıktı veren bir program / işlev oluşturmaktır. Yıl, bir yıl öncesine yakınsa, daha büyük bir yıl çıkar.

Giriş

Aralıkta test edilecek yılı temsil eden bir tam sayı 1600 <= x <= 2100.

Çıktı

En yakın özel ortak yılı temsil eden bir tam sayı.

Test senaryoları

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

notlar

Belirli bir aralıktaki 54 yılın tamamı zaten bağlantılı Wikipedia makalesinde gösterilmektedir. Ben de burada referans için sağlayacaktır:

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
sadece insanlara yardım etmek için referans için, dizi gidiyor gibi görünüyor 6, 11, 11. IE ilk 6 yıl sonra bir diğeri, 11 yıl sonra bir başka, 11 yıl sonra bir başka, 6 yıl sonra bir başka, vb.
Skidsdev

6
@Mayube Pek değil. Gerçek dizi "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'leri ve 6, 11, 6, 6, 11, 6'yı not edin)
Martin Ender

1
Takvim her 400 yılda bir tekrarlandığından, dizinin ilgili (periyodik) kısmı "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 ". Üç düzensizlik nedeniyle bununla bayt kurtarabilecek olursam çok etkileneceğim.
Martin Ender

5
Tebrikler 2k benim için! : 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 dayBu tanımın ikinci kısmı gereksizdir. Sıçramayan tüm yıllar aynı gün başlar ve biter, tam 52 hafta ve bir gün (365 gün) uzunluğundadır.
John Gordon

Yanıtlar:


1

Jöle , 30 bayt

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

Tamsayı bir yıl alan ve dönen monadik bir bağlantı.

Çevrimiçi deneyin! veya bir test takımına bakın .

Nasıl?

Diğer cevaplara çok benzer şekilde, bu, girdi alanı için artışlardan gerekli yılların listesini oluşturur ve girdiden minimum mutlak farkın maksimum yılını bulur.

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

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

Çevrimiçi deneyin!

veya

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

Çevrimiçi deneyin!

Expanded

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

tarih


1
Bir bayt kaydet:$i=($i<1)-$i;
Christoph

8

Python 2 , 129 124 118 bayt

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)

Çevrimiçi deneyin! veya Tüm test senaryolarını deneyin
Önce, sekans oluşturulur (ters çevrilir) a, daha sonra 2401 - input_yearsekansın çıkarılması için başlangıç ​​değeri olarak kullanılır.
Bu şekilde liste otüm ortak yıllar ve girdi arasındaki farkları içerecektir, en yakın yıl sıfıra en yakın sayı (pozitif veya negatif) olacak, daha sonra çıkartılacak (min, key=abs)ve girdiye geri eklenecektir.

İle datetime119 bayt,

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*

Çevrimiçi deneyin!


Bu, sıralamaya göre yılların listesini oluşturuyor mu?
TheLethalCoder

@TheLethalCoder tür, biraz açıklama ekledi
Rod

7

05AB1E , 41 bayt

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

Çevrimiçi deneyin!

açıklama

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 bayt

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 bayt

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

5040 yılına kadar (= 7!) Tüm özel ortak yılların bir listesini oluşturur ve daha sonra bir bağlantı durumunda maksimum değeri alarak girdiye en yakın olanı bulur.


Bu beklediğim cevaptı, listeyi oluşturdum ve onunla karşılaştırdım. Bir cevap bulmak için herhangi birinin "diziyi" kullanıp kullanamayacağını görmek ilginç olurdu.
TheLethalCoder

4
Whaaaa ... PHP Mathematica'yı yeniyor mu?
piskopos

Kodunuzla oynuyordum ve bununla geldim: (n = 1; t = #; [! DayName @ {t} == Pazartesi || LeapYearQ @ {t}, n ++; t = # - (- 1 ) ^ n * Kat [n / 2]]; t) & //.t/ ile değiştirerek bunu golf oynayabilir misiniz; vb? Denedim ama yapamam ...
J42161217

3

Java 7, 217 bayt

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

Açıklama:

Burada deneyin.

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 hep 1 olacak, neden sadece int c () {} ve değişim kaldırmak int d(int y, int x){}içind(int y){int x = 1;...}
Brian H.

@BrianH. Ben kullanan bir özyinelemeli çağrı yapmak x, bu yüzden 1yöntemin en üstünde her zaman sıfırlarsanız x, yanlış ve özyinelemeli çağrı başarısız olur.
Kevin Cruijssen


1

C #, 183 bayt

Topu biraz yuvarlamak için, burada kendi başıma yaptığım bir uygulama var. Eminim hala golf olabilir böylece kimse yeni bir cevap olarak göndermek için çekinmeyin.

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

Çevrimiçi deneyin!

Tam / Biçimli sürüm, bu aynı zamanda çalıştırıldığında verilen aralık için tüm çıkışları gösterir.

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 bayt

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

Başlangıç ​​yılını girdi olarak alan bir lambda tanımlar - f[2017] => 2018

Ruby standart kütüphanesini sevmeliyim! wday==1ile aynı uzunluktadırmonday? ve sonsuz daha az serin :). Özel ortak yıl kontrolü, 1 Haziran Pazartesi günü başlayan ortak bir yılda bir Cuma ("Cuma" eşit en kısa gün adıdır!)

Ne yazık ki, her iki yönde de arama yapmak o kadar iyi değil.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.