Belirli bir yılın her ayında son Pazar günü bul


21

140 karakter içinde bilinen F # çözümleri ve bu bir Rosetta Kodu problemidir.

Giriş yılı için stdout veya dize değişkeninde gerekli sonuç 2014:

2014-01-26 2014-02-23 2014-03-30 2014-04-27 2014-05-25 2014-06-29 2014-07-27 2014-08-31 2014-09-28 2014-10-26 2014-11-30 2014-12-28

1900 için talep edildiği gibi:

1900-01-28 1900-02-25 1900-03-25 1900-04-29 1900-05-27 1900-06-24 1900-07-29 1900-08-26 1900-09-30 1900-10-28 1900-11-25 1900-12-30

Ve 2000:

2000-01-30 2000-02-27 2000-03-26 2000-04-30 2000-05-28 2000-06-25 2000-07-30 2000-08-27 2000-09-24 2000-10-29 2000-11-26 2000-12-31

Tarihler çoğu dilde garipliği ortaya çıkardığı için ortaya çıktı. Tarih kütüphanelerine izin vermekten çok, onları görmeyi umuyorum! Ancak temel dilin dışındaysa, gönderinin adını belirtin (örn. C # + Jon Skeet'in NodaTime'ı).

Açıklamalar:

  • Yıl aralığı 1900 - 3015
  • Miladi takvim
  • Aksi takdirde, İngiltere / Londra için geleneksel olan ne varsa.
  • Komut satırı anahtarını veya stdin'i alan bir program iyidir ve sonucu stdout'a dönüştürür
  • Yıl için değer alan ve bir dize döndüren bir işlev de iyidir.

Standart boşluklar hariç . APL, J, K çözümlerini dört gözle bekliyor ve yeni tarih kütüphaneleri görüyoruz.


@ Sp3000 - 1752 özellikle garip olabilir :-)
squeamish ossifrage

@ MartinBüttner: Lütfen tarih kütüphanelerini kullanın, insanlardan dil ile kullandıklarını beyan etmelerini istemek için soruyu düzenleyin.
Phil H

1
Geçerli girdi olan yıl aralığını ve Gregoryen kabulü ile ilgili hususları belirtmelisiniz. (Yani, yıl aralığı 1930'dan önce varsa, yerel takvimden bağımsız olarak Gregoryen takviminin tüm aralık için kullanılması gerektiğini veya çıktının yerel ayara göre değişebileceğini belirtmelisiniz; ya da daha önce bir kesme tarihi vermelisiniz. Jülyen takvimi, değişim çevresindeki üç yıl boyunca kullanılmalı ve test vakaları olmalıdır).
Peter Taylor

1
@squeamishossifrage: Bunu 1900 ve Gregorian ile sınırladım, çünkü spesifikasyonu oluşturmak için bir araştırma projesinden kaçınmayı tercih ederim ...
Phil H

1
@ Adám: Bir cevap için bu kadar beklemenizi sağladığım için üzgünüm :) Evet, gerçekten.
Phil H

Yanıtlar:


1

Dyalog APL ile cal dan dfns , 19 bayt

Geç olsun güç olmasın!

Yıl için bilgi istemleri, yyyy md biçimindeki tarih listesini döndürür .

⎕{⍺⍵,2↑⊢⌿cal⍺⍵}¨⍳12

sayısal girdi istemine izin verin ve bırakın

