Devrilme Takvimi


17

Bu, Downgoat'ın Sandbox'daki sorularından esinlenerek, gün / ay biçimini kullanan insanlar için 31 Nisan'ı Pi günü olarak eklemesini önerdim, sadece bana 31 Nisan olmadığını bildirmesi için!

Geçersiz olabilecek ay / gün biçiminde bir tarih dizesi verildiğinde , rollover'ı kullanarak doğru tarihi çıktılayın. (Önce ayı, ardından günü çevirin).

Örnekler:

"15/43" - Bu, 15. ayın 43. günü olarak okunur. İlk olarak, ay boyunca bir sonraki yıla yuvarlanıyoruz, bu yüzden 3 (Mart) ile bitiyoruz. Şimdi, Mart ayının sadece 31 günü olduğundan, ekstra günleri Nisan ayına devrediyoruz , bu nedenle gerçek tarihi "4/12" (12 Nisan) olarak çıkardık .

"3/16" - Bu geçerli bir tarih (16 Mart). Olduğu gibi iade edin.

"12/64" - Ah, 64 Aralık'tan pek çok düşkün anı ... Aralık 31 gün, Ocak 31 gün var, bu yüzden gerçekten demek istediğim "2/2" (2 Şubat).

"19/99" - İlk olarak 19, 7 olur (Temmuz). Temmuz 31 gün, Ağustos 31 gün, Eylül 30 gün vardır, bu nedenle çıktı "10/7" (7 Ekim).

"1/99999" - Bir yılda 365 gün vardır. 99999 (mod 365) = 354. Yılın 354 günü "12/20" .

"9999999/10" - Görünüşe göre 9999999 (mod 12) = 3, yani bu "3/10" (10 Mart).

Kriter:

Giriş ayı> 0 tamsayısıdır. Giriş günü> 0 tamsayısıdır. Yıl asla belirtilmemelidir, çünkü başa çıkmak için artık yıl yoktur.

Güncelleme:

Meydan okumayı aşırı derecede basitleştireceğini düşündüğüm için, Java Takvim sınıfındaki gibi takvim işlevleri yasaklandı. Tarih ayrıştırma / biçimlendirme işlevlerine yine de izin verilir.



1
Bir başka önemli test örneği, 8 yıldan fazla sürecek yeterli güne sahip bir örnek olacaktır, böylece yerleşik kullanan cevaplar artık yıl kullanan yerleşiklere dikkat etmek zorundadır.
Martin Ender

Ah, buna cevap veriyor ... Yerleşik bir Mathematica cevabı göndermek üzereydim. : /
Martin Ender

@Martin Üzgünüm;).
geokavel

Referans olarak, Mathematica çözümü hala 90 bayt uzunluğundaydı (dize işlemenin büyük ölçüde baskın olmasına rağmen). Yine de böyle bir test örneği eklemek istiyorsanız, bence 1/99999vermelidir 12/19.
Martin Ender

Yanıtlar:


11

Bu hızlı oldu.
Addison Crump

Burada kullanılan takvim işlevi olmadığından emin olabilir misiniz?
geokavel

LabVIEW ile ilgili iyi bir şey, temelde ne göründüğüdür. İlk şey bir dize 2 modülden sayıları tarar, kutu 28,30 veya 31 veren bir anahtar kutusu yapısıdır ve daha sonra tekrar dize olarak bir araya getirilir.
Eumel

4

C # 269 223

string v(string n){var x=new[]{31,28,31,30,31,30,31,31,30,31,30,31};var s=n.Split('/');Func<string,int> p=int.Parse;var m=p(s[0]);var d=p(s[1]);m=m>=12?m%12:m;while(d>x[m]){d-=x[m];m=++m>=12?m%12:m;}return(m==0?1:m)+"/"+d;}

Düzenleme : 24/1, 36/1, vb.Gibi durumlarda çalışmak için düzeltildi ve biraz golf oynadı. Yorumlar için teşekkürler, biraz kaydettiğim birkaç yer var!

Ungolfed:

string v(string n)
{
    var x = new [] { 31 ,28, 31, 30, 31, 30,31, 31, 30, 31, 30, 31 };

    var s = n.Split('/');
    Func<string,int> p = int.Parse;
    var m = p(s[0]);
    var d = p(s[1]);
    m = m >= 12 ? m % 12 : m;
    while (d > x[m])
    {
        d -= x[m];
        m = ++m >= 12 ? m % 12 : m;
    }
    return (m==0?1:m) + "/" + d;
}

