Geçen pazartesi


27

31 Ekim Pazartesi, Cadılar Bayramı. Ve bu beni düşündürdü - Başka ay ayın son günü ne acaba ayrıca Pazartesi olmak?

Giriş

  • Bir yılı temsil eden uygun formatta pozitif bir tamsayı 10000 > y > 0,.
  • Girişi (örneğin sıfır gelerek edilebilir 0025yıl için 25gerekliyse).

Çıktı

  • Ayın son gününün Pazartesi olduğu o yılın aylarının listesi.
  • Bu , okuyucunun belirsiz olduğu sürece, ay adları (örn. January, March, October) Veya kısa adlar ( Jan, Mar, Oct) veya numbers ( 1, 3, 10), ayrı satırlar veya bir liste veya sınırlandırılmış vb. Olabilir.
  • Çıktı formatı tutarlı olmalıdır:
    • Tüm yılların girişi için (yani, bazı girdiler için ay adları ve diğer girdiler için ay numaraları yazamazsınız)
    • İyi çıkış başına tutarlı olduğunca (yani yapamazsın çıkış 1için Januaryaynı çıktı Juliçin July)
    • Temel olarak, bir format seçin ve buna bağlı kalın.

kurallar

  • Giriş / çıkış için Gregoryen takvimini aşağıya inmiş olarak kabul edin y = 1.
  • Artık yılların doğru bir şekilde muhasebeleştirilmesi gerekir (bir hatırlatma olarak: 400 - 1700, 1800, 1900 ile bölünmediği sürece, her biri 100 ile bölünmeyen yıllar hariç, her biri 4 ile bölünebilir), ancak hepsi 2000 yıl olarak kalmadı.
  • İstediğiniz yerleşik veya diğer tarih hesaplama araçlarını kullanabilirsiniz.
  • Tam bir program veya bir işlev kabul edilebilir. Bir işlev varsa, çıktıyı yazdırmak yerine geri gönderebilirsiniz.
  • Standart boşluklar yasaktır.
  • Bu olduğundan, tüm normal golf kuralları geçerlidir ve en kısa kod (bayt cinsinden) kazanır.

Örnekler

   1 --> Apr, Dec
 297 --> May
1776 --> Sep
2000 --> Jan, Jul
2016 --> Feb, Oct
3385 --> Jan, Feb, Oct

Liderler Sıralaması



1
İlişkili ancak yinelenmeyenler veya?
ElPedro

@ElPedro İlişkili ancak yinelenen değil. Birincisi, herhangi bir yerleşik yapıya izin vermez ve sabit bir tarih / gün birleşimine (13. Cuma) sorar, ikincisi ise yılın her ayı son ayının 1900
3015

Maalesef @TimmD. Yorumunuzu yanlış anladım.
ElPedro

1
@ElPedro Sorun değil! Bir sorum olmamayı ve net olmamasını tercih ederim, bir sorum olmamak ve net olmayan bir şey yapmaktan.
AdmBorkBork

Yanıtlar:


2

Dyalog APL ile dfns sitesindeki cal , Sürüm 15.0: 22; Sürüm 16.0: 19 bayt

Cal fonksiyonu varsayılan bir kurulumla gelir, sadece girin )copy dfns.

15.0 Versiyonu: ∊⎕{⍵/⍨2=≢⍎⊢⌿cal⍺⍵}¨⍳12

enlist (düzleştirmek)

⎕{... aşağıdaki adsız işleve sol argüman olarak sayısal girdi, sağ yan değerlerin her birini de sağ argüman olarak alarak

⍵/⍨ eğer argüman (değilse boş bir liste verir)

2= iki (yani Pazar ve Pazartesi) eşittir

taksiti

sayılar

⊢⌿ en alttaki satır

cal için takvim

⍺⍵ yıl sol argümanı, ay sağ argümanı, ikincisi

⍳12 1 ila 12

Sürüm 16.0: ⍸2=⎕{≢⍎⊢⌿cal⍺⍵}¨⍳12

endeksleri nerede

2= iki eşittir (yani Pazar ve Pazartesi)

⎕{... aşağıdaki adsız işleve sol argüman olarak sayısal girdi, sağ yan değerlerin her birini de sağ argüman olarak alarak

taksiti

sayılar

⊢⌿ en alttaki satır

cal için takvim

⍺⍵ yıl sol argümanı, ay sağ argümanı, ikincisi

⍳12 1 ila 12


19

JavaScript (Firefox 30+), 112 109 103 95 bayt

Bak ma, yerleşik değil!

y=>[for(m of(i=0,y%4|y%400*!(y%100)&&6)+"63153042641")if((i++,y+(y>>2)-(y/100|0)*3/4|0)%7==m)i]

İşte 107 bayt ES6 sürümü:

y=>[...(y%4|y%400*!(y%100)&&6)+"63153042641"].map((m,i)=>(y+(y>>2)-(y/100|0)*3/4|0)%7-m?0:i+1).filter(x=>x)

Ve işte önceki denemem, 123 113 byte ES6:

y=>[(l=y%4|y%400*!(y%100))?[7]:[1,7],[4,12],[9],[3,6],[8,11],[5],l?[1,2,10]:[2,10]][(y+(y>>2)-(y/100|0)*3/4|0)%7]

açıklama

Belirli bir yılın haftanın günü şöyle hesaplanır:

y+(y>>2)-(y/100|0)*3/4|0)%7

Diğer bir deyişle:

  • Al y.
  • Öncesinde 4. yıl sayısını giriniz y( y>>2).
  • Önce 100) yıl sayısını çıkarın y( y/100|0).
  • Önceki 400. yıl sayısına geri ekleyin y; bu 1/4 y/100|0, yani biz kullanıyoruz *3/4|0.

Ardından sonucu 7 ile modüle ederiz. 0Pazar günü, Pazar 1günü, vb. Anlamına gelirsek, sonuç o yılın 31 Aralık haftası gününe karşılık gelir. Bu nedenle, Aralık için sonucun olup olmadığını kontrol etmek istiyoruz 1. Bu bize ipteki son karakteri verir.

