Tarih Biçimi Anlaşmazlığını Çözme


17

Tarihlerin biçimlendirme sırası, dünyanın bugün karşılaştığı en karmaşık ve bölücü konulardan biridir. Bazılarımız, Ay / Gün / Yıl'ın uygun olduğunu iddia ediyor, bu yüzden tarihler yüksek sesle söyleniyor. Diğerleri, Gün / Ay / Yıl'ın en iyi olduğunu yüksek sesle ilan eder, çünkü terimleri temsil ettikleri sürenin artan sırasına koyar.

Yeter artık. Bilgisayarlar bu anlaşmazlığı basit ve adil bir şekilde çözebilir. Kodunuz, tam bir işlev veya program, eğik çizgilerle ayrılmış bir tarih dizesi alır, örn 12/1/2015. Bunun, sıfır olmadan ve sonunda dört basamaklı bir yıl içeren tam biçim olduğunu unutmayın.

  • E? Er kesinlikle Ay / Gün / Yıl, örneğin 10/31/1998, çıkış tam ay adı, gün ve yıl ile bu kesin biçimde bu tarihten, bir metin gösterimi:October 31, 1998
  • E? Er kesinlikle Gün / Ay / Yıl, örneğin 25/12/1989, çıkış metin gösterimi aynı tür: December 25, 1989.
  • Ay / Gün / Yıl veya Gün / Ay / Yıl olup olmadığı belirsizse, olası iki tarihi aşağıdaki gibi birleştirerek belirsizliği gideren bir tarih verin:
    1. Adına ilk yarısını alarak yeni bir ay adı oluşturun önceki ay ve ikinci yarısını ekleyin sonradan ay. Tek uzunlukta aylar için, ilk yarı ekstra mektubu alır. Açık olmak gerekirse, ayların ilk yarıları olan Janu, Febr, Mar, Apr, Ma, Ju, Ju, Aug, Septe, Octo, Nove, ve Deceikinci yarıları bu nedenle ary, uary, ch, il, y, ne, ly, ust, mber, ber, mber, ve mber.
    2. Ortalamayı bir tam sayı olmadığında söz alarak iki olası günü ortalayarak günü hesaplayın.
    3. Bu tarihin metin temsilini 10/8/2011çıktı olarak , örneğin çıktı için Augber 9, 2011.

Giriş tarihi Ay / Gün / Yıl veya Gün / Ay / Yıl (ör. 13/13/2013Hatta çift 2/30/2002) olamazsa, herhangi bir davranış kabul edilebilir. Bu kod golf, en kısa kod kazanır!

Test senaryoları:

10/31/1998 verir October 31, 1998

25/12/1989 verir December 25, 1989

10/8/2011 verir Augber 9, 2011

8/5/1957 verir Maust 6, 1957

9/12/2012 (garip bir şekilde) verir September 10, 2012

1/1/2000 verir January 1, 2000



20
Değer için, gün-ay-yıl için tartışanların birçoğu da bu sırada tarihler söylüyor. (Tabii ki, Gerçek Programcılar yıl-ay-gün için tartışırlar).
Peter Taylor

Emin olmak için: without leading zeroes and with a four-digit year at the endimayear >= 1000
edc65

Bu doğru.
Luke

1
+ ∞, 10 Eylül 2012 için
ev3commander

Yanıtlar:


1

Pyth - 156 bayt

Gerçekten kötü kod ve paketlenmiş dizeleri kullanmak gerekir, ama onun bir şey.

Kc"January February March April May June July August September October November December"dJhM.g>k12=GsMcz\/?<eJ32++@KthJdtP`,eJeGss[@VCcL2KStMPGdPt`,s.OPGeG

Test Takımı .


3

Mathematica 341304298288293 bayt

Bu, saf veya anonim bir işlev, yani kendi adı olmayan bir işlev kullanır.

DateStringtarih belirsizse bir hata mesajı döndürür. Checkbelirsizliği yakalar ve rahatsız edici tarihi olarak gönderir DateList, bu da onu 3 tamsayı listesine dönüştürür (olduğuna inanır {year, month, day}). Ay ve gün tamsayıları boyuta göre sıralanır ve OP'nin talimatlarına göre ay ve günü belirlemek için kullanılır.

