128 yıl mı? Varsayısal artık yıl reformu


23

Güneş yılı bu videoya göre 365 gün, 5 saat, 48 dakika, 45 saniye ve 138 milisaniyedir . Mevcut Gregoryen takvimi ile artık yıllar için kurallar aşağıdaki gibidir:

if      year is divisible by 400, LEAP YEAR
else if year is divisible by 100, COMMON YEAR
else if year is divisible by 4,   LEAP YEAR
else,                             COMMON YEAR

Ne yazık ki, bu yöntem her 3216 yılda bir gün kapalıdır.

Takvimi yeniden düzenlemenin olası bir yöntemi şu kuraldır:

if      year is divisible by 128, COMMON YEAR
else if year is divisible by 4,   LEAP YEAR
else,                             COMMON YEAR

Bunun, takvimlerimizi 625.000 yıl daha tekrar etmemizi, almamızı veya almamızı istememesinin yararı vardır.

Diyelim ki tüm dünya, şimdiden başlayarak, her dördüncü yılın bu sistemini kullandığımızdan, her 128'inci yıl hariç, takvimimizi aşağıdaki şekilde değiştirdiğimize karar veriyor:

YEAR    GREGORIAN    128-YEAR
2044    LEAP         LEAP
2048    LEAP         COMMON
2052    LEAP         LEAP
 ...
2096    LEAP         LEAP
2100    COMMON       LEAP
2104    LEAP         LEAP
 ...
2296    LEAP         LEAP
2300    COMMON       LEAP
2304    LEAP         COMMON
2308    LEAP         LEAP

Bu, haftanın gün algoritmalarımızı nasıl etkiler?

Meydan okuma

  • 2000 yılından 100000 yılına kadar bir tarih verildiğinde, bu yeni takvime göre haftanın gününü bulun.
  • Hangi girişleri kullandığınızı açıkça belirttiğiniz sürece herhangi bir giriş ve çıkış formatına izin verilir.
  • Bu kod golf, bu yüzden çözümlerinizi olabildiğince golf yapmaya çalışın!

Test durumları

"28 February 2048" -> "Friday"
"March 1, 2048"    -> "Sat"
(2100, 2, 29)      -> 0           # 0-indexed with Sunday as 0
"2100-02-29"       -> 7           # 1-indexed with Sunday as 7
"28 Feb. 2176"     -> "Wednesday"
"1-Mar-2176"       -> "Th"
"28/02/100000"     -> "F"         # DD/MM/YYYYYY
"Feb. 29, 100000"  -> 6           # 1-indexed with Sunday as 7
"03/01/100000"     -> 1          # MM/DD/YYYYYY and 1-indexed with Sunday as 1

Mücadele ile ilgili öneri ve geri bildirim bekliyoruz. İyi şanslar ve iyi golf!


Test durumu # 4 için, 1 indeksli demek istiyorsun, değil mi? Aksi takdirde, o hafta 8 gün olması gerekirdi.
Sebastian

Ayrıca, "iyi golf" diyorsun, bu # kodlu bir golf mücadelesi mi? Öyleyse, kazanan ölçütleri girin (örneğin en düşük bayt / karakter sayısı) ve bunu etiket olarak ekleyin.
Sebastian

@Sebastian Her iki durumda da haklısınız. Mücadeleyi zaten düzenlemiştim. Geri bildiriminiz için teşekkür ederiz
Sherlock9

1
Başlığı okurken Matt Parker'ın videosu olsa bile derhal. Konuda da bağlı görmek güzel: D
PattuX

1
Standart haftanın günü kütüphanelerini alın ve global sabitleri buna göre değiştirin, değil mi? ;)
Wildcard

Yanıtlar:


8

C (gcc) , 60 bayt

f(m,d,y){y-=m<3;return(y+y/4-y/128+"-bed=pen+mad."[m]+d)%7;}

Çevrimiçi deneyin!

Sakamoto'nun yönteminde basit değişiklik . Siparişte tam sayı argümanları olarak girdiyi alır month, day, yearve günün sayısını gösterir (Pazar günü 0 dizinli).


"-bed=pen+mad."Parça ne yapar ?
ericw31415

@ ericw31415 Günlerde her ayın uzunluğunu gösterir ve sadece görünüm adına, sıralı karakterlerden ziyade 7'nin katları kadar kaydırılır (31, 28 ...).
notjagan

Doğru, charhala bir sayıyı temsil ettiğini unuttum , böylece mod 7doğrudan yapabilirsin .
ericw31415,

6

Wolfram Dili (Mathematica) , 57 55 53 bayt