Kasım ayının son günü, Aralık ayının son gününden 31 gün öncedir. Bu, Kasım ayının son gününün Pazartesi olması için 31 Aralık’ın (1 + 31) % 7 = 4= Perşembe olması gerektiği anlamına gelir .

Bu prosedür Mart (a 3) 'ya geri dönene kadar tekrar edilir . Artık bir gün olup olmadığına bakılmaksızın, Şubat ayının son günü Mart ayının son gününden 31 gün öncedir, bu yüzden bunu da hesaplayabiliriz (3 + 31) % 7 = 6. İşin zor yanı Ocak için doğru değeri bulmak:

  • Artık bir yılsa, Ocak ayının son günü Şubat ayının son gününden 29 gün önce sonuçlanır (6 + 29) % 7 = 0.
  • Aksi takdirde, Şubat ayının son gününden 28 gün önce sonuçlanır (6 + 28) % 7 = 6.

Aşağıdaki snippet ile artık bir yıl olup olmadığını hesaplayabiliriz:

!(y%400)|y%100*!(y%4)

Bu verir 0eğer yartık yıl değildir ve pozitif bir tamsayı aksi. Bu bizi yönlendirir

!(y%400)|y%100*!(y%4)?0:6

Ocak için günü hesaplamak için. Ancak, koşulları tersine çevirerek daha iyisini yapabiliriz:

y%4|y%400*!(y%100)?6:0

Sahte sonuç her zaman 0 olduğu için, bunu azaltabiliriz.

y%4|y%400*!(y%100)&&6

bir tane daha değerli bayt tasarrufu.

Hepsini bir araya koyarsak, dizedeki her karakter boyunca döngü kurarız, her birinin 31 Aralık haftası gününe eşit olup olmadığını kontrol ederiz. Bu diziyi sonuçta döndürerek eşleşen dizinin dizinlerini tutarız. Ve böyle yapmadan yıl hesaplamaları yap.


Owww ... Beynim, yıllarca atladığın şeyleri anlattın mı?
Magic Octopus Urn

2
@carusocomputing Bunun !(y%4)*y%100|!(y%400)için var. 4 tarafından her yıl bölünebilen yıllar sürece de bölünebilir 400 tarafından, 100 ile bölünebilecek değil hariç
mbomb007

Umarım y+(y>>2)+(z=y/25>>2)+(z>>2)hala bir bayt kurtarır.
Neil

@Neil Teşekkürler, ama daha iyi bir yol buldum :-)
ETHproductions

Güzel; Batch port'umda 6 bayt kullandım (y*5/4-(y/100)*3/4).
Neil

11

JavaScript (Firefox 30-57), 67 65 64 63 61 bayt

y=>[for(_ of(m='')+1e11)if(new Date(y+400,++m).getDay()==2)m]

Kaydedilen 2 4 @ETHproductions 6 bayt sayesinde. Ayları ters sırada yazdırarak başka bir bayttan tasarruf edin.


Bence 2 .keys()y=>[for(_ of(m=0,Array(12)))if(new Date(y+400,++m).getDay()==2)m]
byte'ı kanatsız olarak

@ETHproductions Sıralamayı tersine çevirerek daha fazla byte tasarrufu yapabilirim!
Neil,

Ters sıra iyi. Çıktıyı biçimlendirmek bu zorluğun ilginç bir parçası değil.
AdmBorkBork 27:16

Dizi Anlaşmaları konusundaki politikamız şimdi şartnameden kaldırıldı mı?
MayorMonty

Array(12)Tamamen atlayarak başka bir 2 bayttan tasarruf edebilirsiniz : y=>[for(_ of(m=0,1e11+""))if(new Date(y+400,++m).getDay()==2)m]
ETHproductions

8

MySQL, 183 134 129 106 bayt

SET @y=2016;SELECT help_topic_id AS m FROM mysql.help_topic HAVING m BETWEEN 1 AND 12 AND 2=DAYOFWEEK(LAST_DAY(CONCAT(@y,-m,-1)))

2016İstediğiniz yıl ile değiştirin . Koşmak.

Rev. 2: help_topicsTabloyu geçici bir tablo oluşturmak yerine varsayılan kurulumda kullandı.

Rev.3: Aross´un -hilesini benimsemiş ve teklifleri de ihmal edebileceğimi fark ettim "-1".
Ancak, -1MySQL'de gereklidir: Tam bir tarihe ihtiyacım var.

Rev.4: Kısıtlama (-6) m BETWEEN 1 AND 12olarak yapılabilir m>0 AND m<13, ancak hiç de gerekli değildir - geçersiz değerler göz ardı edilir; uyarılar sayılacak ancak listelenmeyecektir.


Gerçekten masa şema mysql ihtiyacınız var? mariadb.com/kb/en/mariadb/mysqlhelp_topic-table
Jörg Hülsermann

@ JörgHülsermann Ben bir şey anlamadım.
Titus

Olmalı FROM help_topicolmadan mysql.çalışması? Ben denemek zorunda
Jörg Hülsermann

@ JörgHülsermann sadece hazırlarsanız USE mysql;Doğru veritabanı bir şekilde seçilmelidir.
Titus

5

Perl, 64 bayt

İçin +1 içerir -n

STDIN'e giriş verin:

perl -M5.010 mon.pl <<< 2016

mon.pl:

#!/usr/bin/perl -n
map$b.=$/.gmtime$_.e4,-7e6..3e7;say$b=~/on (\S+ )\S.* $_.* 1 /g

5

Toplu iş, 160 152 bayt

@set/ay=%1,m=0,j=6*!(!(y%%4)*(y%%100)+(y%%400)),y=(y*5/4-y/100*3/4)%%7
@for %%d in (%j% 6 3 1 5 3 0 4 2 6 4 1)do @set/am+=1&if %%d==%y% call echo %%m%%

@ ETH üretiminin cevabı limanı. 197 189 bayt ay kısaltmalarıyla :

@set/ay=%1,j=6*!(!(y%%4)*(y%%100)+(y%%400)),y=(y*5/4-y/100*3/4)%%7
@for %%m in (Jan.%j% Feb.6 Mar.3 Apr.1 May.5 Jun.3 Jul.0 Aug.4 Sep.2 Oct.6 Nov.4 Dec.1)do @if %%~xm==.%y% call echo %%~nm