Her şeyden önce: Topluluğa hoş geldiniz! Ben bir döngü içinde sözlük atayarak veya bir anahtar işlevi (burada olsa hiçbir C # pro) kullanarak bazı Baytlar kaydedebilirsiniz sanırım. Ayrıca doğrudan ´m + "/" + d´ yazdırmak biraz yardımcı olabilir. Ve sonuncusu (bu işe ya da çalışmayabilir) argümanlarda dize yerine char * kullanarak.
Eumel

Bu, belirli test durumlarında başarısız olur, örn 24/1.
LegionMammal978

@Eumel teşekkürler! Doğrudan baskı Console.Writedaha fazla olan kullanımları returnve C # yerine ben kullanmak char[]yerine string, ama aynı miktarda karakter, ve /daha sorunlu bölme yapar . Ama, Sözlük'teki notun beni daha iyi bir versiyona götürdü!
DrewJordan

4

R 208 182 bayt

m=c(31,28,31,30,31,30,31,31,30,31,30,31)
e=scan(sep="/");n=(e[1]/12-1)*12;if(!n%%12)n=12;if(n<0)n=e[1];j=e[2];while((j<-j-m[n])>0){n=n+1;if(n>12)n=1};j=m[n]+j;cat(n,j,sep="/")

12'ye bölerek ayı elde edin, ardından döngü yapın, negatif bir sayı elde edene kadar geçerli ayın gün sayısını kaldırın., Son adımı tersine çevirin ve yazdırın.

Birden çok satırda (bir dosyayı kullanmanız ve kaynaklamanız gerekir):

m=c(31,28,31,30,31,30,31,31,30,31,30,31)
e=scan(sep="/")
n=(e[1]/12-1)*12
if(!n%%12)n=12
if(n<0)n=e[1]
j=e[2]
while((j<-j-m[n])>0){n=n+1;if(n>12)n=1}
j=m[n]+j;cat(n,j,sep="/")

Programınızı R'de çalıştırmaya çalışırken aldığım mesaj: pastebin.com/dPh1n64a
geokavel

Daha sonra tekrar kontrol edeceğim garip
Tensibai

Bu mesajı da aldım. Programınızın birkaç ayla ilgili sorunları var gibi görünüyor. Aksi halde çalışıyor. pastebin.com/g3BCUDi8
geokavel

Geri dönüşünüz için teşekkür ederiz. Aslında yoldayım, düzelteceğim
Tensibai

1
@Tensibai evet haklısın, benim kötü (hata mesajı "gerçek" beklediğini söyledi hatırlamalıydım).
plannapus

3

PHP> = 5.5, 181 bayt

list($m,$d)=explode("/",$argv[1]);$m%=12;$d%=365;$i=0;while($d>100)$d-=[31,28,31,30,31,30,31,31,30,31,30,31][$i++];$m+=$i;echo date_create_from_format("m/d","$m/$d")->format("n/j");

PHP neredeyse tarih ayrıştırma ve biçimlendirme talimatları ile rollover'ı neredeyse destekler. Örneğin:

echo date_create_from_format("m/d","12/64")->format("n/j"); // Output: 2/2

Ancak, her iki sayı da 100'den büyük olduğunda, PHP onu ayrıştırmayı reddeder ve bir hata döndürür (muhtemelen bazı nedenlerden dolayı). Yani, bu cevabı olan teori onu PHP'nin ayrıştıracağı yere geri götürmek ve sonra ona göndermektir date_create_from_format().

Ungolfed:

list($month, $day) = explode("/", $argv[1]);
$month = $month % 12;
$day = $day % 365;
$i = 0;
$days = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
while($day > 31) $day -= $days[$i++];
$month += $i;
echo DateTime::createFromFormat("m/d", $month . "/" . $day)->format("n/j");

Çevrimiçi deneyin


1
Bana tarih dizesini girmek veya bir işlev yapmak için bir yol vermelisiniz.
geokavel

GET parametreleri PHP'de bir giriş yöntemi olarak kabul edilemez . Bunu bir işlev haline getirmeniz ve girişi işlev parametreleri olarak $argviletmeniz veya STDIN'den giriş almanız gerekir .
Mego

@Mego Jeeze, OP giriş için herhangi bir gereklilik belirtmediği için cevabımı güncellemem için biraz zaman verin - değiştirmek $tiçin yeterince basit $argv[1]ve şimdi komut satırı girişinden okuyor.
nickb

Giriş için OP belirleme gereksinimleri önemsizdir; meydan okuma yazarlarının bunları her meydan okumada belirtmek zorunda kalmamaları için varsayılan kabul edilebilir G / Ç yöntemlerinin (bağlı olduğum) bir listesine sahibiz.
Mego

2

JavaScript (ES6), 106 bayt

s=>eval('q="030101001010";p=s.split`/`;for(d=i=p[1],m=p[0]-1;i--;d>n&&(m++,d-=n))n=31-q[m%=12];m+1+"/"+d')

açıklama

s=>
  eval(`              // use eval to enable for loop without needing to write {} or return
    q="030101001010"; // q = array of 31 - days in each month
    p=s.split\`/\`;   // p = array of [ month, day ]
    for(
      d=i=p[1],       // d = day
        m=p[0]-1;     // m = month - 1
      i--;            // loop for each day, this is more iterations than needed but extra
                      //     iterations do not affect the result and it's the shortest way
                      //     to guarantee all months have been subtracted from d, it also
                      //     ensures the loop runs at least once to get m % 12
      d>n&&(m++,d-=n) // if too many days, subtract the month's days and increment month
    )
      n=31-q[m%=12];  // n = number of days in month, get m % 12
    m+1+"/"+d         // return the result
  `)

Ölçek


1

Rakip olmayan cevap - Bash + coreutils, 55

date -d1-$[(${1%/*}-1)%12+1]-1+$[${1#*/}-1]day +%-m/%-d

"Tarih ayrıştırma / biçimlendirme işlevlerine yine de izin verilir" - Bunun,date yardımcı program izin verildiğini .

Giriş komut satırından okunur, örneğin:

$ ./rollovercal.sh 15/43
4/12
$ 

Date komutu, birkaç gün ekleyen böyle bir şeye genişlediğinden, bu rakipsizdir:

date -d1-3-1+42day +%-m/%-d

date.add(875)Tarihi 875 gün arttırmak gibi bir şey yapmadığı sürece izin verilir . Çoğunlukla bundan sonra gidiyordum.
geokavel

@jeokavel oh, anlıyorum. dateBurada tamamen genişletilmiş komut date -d1-3-1+42day +%-m/%-d, yani tam olarak bunu yapıyor. Sanırım bu o zaman rakip olmayan bir cevap :(
Digital Trauma
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.