Quiet yazdırma hatası susturur.

t=StringSplit;v=ToString;x=t[#,"-"]&/@t["Janu-ary Febr-uary Mar-ch Apr-il Ma-y Ju-ne Ju-ly Aug-ust Septe-mber Octo-ber Nove-mber Dece-mber"];
Quiet@Check[#~DateString~{"MonthName"," ","DayShort",", ","Year"},
{m,n,o}=DateList@#;{p,q}=Sort@d[[2;;3]];x[[p,1]]<>x[[q,2]]<>" "<>v@Floor@Mean@{n,o}<>", "<>v@d[[1]]]&

t=StringSplit;v=ToString;x=t[#,"-"]&/@t["Janu-ary Febr-uary Mar-ch Apr-il Ma-y Ju-ne Ju-ly Aug-ust Septe-mber Octo-ber Nove-mber Dece-mber"];
Quiet@Check[#~DateString~{"MonthName"," ","DayShort",", ","Year"},
{m,n,o}=DateList@#;{p,q}=Sort@d[[2;;3]];x[[p,1]]<>x[[q,2]]<>" "<>v@Floor@Mean@{n,o}<>", "<>v@d[[1]]]& /@ 
{"10/31/1998","25/12/1989", "10/8/2011", "8/5/1957", "9/12/2012", "1/1/2012"}

{"31 Ekim 1998", "25 Aralık 1989", "9 Ağustos 2011", "Maust 6, 1957", "10 Eylül 2012", "1 Ocak 2012"}


Şahsen bu 0'ı ortadan kaldırdığınızı görmek isterim, ancak oyların olabildiğince düşmesine izin vereceğim.
Luke

Şimdi istendiği gibi "1 Ocak 2012" döndürüyor.
DavidC

3

JavaScript (ES6), 311 295 282 274 246 238 bayt

a=>(a=a.split`/`,b=c=>e(c).length+1>>1,d=' ',e=f=>new Date(99,a[+f]-1).toLocaleString('en',{month:'long'}),g=+a[0],h=+a[1],i=g>h,j=g>12,k=h>12,(j&&!k?e(1)+d+g:k&&!j?e(0)+d+h:e(i).slice(0,b(i))+e(1-i).slice(b(1-i))+d+((g+h)>>1))+', '+a[2])

Düzenleme: kullanır toLocaleStringay adları oluşturmak için. Farklı yerel ayarlardaki ay adlarını kullanarak sonuç almak için yerel ayarı değiştirin!

Edit 2: Şimdi 12 yerine iki aylık isimler üretiyor!

Ungolfed:

func = inp => (
    inp = inp.split `/`,
    get = arg => months(arg).length + 1 >> 1,
    space = ' ',
    months = key => new Date(99, inp[+key] - 1).toLocaleString('en', { month: 'long' }),
    tmp1 = +inp[0],
    tmp2 = +inp[1],
    first = tmp1 > tmp2,
    t1greater = tmp1 > 12,
    t2greater = tmp2 > 12,
    (t1greater && !t2greater ?
        months(1) + space + tmp1
    :
        t2greater && !t1greater ?
            months(0) + space + tmp2
        :
            months(first).slice(0, get(first)) + months(1 - first).slice(get(1 - first)) + space + ((tmp1 + tmp2) >> 1)
    )
    + ', ' + inp[2]
)

Misal:

console.log(
    func('10/31/1998') + '\n' +
    func('25/12/1989') + '\n' +
    func('10/8/2011') + '\n' +
    func('8/5/1957') + '\n' +
    func('9/12/2012') + '\n' +
    func('1/1/2000')
);

Teşekkürler:
@ user81655 , 274 => 246 bayt
@ edc65 , 246 => 238 bayt


1
Çok iyice baktım ama burada yapabiliriz birkaç iyileştirme var değil: değişim Math.ceil(e[c].length/2)için (r=e[c].length/2)+r%1, Array(2).fill().map((_,f)=>...)için f=>...ve her e[n]üzere e(n), i=+(g>h)için i=g>hve e[i]için e[+i]son üçlü operatör gereksiz ayraçlar kaldırmak Ayrıca newDateolmalıdır new Date.
user81655

1
Math.ceilKullanmaktan kaçınınb=c=>e(c).length+1>>1
edc65

2

JavaScript ES6, 204

x=>(s=x=>x.split`/`,[a,b,y]=s(x).sort((a,b)=>a-b),(c=b)>12?c=a:b=a- -b>>1,s('/Janu/Febr/Mar/Apr/Ma/Ju/Ju/Aug/Septe/Octo/Nove/Dece')[a]+s('/ary/uary/ch/il/y/ne/ly/ust/mber/ber/mber/mber')[c]+` ${b}, `+y)

Test snippet'i:

F=x=>(
  s=x=>x.split`/`,
  [a,b,y]=s(x).sort((a,b)=>a-b),
  (c=b)>12?c=a:b=a- -b>>1,
  s('/Janu/Febr/Mar/Apr/Ma/Ju/Ju/Aug/Septe/Octo/Nove/Dece')[a]
  +s('/ary/uary/ch/il/y/ne/ly/ust/mber/ber/mber/mber')[c]+` ${b}, `+y
)

console.log=x=>O.innerHTML+=x+'\n'

;['10/31/1998','25/12/1989','10/8/2011','8/5/1957','9/12/2012','1/1/2000']
.forEach(x=>console.log(x+' -> '+F(x)))
<pre id=O></pre>


2

Python 3 (290 bayt)

Ashwin Gupta'nın cevabına benzer, ancak tüm ay adlarını yazmamak için Python'un takvim modülünden yararlanıyor.

import calendar as C
M,I,P,S,L,A=C.month_name,int,print," ",len,", "
def d(i):
 w=i.split("/")
 f,s,y=I(w[0]),I(w[1]),w[2]
 if(f>12):P(M[s]+S+w[0]+A+y)
 elif(s>12):P(M[f]+S+w[1]+A+y)
 else:l,h=min(f,s),max(f,s);P(M[l][:I(L(M[l])/2+.5)]+M[h][I(L(M[h])/2+.5):]+S+str(I((f+s)/2))+A+y)

Python 2, tamsayı bölme ve parantezlerini kaybetme ile birkaç bayt kırpmalıdır print.


1

Python, 558554 bayt

Python'da bunun nasıl yapılacağına dair gerçekten, gerçekten, gerçekten korkunç bir golfçü örneği. Üzgünüm, bu golf işinde çok kötüyüm D:. Gerçi çalışır. Bunu basitleştirmenin birçok yolu olduğundan eminim, bu yüzden yorumlarda bana bildirin. golfed:

import math
def d(i):
 l=["","January","February","March","April","May","June","July","August","September","October","November","December"]
 w=i.split('/')
 f=int(w[0])
 s=int(w[1])
 S=" "
 y=w[2]
 if(f>12):
  e=int(w[1])
  print(l[e]+S+w[0]+", "+y)
  elif(f<=12 and s>12):
   e=int(w[0])
   print(l[e]+S+w[0]+", "+y)
   else:
    if(f<s):
     o=l[f]
     t=l[s]
    else:
     o=l[s]
     t=l[f]
    o=o[0:int(math.ceil(len(o)/2))]
    t=t[int(math.ceil(len(t)/2)):len(t)]
    print(o+t+S +  str(math.floor((f + s)/2)) + ", " + y)

Ungolfed

import math
def d(i):
    l = ["", "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"]
    w = i.split('/')
    f = int(w[0])
    s = int(w[1])
    y = w[2]
    if(f > 12):
        e = int(w[1])
        print(l[e] + " " + w[0] + ", " + y)

    elif(f <= 12 and s > 12):
         e = int(w[0])
         print(l[e] + " " + w[0] + ", " + y)
    else:
         if(f < s):
            o=l[f]
            t=l[s]
         else:
            o=l[s]
            t=l[f]
         o = o[0:int(math.ceil(len(o)/2))]
         t = t[int(math.ceil(len(t)/2)):len(t)]
         print(o+t+" " +  str(math.floor((f + s)/2)) + ", " + y)

Ekran görüntüsü: resim açıklamasını buraya girin


koymak S=" "sonra her geçtiği yerde değiştirmek, üstündeki " "ile Sbazı bayt traş edecek -
kedi

ödevlerden sonra birkaç gereksiz boşluk var ( e= int[..., o = o...). Ayrıca, inttek harfli büyük harf vars gibi sık kullanılan çağrıları ayarlamak avantajlı olabilir
cat

1
İşte 447 bayt:from math import* I=int S=" " C="," L=len P=print def d(i): l=["","January","February","March","April","May","June","July","August","September","October","November","December"];w=i.split('/');f=I(w[0]);s=I(w[1]);y=w[2] if f>12:e=I(w[1]);P(l[e]+S+w[0]+C+S+y) elif f<13and s>12:e=I(w[0]);P(l[e]+S+w[0]+C+S+y) else: if f<s:o=l[f];t=l[s] else:o=l[s];t=l[f];o=o[0:I(ceil(L(o)/2))];t=t[I(ceil(L(t)/2)):L(t)] P(o+t+S+str(floor((f+s)/2))+C+S+y)
kedi

1
@sysreq tamam aklım resmen patladı. İşlevleri bir değişkene depolayabileceğinizi bilmiyordum. Teşekkür ederim. Bunu da düzenleyeceğim. Ayrıca, bana bir iyilik yapabilir ve kodumu çalıştırmayı deneyebilir misiniz (golfed) ve olması gerektiği gibi çalışıp çalışmadığına bakın, çünkü Luke benden farklı sonuçlar alıyor gibi görünüyor, bu yüzden sadece görmek istiyorum.
Ashwin Gupta

1
@sysreq evet idk. Neden onun için farklı. Neyse, ipuçları için tekrar teşekkürler, gerçekten sadece golf için değil, Python için hala yeni olduğum için genel olarak yardımcı oluyor. Ayrıca, o ve t'nin ilk atamalarımı kaldırabildiğimi ve dizi elemanını doğrudan ayırıcıma koyarak 4 bayt kaydedebileceğimi fark ettim. Bütün bu değişiklikleri bu öğleden sonra yapacağım. Senin sayende yeni bayt sayısı önemli ölçüde daha az olacak!
Ashwin Gupta

0

PHP, 301 294 bayt

function r($t){$e='return date("F",mktime(0,0,0,$o));';list($a,$b,$c)=explode('/',$t);$o=min($a,$b);$m=eval($e);$o=max($a,$b);$n=eval($e);echo(($a|$b)<13)?substr($m,0,ceil(strlen($m)/2)).substr($n,ceil(strlen($n)/2))." ".floor(($a+$b)/2).", $c":date("F j, Y",strtotime(($a>12)?"$b/$a/$c":$t));}

Javascript cevabı ile rekabet edebileceğimi düşündüm. Oh iyi.

Ben daha küçük yapabilir ve belirsiz tarihler için kullandığım kodu sevmiyorum düşünüyorum. Bence bunu yapmanın daha iyi bir yolu var.

Ungolfed:

function r($t){
    // Eval'd code to reduce char count
    $e='return date("F",mktime(0,0,0,$o));';

    // Split the date
    list($a,$b,$c)=explode('/',$t);

    // Get the earliest month
    $o=min($a,$b);
    $m=eval($e);

    // Get the latest month
    $o=max($a,$b);
    $n=eval($e);

    // If ambiguous
    if ($a<13 && $b<13) {
        print substr($m,0,ceil(strlen($m)/2)).substr($n,ceil(strlen($n)/2))." ".floor(($a+$b)/2).", $c";
    }
    else {
        print date("F j, Y",strtotime(($a>12)?"$b/$a/$c":$t));
    }
}
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.