4

J, 48 3433 bayt

[:I.(2=7|_2#@".@,@{.])&>@calendar

@ Adám yardımı ile 15 bayt kaydedildi .

Takvimi, ayları temsil eden bir dizge dizisi oluşturmak için kullanır, ardından son dizilimin ayın son günü olup olmadığını belirlemek için her dizeyi ayrıştırır. Her ayı her birinin ay sayısı olarak verir. Olduğunu, Jan = 0, Feb = 1, ..., Dec = 11.

Çıkış calendarIS

   _3 ]\ calendar 2016
┌─────────────────────┬─────────────────────┬─────────────────────┐
│         Jan         │         Feb         │         Mar         │
│ Su Mo Tu We Th Fr Sa│ Su Mo Tu We Th Fr Sa│ Su Mo Tu We Th Fr Sa│
│                 1  2│     1  2  3  4  5  6│        1  2  3  4  5│
│  3  4  5  6  7  8  9│  7  8  9 10 11 12 13│  6  7  8  9 10 11 12│
│ 10 11 12 13 14 15 16│ 14 15 16 17 18 19 20│ 13 14 15 16 17 18 19│
│ 17 18 19 20 21 22 23│ 21 22 23 24 25 26 27│ 20 21 22 23 24 25 26│
│ 24 25 26 27 28 29 30│ 28 29               │ 27 28 29 30 31      │
│ 31                  │                     │                     │
├─────────────────────┼─────────────────────┼─────────────────────┤
│         Apr         │         May         │         Jun         │
│ Su Mo Tu We Th Fr Sa│ Su Mo Tu We Th Fr Sa│ Su Mo Tu We Th Fr Sa│
│                 1  2│  1  2  3  4  5  6  7│           1  2  3  4│
│  3  4  5  6  7  8  9│  8  9 10 11 12 13 14│  5  6  7  8  9 10 11│
│ 10 11 12 13 14 15 16│ 15 16 17 18 19 20 21│ 12 13 14 15 16 17 18│
│ 17 18 19 20 21 22 23│ 22 23 24 25 26 27 28│ 19 20 21 22 23 24 25│
│ 24 25 26 27 28 29 30│ 29 30 31            │ 26 27 28 29 30      │
│                     │                     │                     │
├─────────────────────┼─────────────────────┼─────────────────────┤
│         Jul         │         Aug         │         Sep         │
│ Su Mo Tu We Th Fr Sa│ Su Mo Tu We Th Fr Sa│ Su Mo Tu We Th Fr Sa│
│                 1  2│     1  2  3  4  5  6│              1  2  3│
│  3  4  5  6  7  8  9│  7  8  9 10 11 12 13│  4  5  6  7  8  9 10│
│ 10 11 12 13 14 15 16│ 14 15 16 17 18 19 20│ 11 12 13 14 15 16 17│
│ 17 18 19 20 21 22 23│ 21 22 23 24 25 26 27│ 18 19 20 21 22 23 24│
│ 24 25 26 27 28 29 30│ 28 29 30 31         │ 25 26 27 28 29 30   │
│ 31                  │                     │                     │
├─────────────────────┼─────────────────────┼─────────────────────┤
│         Oct         │         Nov         │         Dec         │
│ Su Mo Tu We Th Fr Sa│ Su Mo Tu We Th Fr Sa│ Su Mo Tu We Th Fr Sa│
│                    1│        1  2  3  4  5│              1  2  3│
│  2  3  4  5  6  7  8│  6  7  8  9 10 11 12│  4  5  6  7  8  9 10│
│  9 10 11 12 13 14 15│ 13 14 15 16 17 18 19│ 11 12 13 14 15 16 17│
│ 16 17 18 19 20 21 22│ 20 21 22 23 24 25 26│ 18 19 20 21 22 23 24│
│ 23 24 25 26 27 28 29│ 27 28 29 30         │ 25 26 27 28 29 30 31│
│ 30 31               │                     │                     │
└─────────────────────┴─────────────────────┴─────────────────────┘

kullanım

   f =: [:I.(2=7|_2#@".@,@{.])&>@calendar
   f 1
3 11
   f 297
4
   f 1776
8
   f 2000
0 6
   f 2016
1 9
   f 3385
0 1 9

açıklama

[:I.(2=7|_2#@".@,@{.])&>@calendar  Input: year Y
                         calendar  Get 12 boxes each containing a month
    (                )&>@          Operate on each box
                    ]                Identity, get the box
         _2       {.                 Take the last two strings
                ,@                   Flatten it
             ".@                     Parse it into an array of integers
           #@                        Get the length
       7|                            Take it modulo 7
     2=                              Test if it equals 2 - it will either
                                     have two days or 9 days in the last
                                     two lines if the end is on a Monday
[:I.                               Return the indices containing a true value

bekleyin, takvim aslında sanat sanatını mı veriyor?
Yıkılabilir Limon

@DestructibleWatermelon Kesin olarak, çıktı biçimi, calendarher kutu 2d karakter dizisi içeren 12 kutu dizisidir
mil

J'de "her birini" nasıl yapacağımı bile bilmiyorum, ama bu zaten çok daha kısa: I.7=;#&.>".&.>,&.>_2{.&.>calendar 2016Eğer tüm "açık" olanları bir araya getirirseniz, oldukça kısa bir süre için bunu başarabilmelisiniz.
Adám

@ Adám Teşekkürler, daha iyi bir yöntem kullanıyor, ancak J'de bir fiil değil. Hala yardımcı olacağını düşünüyorum
miller

Niyetim sadece ilham vermekti. Bunun bir fiil olmadığını biliyorum.
Adám

4

Mathematica, 62 57 bayt

DayName@DayRange[{#},{#+1},"EndOfMonth"]~Position~Monday&

Anonim işlev Girdi olarak bir sayı alır ve çıktı olarak tek elemanlı sayı listelerinin bir listesini döndürür. Dürüst olmak gerekirse artık nasıl çalıştığından emin değilim.


4

Perl + cal, 46 bayt

say`cal $_ $ARGV[0]`=~/\n.{5}\n/&&$_ for 1..12

Örnek:

$ perl -E 'say`cal $_ $ARGV[0]`=~/\n.{5}\n/&&$_ for 1..12' 2016

2







10


$

1
Açıkçası, bu perl + cal, sadece perl değil :-p. Örneğin, Windows makinem perl, ancak bu orada işe yaramaz.
Philomory

Adil nokta, bu ve benim bash girişimi güncellendi.
Steve

4

Java 7,186 182 172 bayt

4
byte'ı kaydettiği için kevin'e teşekkürler 10 byte'ı kaydettiği için @cliffroot'a teşekkürler

int[]f(int n){int c=n-1,x=c*365+c/4+c/400-c/100,k=0,b[]={3,(n%4<1&n%100>0)|n%400<1?1:0,3,2,3,2,3,3,2,3,2,3},a[]=new int[12];for(int i:b)a[k++]=(x+=i+28)%7==1?1:0;return a;}

ungolfed

int[] f(int n) {
 int c=n-1,x=c*365+(c/4)+(c/400)-(c/100),k=0,
   b[] = {3,(n % 4 < 1 & n % 100 > 0) | n % 400 < 1 ? 1 : 0
                                     ,3,2,3,2,3,3,2,3,2,3},a = new int[ 12 ];

 if ( (n % 4 < 1 & n % 100 > 1) | n % 400 < 1 )
     b[ 1 ] = -1;
 for (int i : b)
    a[ k++ ] = (x += i + 28) % 7 == 1 ? 1 : 0;

return a;
     }

Bu sürüm @cliffroot ( 168 bytes ) tarafından sağlanmıştır

 static int[] f(int n) {
 int b = 13561787 | ( (n%4 < 1 & n%100 > 0) | n%400 < 1 ? 1 << 20 : 0 ),
           x = --n*365 + n/4 + n/400 - n/100,a[]=new int[12],k=0;
    while (k < 12)
    a[k++] = (x += (b >> 24 - k*2&3 ) + 28) % 7 == 1 ? 1 : 0;
  return a;   }
    }

çıktı örneği

1 1 0 0 0 0 0 0 0 1 0 0(for input 3385)

1
Cevabımı yazdım sonra kendinizi daha kısa olacağını şeyi hesaplayarak biliyordu .. :) Btw, golf can n%4==0için n%4<1; n%400==0için n%400<1ve int c=...;int[]b=...,a=...için int c=...,b[]=...,a[]=....
Kevin Cruijssen

1
bve abunun intgibi kısımlarda tanımlanabilir :int ... ,b[]=...,a[]=...
Olivier Grégoire

1
int[]f(int n){int x=--n*365+n/4+n/400-n++/100,k=0,b[]={1,(n%4<1&n%100>0)|n%400<1?-1:-2,1,0,1,0,1,1,0,1,0,1},a[]=new int[12];for(int i:b)a[k++]=(x+=i+30)%7==1?1:0;return a;}çok az sayıda bayt kaydedildi
cliffroot

1
ayrıca 2 bayt biçin b[]={3,(n%4<1&n%100>0)|n%400<1?1:0,3,2,3,2,3,3,2,3,2,3}ve i+30arasında değişiklik yapabiliri+28
cliffroot

1
ve başka bir 3 baytint[]f(int n){int b=13561787|((n%4<1&n%100>0)|n%400<1?1<<20:0),x=--n*365+n/4+n/400-n/100,a[]=new int[12],k=0;while(k<12)a[k++]=(x+=(b>>24-k*2&3)+28)%7==1?1:0;return a;}
cliffroot

3

Python 2, 100 bayt

Ugh. Tarihlerle matematik istediğim kadar basit değil.

lambda y:[m+1for m in range(12)if(date(y,12,31)if m>10else(date(y,m+2,1)-timedelta(1))).weekday()<1]

Çevrimiçi deneyin

Aynı uzunluk:

lambda y:[m-1for m in range(2,14)if(date(y,12,31)if m>12else(date(y,m,1)-timedelta(1))).weekday()<1]

Python'u bununla bile deneyemeyecektim. Güzel çaba.
ElPedro

3

MATL , 21 bayt

12:"G@QhO6(YO9XO77=?@

Aylar sayı olarak görüntülenir.

Çevrimiçi deneyin! Veya tüm test durumlarını doğrulayın .

açıklama

Bu, tarih dönüşüm yerleşik işlevlerini kullanır. Verilen yıl için, hangi ayın son gününün Pazartesi olduğunu test eder.

Ayın son gününü k(28, 29, 30 veya 31 olabilir) açıkça belirtmek yerine , eşdeğer olan ve ay veya yıla bağlı olmayan 0ayın üçüncü gününü belirtiriz k+1.

12:      % Push [1 2 ... 12] (months)
"        % For each month k
  G      %   Push input
  @Q     %   Push k+1
  h      %   Concatenate
  O6(    %   Postpend four zeros. For example, for input 2016 and month k=1 
         %   (first iteration) this gives [2016 2 0 0 0 0] (year, month, day,
         %   hour, min, sec). The 0-th day of month k+1 is the same as the
         %   last day of month k.
  YO     %   Convert the above 6-element date vector to date number
  9XO    %   Convert date number to date string with output format 9, which 
         %   is weekday as a capital letter
  77=    %   Is it an 'M'?
  ?      %   If so
    @    %     Push current month (will be implicitly displayed)

3

Bash + GNU yardımcı programları, 56 bayt

seq -f1month-1day$1-%g-1 12|date -f- +%B%u|sed -n s/1//p

date8.25 sürümünü gerektiriyor gibi görünüyor . Ideone'daki 8.23 ​​sürümü onu kesmiyor.


3

Excel, 537 bayt

Çünkü - bilirsin - Excel!

A1'de girdi yılını alır. Onaltılı ayların listesini döndürür; 1 = Ocak, C = Aralık. Her ay tek bir rakam olduğundan, ayırıcıya gerek yoktur.

=IF(2=WEEKDAY(EOMONTH(DATE(A1,1,1),0)),1,"")&IF(2=WEEKDAY(EOMONTH(DATE(A1,2,1),0)),2,"")&IF(2=WEEKDAY(EOMONTH(DATE(A1,3,1),0)),3,"")&IF(2=WEEKDAY(EOMONTH(DATE(A1,4,1),0)),4,"")&IF(2=WEEKDAY(EOMONTH(DATE(A1,5,1),0)),5,"")&IF(2=WEEKDAY(EOMONTH(DATE(A1,6,1),0)),6,"")&IF(2=WEEKDAY(EOMONTH(DATE(A1,7,1),0)),7,"")&IF(2=WEEKDAY(EOMONTH(DATE(A1,8,1),0)),8,"")&IF(2=WEEKDAY(EOMONTH(DATE(A1,9,1),0)),9,"")&IF(2=WEEKDAY(EOMONTH(DATE(A1,10,1),0)),"A","")&IF(2=WEEKDAY(EOMONTH(DATE(A1,11,1),0)),"B","")&IF(2=WEEKDAY(EOMONTH(DATE(A1,12,1),0)),"C","")

Örnek: A1, 2016'yı içerir. B1, yukarıdaki formülü içerir ve 2AŞubat ve Ekim ayları anlamına gelir.


3

PHP, 109 180 159 bayt

for($z=$argv[1];$m++<12;)if(date(N,strtotime(sprintf("%04d-$m-",$z).cal_days_in_month(0,$m,$z)))<2)echo"$m,";
  • Verilen yılı verir, hepsini değil (... her zaman soruyu okuyun)
  • İhmal edilen bildirimler (teşekkürler Titus)
  • Değişim whileiçin forartık tek bir yıl var olarak (tekrar teşekkürler Titus)

Eski 2

$z=0;while($z++<9999){$o=[];$m=0;while($m++<12)if(date("N",strtotime(sprintf("%04d-$m-","$z").cal_days_in_month(0,$m,$z)))<2)$o[]=$m;echo count($o)>0?"$z:".implode(",",$o)."
":"";}

10000’den 10000’e kadar olan tüm yılları destekliyor, aynı zamanda bir PC’de farkında olmadığım bir tanımlanmamış var uyarısından da kurtuldum. Evet, eski sürümden daha uzun, ancak daha sağlam.

Eski 1

while($z++<9999){$o=[];$m=0;while($m++<12)if(date("N",strtotime("$z-$m-".cal_days_in_month(0,$m,$z)))<2)$o[]=$m;echo count($o)>0?"$z:".implode(",",$o)."
":"";}

Windows veya 32bit sistemde çalışıyorsa, korkunç 2038 hatası ortaya çıkar, ancak 64 bitlik bir linux sisteminde sorun olmaz.

date("t"...Verilen ayın son tarihini temsil etmek için kullanmaya çalıştım , ancak sonuçlar bu konuda daha önce belirtilenlere uymuyordu.


2
-2: görmezden: "$ z" hayır tırnak -7 ihtiyacı bildirimleri (bunlar varsayılan ayarları ile yazdırılır değil: init yok $ziçin hiçbir tırnak N) -1: foryerine while -43 : take girişi yerine yıllar boyunca döngü istendiği gibi -3: -16 joinyerine implode: doğrudan çıktı: for($z=$argv[1];$m++<12;)if(date(N,strtotime(sprintf("%04d-$m-",$z).cal_days_in_month(0,$m,$z)))<2)echo"$m,";+9, izleyen virgül olmadığında ısrar ediyorsanız:echo$o=$o?",$m":$m;
Titus

Ahh soruyu yanlış! Tüm yıl boyunca olduğunu düşündüm .. ayy: B Diğer önerileriniz için de teşekkürler, onları ele alacak
CT14.IT

3

PHP, 92 Bayt

for($d=new DateTime("$argv[1]-1-1");$i++<12;)$d->modify("1month")->format(w)!=2?:print"$i,";

yılın ilk günü salı bir ay sonra 1 ay 12 kez kontrol edin. Eğer öyleyse, ayın son gününden önceki gün Pazartesi günü demektir.


Yazdırmak yerine yankıyı kullanabilir ve 1
Octopus

1
@Octopus üçlü Operatör içinde değil
Jörg Hülsermann 28:16

3

C, 214 bayt

main(int a,char *b[]){for(int x,y,d,m=12;m;m--){y=atoi(b[1]);x=m-1;d=x==1?(y%4==0?(y%100==0?(y%400==0?29:28):29):28):(x==3||x==5||x==10?30:31);if((d+=m<3?y--:y-2,23*m/9+d+4+y/4-y/100+y/400)%7==1)printf("%d\n",m);}}

derleme

gcc -std=c99 -o foo foo.c

Ungolfed

İlgili gurulara krediyle.

C Programı için Michael Keith ve Tom Craver , tarih verilen haftanın gününü bulmak için .

Sorular ve Cevaplar için Collin Biedenkapp : Ayın son gününün nasıl olduğunu nasıl anlarım?

/* credit to Collin Biedenkapp */
short _get_max_day(short x, int z) {
    if(x == 0 || x == 2 || x == 4 || x == 6 || x == 7 || x == 9 || x == 11)
        return 31;
    else if(x == 3 || x == 5 || x == 8 || x == 10)
        return 30;
    else {
        if(z % 4 == 0) {
            if(z % 100 == 0) {
                if(z % 400 == 0)
                    return 29;
                return 28;
            }
            return 29;
        }
        return 28;
    }
}

main(int argc,char *argv[]) {
 for(int y,d,m=12;m;m--) {
  y=atoi(argv[1]);
  d=_get_max_day(m-1,y);
  /* credit to Michael Keith and Tom Craver */
  if ((d+=m<3?y--:y-2,23*m/9+d+4+y/4-y/100+y/400)%7 == 1)
    printf("%d\n",m);
 }
}

1
Ya ifdiğer yöne çevirirseniz, elsegeri dönüşünüzü 31yaparsanız ve böylece büyük ==zinciri ortadan kaldırabilirsiniz ?
AdmBorkBork 27:16

1
(x == 1) {z part} else ise (x == 3 || x == 5 || x == 8 || x == 10)
eğer

1
peki: return x == 1? (z% 4 == 0? (z% 100 == 0? (z% 400 == 0? 29: 28): 29): 28) :( x == 3 | | x == 5 || x == 8 || x == 10 - 30: 31)
RosLuP

TimmyD + RosLuP: dönüş () puan için teşekkürler, şimdi 100 bayt kaydedildi.
steve

1
nihayetinde şu ana kadar azalmaya devam etmek mümkündür: u (y, m) {return m-1? 30 + ((2773 >> m) & 1): 28+ (y% 4 == 0 && y% 100 || y% 400 == 0);} burada y, ay ve aydır
RosLuP

3

C, 119 bayt

t=1248700335,m;main(y){for(scanf("%d",&y),t+=y&3||y%25<1&&y&15;m++,(6+y+y/4-y/100+y/400+t)%7||printf("%d,",m),t;t/=7);}

Bu, artık bir ay için her ayın son gününün hafta içi gününün ofsetini içeren, taban 7 kullanılarak işaretlenmiş 32 bitlik bir sözcükle kodlanmış bir tablo kullanır. Eğer artık yıl değilse, 1 Ocak ofsetini ekleriz. (Gördüğünüz gibi y&3||y%25<1&&y&15artık günler olmadan yılları kontrol etmek için kullanılır). Sonra sadece her ay döngüden geçiyoruz ve son gününün Pazartesi olup olmadığını kontrol ediyoruz. Aslında oldukça basit, çirkin kesmek ya da hileler. İşte biraz ungolfed:

t=1248700335,m;
main(y){
  for(
    scanf("%d",&y),t+=y&3||y%25<1&&y&15;
    m++,(6+y+y/4-y/100+y/400+t)%7||printf("%d,",m),t;
    t/=7
  );
}

Birkaç karakter kaydetme işlevi olarak yeniden yazmak için bunu tekrar ziyaret edebilirim. printfAyrıca biraz fazla yer kaplar ...


Printf ("% d,", m) 1 veya 2, 3 gibi bir şey
basar

Aslında çıktıdaki boşlukları da tercih ederim, ancak golf sahası C çözümlerimi genellikle boşluk bırakmaya gerek kalmadan yazarım, bu yüzden karakter sayımı kontrol etmek istediğimde yarı boşluklu versiyonumdaki tüm boşlukları kopyalayabilirim .
Fors

3

PHP, 96 95 76 71 69 64 61 bayt

Not: yıl sayıları 4 karaktere kadar doldurulmalıdır 0070.

for(;13+$i-=1;)date(N,mktime(0,0,0,1-$i,0,$argn))-1||print$i;

Bu şekilde koş:

echo 3385 | php -nR 'for(;13+$i-=1;)date(N,mktime(0,0,0,1-$i,0,$argn))-1||print$i;';echo
> -1-2-10

açıklama

-1'den -12'ye kadar tekrar eder. Mktime, day 0(önceki ayın son günü) ve ay kullanarak tarih oluşturun 2..13. Tarihi gün numarası olarak biçimlendirin ve sonuç 1 ise, geçerli numarayı yazdırın. Negatif işareti -sınırlayıcı olarak kullanılır.

Millenium Böceği Yine Çarptı!

Bu versiyonda, aralığın 0..100olarak yorumlandığını unutmayın 1970..2069. 0..69Haftalar, her 400 yılda bir (146097 gün, tam olarak 20871 hafta) tekrarlayan bir desene sahip olduğundan bu aralık için sorun değildir , ancak aralık için 70..99, 400'ün katı olmayan yıl sayısına 1900 eklenir. Düzeltmek için SADECE sorunu 10k aralığında 30 yıl sayılar için, en basit yol 2 basamaklı yorumlamayı ( +4 bayt ) önlemek için yıl numarasına 400 eklemektir :

for(;13+$i-=1;)date(N,mktime(0,0,0,1-$i,0,$argn+400))-1||print$i;

Düzenlemeler

  • !~-$iKarşılaştırmak $iiçin kullanarak bir bayt kaydedildi 1( -1ikili negatif 0, mantıksal olarak negatif true; her diğer sayı false), bu nedenle parantez gerekmez
  • last day ofYYYY-mTarih oluşturmak için gösterim kullanarak 19 bayt kaydedildi
  • Kullanarak dateve strtotimeyerine 5 bayt kaydedildidate_create
  • Negatif sayılardan sayılarak, negatif sınırlayıcı olarak çıktı sınırlayıcı olarak (negatif ay numaraları yoktur) ve YYYY-mtarih kısmındaki sınırlayıcıyı kullanarak 2 bayt kaydedildi
  • Kullanarak 5 bayt Kaydedilen mktimeyerine strtotime. Gün kullanmaya geri 0( mktimeaynı zamanda o kadar, ay 13 destekler 0-13== 31-12)
  • Kullanılabilir -Rhale getirmek için 3 bayt kaydedildi$argn

mktimeYılı doldurma gerekliliğini ortadan kaldırıyor, değil mi?
Titus,

@Titus, keskin. Eh ben sadece anladım mktimeolduğu karşı-sezgisel argümanlar olarak alındığı için, INTs. Bunun anlamı seneyi kapatamazsın ... yani menzil 0..100içindeki her şey olarak yorumlanır 1970..2070. Bu aralık için sorun yok 0..70çünkü 400 yıl kesin bir hafta sayısına sahip (bu yüzden takvimler her 400 yılda bir modeli tekrarlıyor), ancak 70..991900 ekliyor (400'ün katı değil!). Bu nedenle yeni ver. bir böcek var.
Ekim’den

Şu an bunun için gördüğüm tek çözüm $argv[1]+400... Julian ve Gregorian'ın hafta içi günleri farklı olmadığı sürece.
Titus

@Titus, evet. Kurallar Kullanım Gregoryen cal demek
aross

3

Excel, 428 97 96 bayt

A1'de giriş yapın. Ayrılmamış Onaltılık değerlerin çıkışı (Ocak = 0, Aralık = B)

=IF(2=WEEKDAY(DATE(A1+2000,1,31)),0,"")&CHOOSE(WEEKDAY(DATE(A1+2000,3,0)),4,19,6,"3B",8,25,"7A")

1990 öncesi tarihlerin kullanılmasına izin vermek için 10 bayt ("+2000") eklendi.

@ Engineer Toast sayesinde 11 bayt kaydedildi .


İlk girişim (428 bytes), @ Adám'ın çözümünden ağır borç aldı .

=IF(2=WEEKDAY(DATE(A1,1,31)),1,"")&IF(2=WEEKDAY(EOMONTH(DATE(A1,2,1),0)),2,"")&IF(2=WEEKDAY(DATE(A1,3,31)),3,"")&IF(2=WEEKDAY(DATE(A1,4,30)),4,"")&IF(2=WEEKDAY(DATE(A1,5,31)),5,"")&IF(2=WEEKDAY(DATE(A1,6,30)),6,"")&IF(2=WEEKDAY(DATE(A1,7,31)),7,"")&IF(2=WEEKDAY(DATE(A1,8,31)),8,"")&IF(2=WEEKDAY(DATE(A1,9,30)),9,"")&IF(2=WEEKDAY(DATE(A1,10,31)),"A","")&IF(2=WEEKDAY(DATE(A1,11,30)),"B","")&IF(2=WEEKDAY(DATE(A1,12,31)),"C","")

Bu 1900'den önceki yıllarda nasıl çalışır? Test durumu bu formülle 297 -> Maygeri döner 6. 4 olmalı mı? sadece Eylül için yerine 1776verir . 7A8
Mühendis Toast

İşe yararsa, muhtemelen, Date(A1,3,0)yerine kullanabilirsinizEOMONTH(DATE(A1,2,1),0)
Mühendis Toast

2

Bash + cal, 58 bayt

$ cat t.sh
for A in {1..12};do cal $A $1|grep -qx .....&&echo $A;done
$ bash t.sh 2016
2
10
$

+1 - BSD için çalışır cal(örn. OSX), ancak GNU’da izlenen boşlukları izleyin cal.
Dijital Travma

2

Python 2, 94 bayt

from datetime import*
lambda y:[m for m in range(1,13)if date(y+(m>11),m%12+1,1).weekday()==1]

repl.it

Adsız bir işlev, tamsayı bir yıl alır, ay sayılarının bir listesini çıkarır [1-12].

Ayrıca bayt sayısını aritmetik olarak başarı ile (110 bayt) yenmeye çalıştım. :

lambda y:map(lambda x,v:(23*((x+2)%13or 1)/9+y-2*(0<x<11)+(x>10)+v/4-v/100+v/400)%7==4,range(12),[y-1]+[y]*11)

[Ocak-Aralık] ayının Pazartesi günü bitip bitmeyeceğini temsil eden bir boole değerleri listesi döndüren adsız işlev


2

Java 7, 200 249 bayt

import java.util.*;String c(int y){String r="";GregorianCalendar c=new GregorianCalendar();c.setGregorianChange(new Date(1L<<63));c.set(1,y);c.set(2,0);for(int i=0;i++<12;c.add(2,1)){c.set(5,c.getActualMaximum(5));if(c.get(7)==2)r+=i+" ";}return r;}

Java'da, GregorianCalendarbir Gregoryen ile Julian takvimi arasında bir karışımdır. Bu nedenle, yıl 1yanlış sonuçlar verdi. Değişen Calendar c=Calendar.getInstance();için GregorianCalendar c=new GregorianCalendar();c.setGregorianChange(new Date(1L<<63));sadece Gregoryen takvimin bir kullanım zorlayarak düzeltmeleri bu. Bunu bana açıkladığı için stackoverflow.com'daki @JonSkeet'e teşekkürler .

Ungolfed ve test kodu:

Burada dene.

import java.util.*;
class M{
  static String c(int year){
    String r = "";
    GregorianCalendar calendar = new GregorianCalendar();
    calendar.setGregorianChange(new Date(Long.MIN_VALUE));
    calendar.set(Calendar.YEAR, year);
    calendar.set(Calendar.MONTH, 0);
    for(int i = 0; i++ < 12; calendar.add(Calendar.MONTH, 1)){
      calendar.set(Calendar.DATE, calendar.getActualMaximum(Calendar.DATE));
      if(calendar.get(Calendar.DAY_OF_WEEK) == 2){
        r += i+" ";
      }
    }
    return r;
  }

  public static void main(String[] a){
    System.out.println(c(1));
    System.out.println(c(297));
    System.out.println(c(1776));
    System.out.println(c(2000));
    System.out.println(c(2016));
    System.out.println(c(3385));
  }
}

Çıktı:

4 12
5 
9 
1 7 
2 10 
1 2 10 

2

C # 6 C #, 171 167 135 bayt

using System;
void d(int n){for(int i=0;++i<13;)if((int)new DateTime(n,i,DateTime.DaysInMonth(n,i)).DayOfWeek==1)Console.Write(i+" ");}

Shebang sayesinde -32 bayt

Ayları sayı olarak yazdır; ayrılmış alanla; sondaki boşlukla. Şimdi bu cevap C # 'nın önceki sürümleri için de geçerli.


Eski, 167 bayt

using System;using System.Linq;
c(int n)=>string.Join(",",Enumerable.Range(1,12).Where(i=>new DateTime(n,i,DateTime.DaysInMonth(n,i)).DayOfWeek==(DayOfWeek)1));

TimmyD sayesinde -4 bayt

Çıktı ayları, döndürülen dizgede sayılardır, virgülle ayrılmış

Ungolfed

string c(int n)=>
    string.Join(",",                                        // Join them with commas
        Enumerable.Range(1,12)                              // For 1-12 inclusive
        .Where(                                             // Select only
            i=>new DateTime(n,i,DateTime.DaysInMonth(n,i)   // Get last day of that year-month
            ).DayOfWeek                                     // Get its day of week
            ==(DayOfWeek)1                              // Is Monday
        )
    )
;

@TimmyD Evet, ancak açık bir döküm gerekiyor. Cevap güncellendi
Link Ng

LINQ eğlenceli ama bu 126 bayt: void q(int y){for(int m=1;m<13;m++){if((int)new DateTime(y,m,DateTime.DaysInMonth(y,m)).DayOfWeek==1){Console.WriteLine(m);}}};) Ayrıca, dökümün yapılması daha kısa olacağını DayOfWeekhiç intdökümün yapılması olacağından daha inthiçDayOfWeek
Kade

@Shebang Teşekkürler. Gerçekten tek hatlı linq golf yapmamalıyım --- Sadece Jon Skeet bunu yapabilir. Yarın güncelleme için vaktim var mı bakın. Şimdi bıktım.
Link Ng,

Bunun bir olmak dönüştürebilirsiniz Action<int>bazı bayt kaydetmek
TheLethalCoder

2

Ruby, 54 + 6 = 60 bayt

λ cat monday.rb
p (1..12).select{|m|Date.new($*[0].to_i,m,-1).monday?}
λ ruby -rdate monday.rb 2016
[2, 10]

-rdateStandart kütüphaneden Date sınıfını almak için komut satırında 6 bayt .

Açıklama: Ruby stdlib'in mükemmel Datesınıfı sayesinde oldukça basit . Yapıcı, vb. Gibi yöntemlere sahip olmakla kalmaz monday?, tuesday?geçen yıl herhangi bir alanda 'bu alanı bir önceki alan tarafından temsil edilen dönemin sonundan geriye doğru saymak' anlamına gelir. $*için steno edilir ARGV, bu nedenle $*[0]ilk komut satırı argümanı almak için hızlı bir yoldur.


2

PHP, 84 bayt

for($m=1;$m++<14;){if(strftime('%w',strtotime($argv[1]."-$m-1"))==2)echo($m-1)." ";}

İlk Kod Golf'üm. Bu, şu ana kadarki en kısa PHP.

EDIT: 1 yıl için çalışmıyor gibi görünüyor. Nedenini bulmak zorundayım, ama şimdi gitmek zorundayım.


1
"PPCG'ye Hoş Geldiniz!" Derdim. ama sen burada benden daha uzun süredir kayıtlısın! : D Güzel ilk golf.
AdmBorkBork 27:16

Hata, 1 <13 yıl için 1-13-1 ve 1-14-1 oluşturmanız yeterlidir. Bunu çözersen şu anda gereksiz parantezleri kaldırabilir ve üçlü operatör kullanmayı düşünebilirsin
Jörg Hülsermann 27:16

This should fixed your problems for(;$m++<12;)strftime("%w",strtotime($argv[1]+($m/12^0)."-".($m%12+1)."-1"))!=2?:print"$m ";
Jörg Hülsermann

2

R, 106 99 95 83 78 77 74 bytes

g=function(x)which(format(seq(as.Date(paste0(x,-2,-1)),,'m',12)-1,"%u")<2)

The sequence of last days of each month is given by seq(as.Date(paste0(x,-2,-1)),,'m',12)-1:

  • paste0 coerces -2 and -1 to characters. If the x was 2016 for instance, paste0(x,-2,-1) gives "2016-2-1" which is then converted to the 1st of February 2016 by as.Date.

  • seq applied to a POSIXct or a Date object is seq(from, to , by, length.out): here to is not given, by is given as 'm' which is matched to 'month' thanks to partial matching, and length.out is of course 12.

  • The resulting sequence is the first day of the 12 months starting with February of the year in question. -1 gives us then the last day of the 12 months starting with January of the year in question.

Test cases:

> g(1)
[1]  4 12
> g(25)
[1] 3 6
> g(297)
[1] 5
> g(2000)
[1] 1 7
> g(2016)
[1]  2 10
> g(3385)
[1]  1  2 10
> g(9999)
[1] 5

Old version at 95 bytes, outputting the month names instead of just their numbers:

g=function(x)format(S<-seq(as.Date(sprintf("%04i-02-01",x)),,'m',12)-1,"%B")[format(S,"%u")==1]

This answer is just brilliant. I had no idea seq had a method for Date -objects and this solves the issue of as.Date not handling years above 10000 in my deleted answer.
Billywob

@Billywob yes seq.Date and seq.POSIXt are quite impressive: they can even process commands such as seq(time1, time2, by="10 min") or seq(date1, date2, by="quarter"). Very useful when plotting a time-series.
plannapus

2

Japt, 24 bytes

Do1 £Ov"Ð400+U"+X e ¥2©X

Test it online! Outputs an array of numbers, with false in place of months that don't end in a Monday.

There was a bug in the interpreter that didn't allow me to use Ð in the function body £. After the bug fix and another feature addition, this is 18 bytes in the current commit:

Do1@Ð400+UX e ¥2©X

1

Java, 143 129 bytes

This uses the new time API of Java 8.

y->{String s="";for(int m=0;++m<13;)if(java.time.YearMonth.of(y,m).atEndOfMonth().getDayOfWeek().ordinal()==0)s+=m+" ";return s;}

Output

Note that each line has an extra space at the end.

4 12 
5 
9 
1 7 
2 10 
1 2 10 

Ungolfed and testing

import java.time.*;
import java.util.function.*;

public class Main {
    public static void main (String[] args) {
        IntFunction<String> func = year -> {
          String result = "";
          for (int month=1; month <= 12; month++) {
            if (YearMonth.of(year, month).atEndOfMonth().getDayOfWeek().ordinal() == 0) {
              result += month + " ";
            }
          }
          return result;
        };
        System.out.println(func.apply(1));
        System.out.println(func.apply(297));
        System.out.println(func.apply(1776));
        System.out.println(func.apply(2000));
        System.out.println(func.apply(2016));
        System.out.println(func.apply(3385));
    }
}

Shaves

  1. 143 to 129 bytes: use DayOfWeek::ordinal to compare with a numerical constant instead of the enum constant.
    Thanks @TimmyD for the general idea if not the exact solution! ;-)

@TimmyD sadly, it's an enum. It does have a getValue() method, though, which would save a few bytes.
Celos

@Celos ordinal() saves 1 more byte compared to getValue(), even though it is suggested to never use it.
Olivier Grégoire

yes, good thinking. I posted my comment without first refreshing, so I didn't see your reply and edit.
Celos

1

GNU awk, 80 bytes

{for(;m<13;a=mktime($0" "++m" 1 9 0 0")){if(strftime("%w",a-8e4)~1){print m-1}}}

Example

$ gawk '{for(;m<13;a=mktime($0" "++m" 1 9 0 0")){if(strftime("%w",a-8e4)~1){print m-1}}}' <<<2016
2
10
$
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.