DayName@{m=#~Mod~128;6+Mod[(9#-m)/8-6Clip@m,28],##2}&

Çevrimiçi deneyin!

Üç girdi alır: bu siparişte yıl, ay ve gün. Örneğin, yukarıdaki işlevi olduğu gibi kaydederseniz fun, o zaman fun[2048,2,28]28 Şubat 2048 haftanın gününü söyler.

Nasıl çalışır

Formül m=#~Mod~128;6+Mod[(9#-m)/8-6Clip@m,28], yıl 6 ile 33 arasında, eşdeğer bir yıla (haftanın aynı günlerine sahip bir yıl) dönüştürür. Bunu yapmak için, bir ofset çıkartır ve sonra mod 28'i alırız; ancak ofset her 128 yılda bir değişir ve 128 ile bölünebilen yıllar boyunca, daha fazla düzeltme yapmamız gerekir, çünkü eşdeğer yıl artık yıl olmamalıdır.

Her neyse, bir kez yapıldıktan sonra, yerleşik olanı kullanarak aynı yıl içindeki ay ve günü araştırırız DayName.



3

JavaScript, 65 59 bayt

(d,m,y)=>(y-=m<3,(+"0032503514624"[m]+y+(y>>2)-(y>>7)+d)%7)

(d,m,y)=>(y-=m<3,(+"0032503514624"[m]+~~y+~~(y/4)-~~(y/128)+d)%7)

Sakamoto'nun yöntemini kullanır. verir0=Sunday, 1=Monday, 2=Tuesday...

Misha Lavrov sayesinde -2 bayt
Arnauld sayesinde -4 bayt


1
Bence ~~ysadece değiştirilebilir y. Girdide kesirli bir yıl almayacaksın, değil mi? Ancak kabul ediyorum, JavaScript’te akıcı değilim.
Misha Lavrov

2
Ne dersiniz +y+(y>>2)-(y>>7)?
Arnauld,

@MishaLavrov Evet, bu doğru. Bazı nedenlerden dolayı herşeyi döşemem gerektiğine karar verdim.
ericw31415,

2

Aslında , 37 bayt

Bu bir liman notjagan modifikasyonuna ait Sakamoto algoritması , ancak birkaç yığın tabanlı hile ile aşağıda tarif edildiği gibi. Giriş formatı day, year, month. Çıktı formatı 0-indexed with Sunday as 0. Golf önerileri hoş geldiniz! Çevrimiçi deneyin!

;"0032503514624"Ei)3>±+;¼L;¼¼½L±kΣ7@%

açıklama

                     Implicit input: day, year, month (month is at TOS)
;"0032503514624"Ei)  Get the month code, convert to float, rotate to bottom of the stack
3>±+                 If 3>month, add -1 to year
;¼L                  Push floor(year/4) to stack
;¼¼½L±               Push floor(year/4) and append -floor(year/128) to stack.
kΣ                   Wrap the stack (y/128, y/4, y, month_code, d) in a list and sum
7@%                  Get the sum modulo 7
                     Implicit return

2

Jelly , 32 31 30 28 bayt

Başka limanı notjagan en modifikasyon ait Sakamoto algoritması ama yerine bir baz-250 sayı ile 032503514624(ekstra gerekmez 0Jelly 1-endeksli olduğu için). Giriş formatı month, year, day. Çıktı formatı 0-based with Sunday as 0. Golf önerisi, bağlantıların düzenlenmesi zor olduğu ve hala golf oynayabildiği için son derece açıktır. Çevrimiçi deneyin!

Düzenleme: tamsayı bölme yerine bit kaydırma kullanmadan -1 bayt. -1 bayt başlangıç ​​ve giriş formatını yeniden düzenler. Erik Bayramcı ve caird coinheringaahing sayesinde -2 bayt.

3>_@µæ»7,2I+µ“Ṿ⁵Ḥ9{’D³ị+⁵+%7

açıklama

         Three arguments: month, year, day
3>_@     Subtract (month<3) from year. Call it y.
µ        Start a new monadic chain.
æ»7,2    Bit shift y by both 7 and 2 (equivalent to integer division by 128 and by 4).
I+       y + y/4 - y/128
µ        Start a new monadic chain.
“Ṿ⁵Ḥ9{’  The number 732573514624 in base 250.
D        The list [7, 3, 2, 5, 7, 3, 5, 1, 4, 6, 2, 4].
³ị       Get the month code from the list (1-based indexing).
+⁵+      Add y, our month code, and day together.
%7       Modulus 7.

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.