{... anonim işlev (aşağıda bulunur) her birine uygulanır

⍳12 1'den 12'ye kadar olan sayılar (aylar)

Yukarıdaki anonim işlev aşağıdaki gibidir:

⍺⍵, sol ve sağ argümanları (yıl ve ay)

2↑ ilk iki karakteri

⊢⌿ en alt satırı

cal için takvim

⍺⍵ sol argüman ve sağ argüman (yıl ve ay)

Çevrimiçi TryAPL:

  1. İçe aktarmak için burayacal ve bağımlılıklarına tıkladıktan sonra bu sayfaya dönün

  2. Test senaryolarını çalıştırmak için buraya tıklayın .


Çok iyi. Tarihlerin ne anlama geldiğini anlayan bir APL kütüphanesi umuyordum, ama cal makul!
Phil H

@PhilH tarih ve günleri ?
Adam

1
@PhilH MiServer'dan Tarihler ad alanı da var.
Adám

1
@PhilH Ve Dyalog APL diyadik ilkel + - < = ve Net tarih nesnelerle çalışma .
Adam

7

Yakut, 91 + 6 = 97

#!ruby -prdate
$_=(Date.new(y=$_.to_i)...Date.new(y+1)).select(&:sunday?).chunk(&:mon).map{|k,v|v[-1]}*' '

Oldukça iyi çalışıyor. select(&:sunday?)güzel ve şaşırtıcı bir şekilde *' 'tüm biçimlendirmeyi tek başına yapıyor.


Güzel numaralar! Bunun chunkyerine kullanarak üç karakter daha kaydedebilirsiniz group_by.
Cristian Lupascu

Böylece yapabilirim, güzel.
histokrat

6

Bash 4.x + ncal, 57

Boşluk yerine satırsonu ayırıcıları iyi ise, -nanahtarı ve sondaki boşluğu echoifadeden kaldırabiliriz . Ve sanırım hala shebang olmadan çalışacaktır, bu yüzden ben de kaldırıldı:

for i in {01..12};{ echo "$1-$i-`ncal $i $1|tail -c-3`";}

Orijinal komut dosyası (73 bayt):

#!/bin/bash
for i in {01..12};{ echo -n "$1-$i-`ncal $i $1|tail -c-3` ";}

Kullanımı:

$ bash sundays.sh 2014
2014-01-26
2014-02-23
2014-03-30
2014-04-27
2014-05-25
2014-06-29
2014-07-27
2014-08-31
2014-09-28
2014-10-26
2014-11-30
2014-12-28
$

Not: 4.0'dan önceki Bash sürümleri aylardan önde gelen sıfırları atlar. Bu değiştirerek 5 karakter eklenmesiyle sabitlenebilir {01..12}için `seq -w 1 12)`. Ayrıca, tail -c-3çıkışının ncalsondaki boşlukları içerdiği bazı sistemlerde sorunlara neden olabilir , ancak bunun farkında değilim.


1
Aradaki fark sadece Bash versiyonuyla değil, Darwin ile mi ilgili? Bash 4.0 (daha sonra bazı hatalar olsa da) eklendi. Her neyse, `…`iyi alışkanlık yerine 1 karakter korunabilir $(…).
manatwork

Ah, olabilir. Darwin 3.2.53 sürümünü kullandığını söylüyor; Debian 4.1.5 kullanıyor.
squeamish ossifrage

@manatwork PS Sadece arka keneler hakkındaki yorumunuzu fark ettiniz. İyi yakaladın, teşekkürler!
squeamish ossifrage

#!/bin/bashGolf için saymanız gerektiğini düşünmüyorum .
Dijital Travma

@DigitalTrauma Bu iyi. Görünüşe göre boşluk yerine satır sonları da kullanabilirim. Şimdi 57 bayta
düştü

6

IBM DFSORT, 11 71, 72 veya 80 karakterlik 3 satır

 OPTION COPY 
 OUTFIL REPEAT=12,OVERLAY=(5:SEQNUM,2,ZD,5,2,1,8,Y4T,LASTDAYM,TOJUL=Y4T*
 ,9,7,Y4T,ADDDAYS,+1,TOJUL=Y4T,1:16,7,Y4T,PREVDSUN,TOGREG=Y4T(-),12X) 

Sütunlu çıktı formatı ile verilen iki cevap zaman testini geçmiştir. Bu bana bir "döngü", bir tür, OUTFIL REPEAT = geçerli kayıt birçok kez kopyalar verir.

Değere ulaşmak için farklı teknik, daha uzun gibi görünüyor ama ertesi yıl 12. kayıt ile başa çıkmak için koşulsuz bir yol çalışamam ve IFTHEN=(WHEN=iki kez ve diğer bazı şeyler dahil koşullu araçlar yapmak gibi daha kısa . Salıncaklarda kazanç (ilk ay bunu yapmanın en basit yoludur) kavşaklarda (belirli sözdizimi gereksinimleri) ağır bir şekilde kaybeder.

Bu, ayın son gününü bulmak için dahili bir işlev kullanır (DFSORT'daki tüm işlevler yerleşiktir). Ardından, bir sonraki ayın ilk gününe ulaşmak için bir gün (işlev) ekler ve önceki Pazar günü almak için PREVDSUN işlevini kullanır (önceki gibi her zaman önceki ayın son Pazar günü olur).

Yılı (giriş) geçerli bir tarihe çevirirken, ay için iki basamaklı bir sıra numarası kullanılır ve başlangıç ​​değeri bizim kadar önemli olmadığı için bu değer gün için de kopyalanır başlangıçta ayın son gününden sonra: 5,2daha kısadır C'01'.

İşte detay:

OPTION COPY - giriş dosyasını çıktıya kopyala

OUTFIL - farklı seçim ve biçimlendirmelere sahip birden çok çıktı dosyasının biçimlendirilmiş raporlar üretmesine izin vermek için. Tercihen daha kısa kullanılması INRECnedeniyle kullanılır REPEAT=.

REPEAT = 12 - her kaydın 12 kopyasını üretir. Bu örnekte, SEQNUM nedeniyle yalnızca bir giriş kaydı olabilir (önceki sürümden farklı olarak).

5: - kayıttaki 5. sütundan başlayın.

SEQNUM, 2, ZD - sıra numarası, varsayılan olarak bir, iki basamaklı, "zoned ondalık" olarak başlatır (imzasız için, karakterle aynı olacaktır).

1,8 - 8 uzunluk için bayt 1'i geçerli konuma (9) kopyalayın. Bunun nedeni, Y4T'nin 8'i görmesi gerektiğidir, aksi takdirde farklı bir tarih biçimi kullanılır.

Y4T - ccyymmdd biçiminde tarih (hemen önünde 8 nedeniyle).

LASTDAYM - Ayın son günü (Hafta, Çeyrek ve Yıl da mümkündür).

TOJUL = - tarih işlevleri için çıktı tarih dönüşümü (TOJUL, TOGREG değerinden bir karakter daha az)

9,7 - şimdi 7 uzun olduğu için Y4T CCYYDDD olacak.

EKLEME - bir sonraki güne / yıla girilirse otomatik olarak ayarlanan birkaç gün ekler (ayrıca EKLE ve EKLEME olabilir)

PREVDSUN - Jülyen tarihi gelir, önceki Pazar bulunur, doğru çıktı formatını almak için TOGREG, "-" ayırıcıyla (ayırıcı olarak istediğiniz herhangi bir şey olabilir)

12X - bu kadar kısa bir şekilde yapmamıza izin veren karışıklığı gidermek için boşluklar

2014 yılı için yukarıdakilerden çıktı:

2014-01-26
2014-02-23
2014-03-30
2014-04-27
2014-05-25
2014-06-29
2014-07-27
2014-08-31
2014-09-28
2014-10-26
2014-11-23
2014-12-28

SORT'a ne yapacağını söyleyecek bir şey gerekiyor. Varsayılan yok. OPTION COPYen kısa, SORT FIELDS=COPYeşdeğer ama daha uzundur.

Bu kez yaptığı işin kendisi OUTFIL(REPEAT kullanımına izin vermek için). Çalışma kodu tartışmalı olarak 160 (2 * 80), 144 (2 * 72), 140 (72 + 69) veya 138 (70 + 68) 'den herhangi biridir (önde gelen boşluklar, zorunlu devam ve sondaki boşluklar hariç).

Alıcının ne yaptıklarını bilmek zorunda kalacağı göz önüne alındığında, DFSORT kodunun 1900'den itibaren herhangi bir yılın her ayının son Pazar gününü listelemesini söyleyebilirim (0001 yılından itibaren çalışacak, ancak araştırmadan kaçınıyorum 9999'a kadar (DFSORT 9999'a kadar olan yılları desteklese de, 12. çözüm bir sonraki yıla girdiği için 9999 yılında önceki çözüm işe yaramayacaktır) Tweetlenebilir.

Özellikle uygun dahili fonksiyonlar varsa, kod neden bu kadar uzun?

Alan tanımları kısa ömürlüdür. Bir alan, hemen kullanımı için verilerdeki (bu bir kayıttır) belirli bir konum olarak tanımlanır. Başka bir deyişle, alanlar bu şekilde tanımlanmaz, ancak her kullanım için ve yalnızca kullanım için tanımlanır. Tarih işlevlerinin kaynak için hangi (birçok) tarih biçiminin kullanıldığını bilmesi gerekir ve çıktının belirtilmesi gereken bir tarih biçiminde olması gerekir.

Şimdi bir Julian randevumuz var .... TBC?


 OPTION COPY 
 INREC OVERLAY=(1,4,C'0201',1,8,1,8,1,8,1,8,1,8,1,8,1,8,1,8,1,8,1,8,1,8*
 ,94:C'1',89:1,4,ZD,ADD,+1,ZD,LENGTH=4,14:C'3',22:C'4',30:C'5',38:C'6',*
 46:C'7',54:C'8',62:C'9',69:C'10',77:C'11',85:C'12',127:X,89,8,Y4T,PREV*
 DSUN,TOGREG=Y4T(-),116:X,81,8,Y4T,PREVDSUN,TOGREG=Y4T(-),105:X,73,8,Y4*
 T,PREVDSUN,TOGREG=Y4T(-),94:X,65,8,Y4T,PREVDSUN,TOGREG=Y4T(-),83:X,57,*
 8,Y4T,PREVDSUN,TOGREG=Y4T(-),72:X,49,8,Y4T,PREVDSUN,TOGREG=Y4T(-),61:X*
 ,41,8,Y4T,PREVDSUN,TOGREG=Y4T(-),50:X,33,8,Y4T,PREVDSUN,TOGREG=Y4T(-),*
 39:X,25,8,Y4T,PREVDSUN,TOGREG=Y4T(-),28:X,17,8,Y4T,PREVDSUN,TOGREG=Y4T*
 (-),17:X,09,8,Y4T,PREVDSUN,TOGREG=Y4T(-),1:1,8,Y4T,PREVDSUN,TOGREG=Y4T*
 (-),11:X,18,120,6X) 

Biraz ihtiyacı var JCL

//LASTSUNG EXEC PGM=SORT 
//SYSOUT   DD SYSOUT=* 
//SORTOUT  DD SYSOUT=* 
//SYSIN    DD * 

Ve bir girdi dosyası (başka bir JCL satırı ve üç veri içi veri):

//SORTIN DD *
2014 
1900 
2000 

üretir:

2014-01-26 2014-02-23 2014-03-30 2014-04-27 2014-05-25 2014-06-29 2014-07-27 2014-08-31 2014-09-28 2014-10-26 2014-11-30 2014-12-28
1900-01-28 1900-02-25 1900-03-25 1900-04-29 1900-05-27 1900-06-24 1900-07-29 1900-08-26 1900-09-30 1900-10-28 1900-11-25 1900-12-30
2000-01-30 2000-02-27 2000-03-26 2000-04-30 2000-05-28 2000-06-25 2000-07-30 2000-08-27 2000-09-24 2000-10-29 2000-11-26 2000-12-31

Aslında 9999 yılına kadar çalışacak.

DFSORT, IBM'in Mainframe sınıflandırma ürünüdür. Veriler manipüle edilebilir, ancak sıralama anahtar olduğundan ve türler genellikle büyük ve uzun süredir çalıştığından, DFSORT kontrol kartlarının döngü yapıları yoktur, bu nedenle bir SORT'u bir döngüye koyamayız. Golf gibi görevler için işleri biraz uzun soluklu yapar.

Yanıtın neden gönderilmesinin nedeni, DFSORT'ın bir PREVDdayişlevi olmasıdır. Yani geçen Pazar bir ay içinde kolay. Bu, bir önceki ayın ilk günü olan PREVDSUN Pazar günüdür.

Bunu bir "işlenen" (OVERLAY) içinde yapmak biraz eğlenceliydi, biraz içinde sprintfveya benzeri yapmak gibi .

İşte çözülmemiş:

 OPTION COPY 

 INREC OVERLAY=(1,4,C'0201',1,8,1,8,1,8,1,8,1,8,1,8, 
         1,8,1,8,1,8,1,8, 
         1,8,94:C'1',89:1,4,ZD,ADD,+1,ZD,LENGTH=4, 
         14:C'3',22:C'4',30:C'5',38:C'6',46:C'7',54:C'8',
         62:C'9',69:C'10',77:C'11',85:C'12', 
        127:X,89,8,Y4T,PREVDSUN,TOGREG=Y4T(-), 
        116:X,81,8,Y4T,PREVDSUN,TOGREG=Y4T(-), 
        105:X,73,8,Y4T,PREVDSUN,TOGREG=Y4T(-), 
         94:X,65,8,Y4T,PREVDSUN,TOGREG=Y4T(-), 
         83:X,57,8,Y4T,PREVDSUN,TOGREG=Y4T(-), 
         72:X,49,8,Y4T,PREVDSUN,TOGREG=Y4T(-), 
         61:X,41,8,Y4T,PREVDSUN,TOGREG=Y4T(-), 
         50:X,33,8,Y4T,PREVDSUN,TOGREG=Y4T(-), 
         39:X,25,8,Y4T,PREVDSUN,TOGREG=Y4T(-), 
         28:X,17,8,Y4T,PREVDSUN,TOGREG=Y4T(-), 
         17:X,09,8,Y4T,PREVDSUN,TOGREG=Y4T(-), 
          1:1,8,Y4T,PREVDSUN,TOGREG=Y4T(-), 
         11:X,18,120,6X) 

Oldukça kötüye kullanılmasa da, tüm bunları bir OVERLAY'a sıkıştırmaya çalışmak normal olmazdı ve hepsinin bir OVERLAY'a girmesine izin vermek için gerekli olan bazı gereksiz şeyler var. Golf için bir yer var, ama sadece bir satırı en fazla kaldıracağından, cazip değilim.

INREC her kayıt için işlenir.

OVERLAY mevcut bir kaydın içeriğinin değiştirilmesine izin verir. Kayıt, işlemdeki uzunluğunun ötesine uzatılırsa, bu bir sorun değildir.

1,4, gelen yıl. 0201 değerinde bir değişmez değeri eklenmiş ve ardışık 1,8'ler 96 baytlık uzun bir ayna vermek için 11 kez tekrar ediyor,

Genişletilmiş cari kayıtta 12. yıl 1 eklenir ve ayı 1 (Ocak) olur.

Kalan 10 ay 3'ten 11'e değiştirildi.

Sonra bu tür şeylerin tersi sırada (OVERLAY nedeniyle) 12 vardır:

127:X,89,8,Y4T,PREVDSUN,TOGREG=Y4T(-),

N: kayıttaki bir sütun numarasıdır. X bir boşluk ekler. 89,8 verileri bu sütun / uzunluktan alır, Y4T bunu bir CCYYMMDD tarihi olarak kabul eder, PREVDSUM önceki Pazar günü çalışır, TOGREG = Y4T (-) bunu bir Gregoryen CCYY-AA-GG tarihi olarak verir.

Bir OVERLAY'in belirli bir bölümünün kaynağı ve hedefi yıkıcı bir şekilde çakışırsa çöp alırsınız, son 11:X,18,120,6X)yeniden dağınıklığı yeniden düzenler ve maskeler.

Kılavuzlar ve belgeler şu adreste bulunabilir: http://www-01.ibm.com/support/docview.wss?uid=isg3T7000080 ve 900+ sayfalık DFSORT Uygulama Programlama Kılavuzu'nu içerir.

Tüm IBM ürünlerinde olduğu gibi, tüm kılavuzlar ücretsiz olarak mevcuttur (yalnızca çok az sayıda insanın anlamayı bile düşüneceği çok az miktarda çok pahalı olanlar hariç).

Tüm DFSORT Kontrol Kartları bir boşlukla başlamalıdır. Sütun 72 sadece devam için kullanılır (boş olmayan herhangi bir işlem yapılır, ancak * gelenekseldir). Sütun 72'yi, her bir kaydı 80 bayt yapan yok sayılan bir sıra numarası alanı izler.

Belki gelecek birkaç çözüm daha.


5

Bash, 63 bayt

for i in {01..12};{  date -v30d -v${i}m  -v2014y  -vsun +%Y-%m-%d;}

Çıktı:

2014-01-26
2014-02-23
2014-03-30
2014-04-27
2014-05-25
2014-06-29
2014-07-27
2014-08-24
2014-09-28
2014-10-26 
2014-11-30
2014-12-28

for i in {1..12};{ date -v30d -v${i}m -v$1y -v0w +%Y-%m-%d;}- 60 bayt
Dijital Travma

-vparametresi dateBSD tarihine özeldir. Yani bu OSX üzerinde çalışıyor, ancak çoğu Linux'ta değil - belki de cevapta belirtilmelidir.
Dijital Travma

@DigitalTrauma, mac ve Linux'um üzerinde çalışıyor.
michael501

4

Python 2-189 bayt

y=input()
for m in range(12):
 d=[31-(1322>>m&1),28+(y%400<1or 1>y%4<y%100)][m==1];Y=y-(m<2);Z=Y%100;C=Y/100
 while(d+13*((m-2)%12+4)/5+Z+Z/4+C/4-2*C)%7-1:d-=1
 print"%d-%02d-%d"%(y,m+1,d),

Tarihi STDIN ile girin.

Yine de yapılabilecek çok daha fazla golf. Program sadece eğlenmek için biraz denize düşüyor:

  • Herhangi bir içe aktarma yok, özellikle yerleşik tarih işlevlerini kullanmıyor
  • Haftanın günlerini hesaplamak için Zeller'ın uyumunu kullanır

notlar

  • 1322, Şubat ayının dışında bir ayın 30 veya 31 gün olup olmadığını belirlemek için sihirli bir arama tablosu
  • Hiçbir zfillnedeniyle giriş aralığına yıl için gerekli olan, ne günler hep 20 üzerinde olacak şekilde

Python 2-106 bayt

Eğlenceli olmayan çözüm:

from calendar import*
y=input();m=1
while m<13:w,n=monthrange(y,m);print"%d-%02d-%d"%(y,m,n-(n+w)%7),;m+=1

calendar.monthrangeiki sayı döndürür: ayın başladığı hafta içi gün ( w) ve aydaki gün sayısı ( n). Çözüm, bir yakalama nedeniyle biraz mantıksızdır - iade edilen hafta içi Pazar günü değil Pazartesi için 0'da başlar ! Ancak, bu n1 tabanlı gerçeğiyle dengelenir .


1
Çok aptalca bir Pyth cevap:$from calendar import monthrange as gt$V12AGH>QhN%"%d-%02d-%d"(QhN-H%+GH7
FryAmTheEggman

3

JavaScript (ES6) 155 145

Düzenle Sabit saat dilimi sorunları Yinelemeli yapılırsa daha kısa olabilir. Olabilir.

F=y=>{
  for(n=i=o=[];!o[11];)
    d=new Date(Date.UTC(y,0,++i)),m=d.getMonth(),
    d.getDay()||(m!=n&&o.push(p.toISOString().slice(0,10)),p=d,n=m);
  return o.join(' ')
}

Kullanabilirsiniz new Date(y,0,++i,9). Ayrıca, JS bu sıçrama yılları hakkında bilgi sahibi olmadığından ve 2100 ve üstü için artık yıllarda olmadığı için, bu 2100 ve artık yılların üzerinde başarısız olur Feb 29.
Optimize Edici

@Optimizer JS değil: 2100,2200,2300 artık yıl değil. 2014 artık bir yıl ve JS biliyor. Saat 9'u kullanmaya gelince, doğrulayamıyorum ama örneğin Melbourne'deyseniz bunun işe yaramadığını düşünüyorum ...
edc65

Ah .. 400 yılda 3 gün düştüğümüzü hiç bilmiyordum. Ben 1100 (Melbourne) için -1000 (Hawaii) benim dilimini değiştirmeme - 9 Hakkında new Date(2014,0,26,9)bir Pazar doğru vererek idi ISOyanı sıra dize getDay()kadar 0.
Optimize Edici

3

JavaScript, ES6, 222 219 199 bayt

Rosetta wiki'de herhangi bir JavaScript yanıtı görmedim.

İşte başlıyoruz:

S=Y=>{for(l=[],p=new Date(Y,i=0);i<365+!(Y%4);)if(!(d=new Date(Y,0,++i,9)).getDay()){p.getMonth()-d.getMonth()&&l.push(p);p=new Date(d)}return[...l,p].map(x=>x.toISOString().split("T")[0]).join(" ")}

Bu S, istenen çıktıya sahip bir dize döndüren bir işlev oluşturur . bu fonksiyon artık yıllar ile de ilgilenir.

ES6 nedeniyle, bu yalnızca en son Firefox'ta çalışır.

200 bayta indirilmiş uç için apsillers sayesinde

Aşağıdaki çözülmemiş sürümü burada çalıştırabileceğiniz bir yığın snippet'i olarak bulun:

S=Y=>{
  for(l=[],p=new Date(Y,i=0);i<365+!(Y%4);)
    if(!(d=new Date(Y,0,++i,9)).getDay()){
      p.getMonth()-d.getMonth()&&l.push(p);
      p=new Date(d)
    }
  return[...l,p].map(x=>x.toISOString().split("T")[0]).join(" ")
}

alert(S(parseInt(prompt())))


Ayrıştırmak yerine + istemi () kullanabilir ve bazı baytları tıraş edebilirsiniz
Jacob

@Jacob Bu bilgi istemi bayt sayısına eklenmez.
Optimizer,

İKÖ. Soruyu okumalıydım ...
Yakup

@apsillers Bir ton teşekkürler! Sorun düzeltildi ve ipucunuza göre çok azaltıldı.
Optimizer

Giriş 2100çıkışı 2100-01-31 2100-02-28 2100-03-28 2100-04-25 2100-05-30 2100-06-27 2100-07-25 2100-08-29 2100-09-26 2100-10-31 2100-11-28 2100-12-26 2101-01-02yanlış.
Qwertiy

3

Asi - 120 116 80 79 76

d: do join"1-1-"input print collect[for m 2 13 1[d/2: m keep d - d/weekday]]


Ungolfed + bazı ek açıklamalar:

d: do join "1-1-" input         ;; golfy way to create Rebol date! datatype 1-Jan-(year)

print collect [
    for m 2 13 1 [              ;; loop thru months 2 to 13!
        d/2: m                  ;; move to (1st of) next month
        keep d - d/weekday      ;; collect/keep last sunday of month
    ]
]

Rebol konsolunda pazar hesaplaması örneği:

>> ; get last sunday of Jan 2014

>> d: 1-1-2014
== 1-Jan-2014

>> d/month: d/month + 1
== 2

>> d
== 1-Feb-2014

>> d/weekday
== 6

>> d - d/weekday
== 26-Jan-2014

>> ; above is last sunday of Jan 2014
>> ; and when pass end of year (ie. month 13!)

>> d/month: 13
== 13

>> d
== 1-Jan-2015

Potansiyel 87: d: 1-1-1 d / yıl: girdi yazdırmayı toplama yap [tekrar m 12 [d / ay: m + 1 tutmak d - d / hafta içi]]
rgchris

@rgchris Teşekkürler Chris. Bunun için 7 karakter daha tıraş edebildim.
draegtun

Güzel!! Durumu kötü, ama gerçekten düşünmek asla FOR kısayol olarak.
rgchris

2

CJam, 122 102 bayt

30li:X400%){[1387Yb30f+~28I!I4%!I100%e&|g+\]W%{\_2$>7*-\7%7\m1$+}/}fI;]12/W=12,{101+s1>}%]z{X+W%'-*S}/

Bu herhangi bir tarih kütüphanesi kullanmaz. Yine de çok fazla golf yapılabilir sanırım.

Burada test edin.


3
Öylesine muhteşem stoklanmış ki bir CJam cevabı bir kez kod-golf mücadelesinde en iyi cevap değil. Mutlu ölebilirim .. Bugün iyi bir gün (açıkçası 6 bayta kadar golfe kadar)
Brandon,

@Brandon: Bu ilginç olacağını düşündüğüm türden bir nedendi. Gerçekten bu kadar kolay, ama şimdiye kadar hayal kırıklığına kılan harika bir kütüphane görmek umuduyla.
Phil H

1

R, 128 karakter

P=paste;f=format;a=strptime(P(1:366,scan()),"%j %Y");cat(sort(sapply(split(a,f(a,"%B")),function(x)P(tail(x[f(x,"%u")==7],1)))))

Satır kesmeleri ile:

P=paste
f=format
a=strptime(P(1:366,scan()),"%j %Y")
cat(sort(sapply(split(a,f(a,"%B")),function(x)P(tail(x[f(x,"%u")==7],1)))))

1

C # 255

Ungolfed

static void Main(string[] a)
    {
        int y = Int32.Parse(Console.ReadLine());
        DateTime d = new DateTime(y, 1, 1);
        while (d.Year == y)
        {
            if (d.DayOfWeek == DayOfWeek.Sunday && d.Day>(DateTime.DaysInMonth(y,d.Month)-7))
                Console.WriteLine(d.ToShortDateString());
            d = d.AddDays(1);
        }
        Console.ReadKey();
    }

Düzenleme: yalnızca son Pazar günü yazdırılacak şekilde değiştirildi :)


Gerekli çıktı biçimi değil. + Bu kod golf
edc65

1

q, 67

{({{1<>x mod 7}-[;1]/x}')14h$1_til[13]+13h$"D"$(($)x),".01.01"}

Q için bunun için kullanılabilir tarih kütüphaneleri yok mu?
Phil H

1

"Ah, hayır, tekrar onu!"

Java - 259246 bayt

void g(int y){for(int i=;i<12;i++){GregorianCalendar c=new GregorianCalendar(y,i,0);c.set(c.DAY_OF_WEEK,c.SUNDAY);c.set(c.DAY_OF_WEEK_IN_MONTH,-1);System.out.print(y+"-"+String.format("%02d",(c.get(c.MONTH)+1))+"-"+(c.get(c.DAY_OF_MONTH))+" ");}}

Ungolfed sürümü:

void g(int y){
    for (int i = 0; i < 12;i++) {
        GregorianCalendar c = new GregorianCalendar(y, i, 0);
        c.set(c.DAY_OF_WEEK, c.SUNDAY);
        c.set(c.DAY_OF_WEEK_IN_MONTH, -1);
        System.out.print(y+"-"+String.format("%02d",(c.get(c.MONTH)+1))+"-"+(c.get(c.DAY_OF_MONTH))+" ");
    }
}

Kullanımı:

import java.util.GregorianCalendar;
import java.util.Scanner;

public class LastSundayInYear {

    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        System.out.println("Year?");
        int year = scanner.nextInt();
        LastSundayInYear sunday = new LastSundayInYear();
        sunday.g(year); 
    }

    void g(int y){
        for (int i = -1; ++i < 12;) {
            GregorianCalendar c = new GregorianCalendar(y, i, 0);
            c.set(c.DAY_OF_WEEK, c.SUNDAY);
            c.set(c.DAY_OF_WEEK_IN_MONTH, -1);
            System.out.print(y+"-"+String.format("%02d",(c.get(c.MONTH)+1))+"-"+(c.get(c.DAY_OF_MONTH))+" ");
        }
    }
}

Çıktı:

2014-01-26 2014-02-23 2014-03-30 2014-04-27 2014-05-25 2014-06-29 2014-07-27 2014-08-31 2014-09-28 2014-10-26 2014-11-30 2014-12-28

Yine başka bir "sadece tekmeler için bir Java yanıtı koyalım" yanıtı. Oh iyi. Ama, en azından, cevabımın bu noktasına ulaşmak için uğraştığın için, seni biraz daha sıkmaya ve mantığımı açıklamaya çalışacağım.

Yöntem gistenen yılı alır ve her ay için bir GregorianCalendarnesne oluşturur (aylar 0-11 arasıdır). Daha sonra, ilk c.setgün haftanın gününü Pazar olarak belirler ve ikincisi de ayın son haftasını istediğimizi - resmi belgelerde görüldüğü gibi - beyan eder . Bu System.out.printlnPazar gününün tarihini basarsa (bunu doğru yapsaydık, yıl olarak yazdırılacaktı c.get(c.YEAR), ancak ytekrar 13 karakter kullanıyordu), ayın Ocak ayından Eylül ayına önde gelen sıfır ekleyecek şekilde biçimlendirilmesi gerekiyor (ve değer artar, çünkü burada aylar 0-11 temsil edilir) ve geçen Pazar günü yazdırılır. Ve bu prosedür diğer on bir ay boyunca tekrarlanır.


0

C #, 212 , 237

string x(int y){var s="";var t="";var d=new DateTime(y,1,1);for(;;){if(d.Year!=y){return s;}t=(d.DayOfWeek==DayOfWeek.Sunday)?t=string.Format("{0}-{1}-{2} ",d.Year,d.Month,d.Day):t;s=(d.AddDays(1).Month!=d.Month)?s+=t:s;d=d.AddDays(1);}}

Satır kesmeleri ile

string x(int y)
    {
        var s = "";
        var t = "";
        var d = new DateTime(y,1,1);
        for (;;)
        {
            if (d.Year != y) {
                return s;
            }
            t = (d.DayOfWeek == DayOfWeek.Sunday) ? t = string.Format("{0}-{1}-{2} ", d.Year, d.Month, d.Day) : t;
            s=(d.AddDays(1).Month!=d.Month)?s+=t:s;
            d=d.AddDays(1);
        }
    }

2014 Çıktıları

"2015-1-25 2015-2-22 2015-3-29 2015-4-26 2015-5-31 2015-6-28 2015-7-26 2015-8-30 2015-9-27 2015-10-25 2015-11-29 2015-12-27"

Gerekli çıktı biçimi değil
edc65

Orada düzeltildi. Daha iyi?
Darren Breen

0

C # 171

Bir dize döndüren işlev.

string S(int y){var r="";for(int m=1;m<13;++m){var d=new System.DateTime(y,1,1).AddMonths(m).AddDays(-1);r+=y+string.Format("-{0:00}-{1} ",m,d.Day-d.DayOfWeek);}return r;}

Ungolfed

string S(int y)
{
    var r="";
    for (int m=1;m<13;++m)
    {
        var d = new System.DateTime(y, 1, 1).AddMonths(m).AddDays(-1);
        r += y + string.Format("-{0:00}-{1} ", m, d.Day - d.DayOfWeek);
    }
    return r;
}

0

C # 194

Linq kullanarak:

string d(int y){return string.Join(" ",Enumerable.Range(1,12).Select(m=>new DateTime(y,m,DateTime.DaysInMonth(y,m))).Select(d=>d.AddDays(-(int)d.DayOfWeek)).Select(d=>d.ToString("yyy-MM-dd")));}

Ungolfed

string d(int y)
{
    return string.Join(" ",Enumerable.Range(1,12)
        .Select(m => new DateTime(y, m, DateTime.DaysInMonth(y, m)))
        .Select(d => d.AddDays(-(int)d.DayOfWeek))
        .Select(d => d.ToString("yyy-MM-dd")));
}

Çıktı

2013-01-27 2013-02-24 2013-03-31 2013-04-28 2013-05-26 2013-06-30 2013-07-28 2013-08-25 2013-09-29 2013-10-27 2013-11-24 2013-12-29

0

Mathematica - 171

Anonim bir işleve sarılır, dizeyi döndürür

StringJoin[Last@#~DateString~{"Year","-","Month","-","Day"," "}&/@GatherBy[Select[DateRange[DateObject[{#}],DateObject[{#+1}]],DayName@#==Sunday&],DateValue[#,"Month"]&]]&

İlk mathematica golf. Büyük ölçüde azaltılabileceğini hissediyorum.


0

VB-192

Function z(y)
For i = 1 To 11
a = 0
s = IIf(i <> 11, DateSerial(y, i + 1, 1), DateSerial(y + 1, 1, 1))
While Weekday(s - a) <> 1
a = a + 1
Wend
r = r + Str(s - a) + " "
Next
z = r
End Function

Daha kötü olabilir ^ ^

İkinci ve son girişim (daha küçük olabileceğimi sanmıyorum)

142

Function z(y)
Dim m(12)
For i = 1 To 366
s = DateSerial(y, 1, 1) + i
If Weekday(s) = 1 Then m(Month(s)) = s
Next
z = Join(m, " ")
End Function

0

Yakut 76

Bir komut satırı parametresi kullanır ruby sundays.rb 1900. Tarih kütüphanesini kullanır.

require'date';puts (1..12).map{|m|d=Date.new($*[0].to_i,m,-1);d-d.wday}*" "
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.