지난 월요일


27

10 월 31 일 월요일은 할로윈입니다. 그리고 그것은 나를 생각있어 - 내가 다른 달은 달의 마지막 날이 궁금해 월요일 일을?

입력

  • 양의 정수 편리한 형식으로 년을 대표하는 10000 > y > 0.
  • 필요한 경우 입력을 0으로 채울 수 있습니다 (예 : 0025연도 25).

산출

  • 해당 월의 마지막 날이 월요일 인 월의 목록입니다.
  • 독자에게 명확하지 않은 한 , 월 이름 (예 January, March, October:) 또는 짧은 이름 ( Jan, Mar, Oct) 또는 숫자 ( 1, 3, 10), 별도의 줄 또는 목록 또는 구분 등이 될 수 있습니다.
  • 출력 형식은 일관성이 있어야합니다.
    • 모든 연도 입력 (즉, 일부 입력의 월 이름과 다른 입력의 월 번호는 출력 할 수 없음)
    • 물론 출력에 따라 일관 한 (의미, 당신이 할 수없는 출력 1에 대한 January동일한 출력 Jul을위한 July)
    • 기본적으로 하나의 형식을 선택하고 고수하십시오.

규칙

  • 입 / 출력을 위해 그레고리력 달력을 가정합니다 y = 1.
  • 윤년은 올바르게 설명해야합니다 (알림 : 매년 4로 나눌 수 있음, 100으로 나눌 수있는 기간은 제외), 400-1700, 1800, 1900으로 나눌 수있는 경우를 제외하고는 모두 윤년이 아니었지만 2000 년이었습니다.
  • 내장 또는 기타 날짜 계산 도구를 사용할 수 있습니다.
  • 전체 프로그램 또는 기능이 허용됩니다. 함수 인 경우 출력하지 않고 출력을 반환 할 수 있습니다.
  • 표준 허점 은 금지되어 있습니다.
  • 이것은 이므로 모든 일반적인 골프 규칙이 적용되며 가장 짧은 코드 (바이트)가 이깁니다.

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

리더 보드



1
관련이 있지만 중복되지 않습니까?
ElPedro

@ElPedro 관련이 있지만 중복되지는 않습니다. 첫 번째는 빌트인을 허용하지 않으며 고정 된 날짜 / 일 콤보 (13 일 금요일)를 요청하는 반면, 두 번째는 1900 년에서 3015 년으로 제한되는 매월 마지막 일요일을 요청합니다.
AdmBorkBork

@TimmD 죄송합니다. 당신의 의견에 대한 나의 오해.
ElPedro

1
@ElPedro 문제 없습니다! 차라리 질문이없고 분명 하지 않은 것보다는 질문이 있고 명확 해야합니다.
AdmBorkBork

답변:


2

dfnscal , 버전 15.0을 갖는 Dyalog APL : 22; 버전 16.0 : 19 바이트

cal 기능은 기본 설치와 함께 제공됩니다 )copy dfns.

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

입대하다

⎕{... 다음 익명 함수에 대한 왼쪽 인수로 숫자 입력, 각 오른쪽 값을 차례로 오른쪽 인수로 사용

⍵/⍨ 인수 if (그렇지 않으면 빈 목록을 제공)

2= 2 (일요일과 월요일)는

탈리

의 숫자

⊢⌿ 최하단

cal 달력

⍺⍵ 왼쪽 인수, 왼쪽 오른쪽 인수, 후자는

⍳12 1에서 12

버전 16.0 : ⍸2=⎕{≢⍎⊢⌿cal⍺⍵}¨⍳12

어디에서 인덱스

2= 두 개 (일요일과 월요일)

⎕{... 다음 익명 함수에 대한 왼쪽 인수로 숫자 입력, 각 오른쪽 값을 차례로 오른쪽 인수로 사용

탈리

의 숫자

⊢⌿ 최하단

cal 달력

⍺⍵ 왼쪽 인수, 왼쪽 오른쪽 인수, 후자는

⍳12 1에서 12


19

자바 스크립트 (파이어 폭스 30 +), 112 (109) 103 95 바이트

엄마 봐, 내장이 없어!

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]

107 바이트 ES6 버전은 다음과 같습니다.

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)

그리고 내 이전 시도는 123 113 바이트의 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]

설명

특정 연도의 요일은 다음과 같이 계산됩니다.

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

다른 말로:

  • 가져 가라 y.
  • 4 년 전 y( y>>2)을 더하십시오.
  • y( y/100|0) 전에 100 년을 뺍니다 .
  • 400 년 전에 다시 추가 y; 이것은 1/4입니다 y/100|0. 그래서 우리는 사용 *3/4|0합니다.

그런 다음 결과를 7로 변조합니다. 0일요일, 1월요일 등을 의미하면 결과는 해당 연도의 12 월 31 일 요일에 해당합니다. 따라서 12 월에 대해 결과가 0인지 확인하려고합니다 1. 이것은 우리에게 문자열의 마지막 문자를 제공합니다.

11 월 마지막 날은 12 월 마지막 날 전 31 일입니다. 이것은 11 월 마지막 날이 월요일이고 12 월 31 일은 (1 + 31) % 7 = 4= 목요일 이어야 함을 의미합니다 .

이 절차는 3 월 (a 3)로 돌아갈 때까지 반복 됩니다. 윤일이 있든 없든, 2 월 마지막 날은 3 월 마지막 날 전 31 일이므로 우리도 계산할 수 있습니다 (3 + 31) % 7 = 6. 까다로운 부분은 1 월의 올바른 값을 찾는 것입니다.

  • 윤년 인 경우 1 월 마지막 날은 2 월 마지막 날 29 일 이전에 (6 + 29) % 7 = 0.
  • 그렇지 않으면 2 월 마지막 날 28 일 전입니다 (6 + 28) % 7 = 6.

다음 스 니펫을 사용하여 윤년인지 여부를 계산할 수 있습니다.

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

이것은 윤년이 아닌 0경우 y양수, 그렇지 않으면 양의 정수를 제공합니다. 이로 인해 우리는

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

1 월의 날짜를 계산합니다. 그러나 다음과 같은 조건을 바꾸면 더 잘할 수 있습니다.

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

어쨌든 허위 결과는 항상 0이므로 다음과 같이 줄일 수 있습니다.

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

하나 더 소중한 바이트를 저장합니다.

모두 합치면 문자열의 각 문자를 반복하여 12 월 31 일의 요일과 같은지 확인합니다. 일치하는 인덱스를 유지하고 결국이 배열을 반환합니다. 이것이 내장 된 연도 계산 방법입니다.


으 아아아 ... 내 두뇌, 당신은 alla에서 윤년을 설명 했습니까?
매직 문어 Urn

2
@carusocomputing 그게 다야 !(y%4)*y%100|!(y%400). 400으로 나눌 수없는 경우를 제외하고 매년 4로 나눌 수있는 것을 제외하고 100으로 나눌 수있는 해를 제외하고
mbomb007

바라건대 y+(y>>2)+(z=y/25>>2)+(z>>2)여전히 바이트를 절약합니다.
Neil

@Neil 감사합니다, 그러나 더 나은 방법을 찾았습니다 :-)
ETHproductions

좋은; 를 사용하여 배치 포트에 6 바이트를 저장했습니다 (y*5/4-(y/100)*3/4).
Neil

11

JavaScript (Firefox 30-57), 67 65 64 63 61 바이트

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

저장된 2 개 4 @ETHproductions 6 바이트 감사합니다. 월을 역순으로 출력하여 다른 바이트를 저장했습니다.


나는 당신이없이 날개를 .keys()y=>[for(_ of(m=0,Array(12)))if(new Date(y+400,++m).getDay()==2)m]
쳐서

@ETHproductions 순서를 반대로하여 추가 바이트를 절약 할 수 있습니다!
Neil

역순은 괜찮습니다. 출력 형식을 지정하는 것은이 도전에서 흥미로운 부분이 아닙니다.
AdmBorkBork

사양에서 제거 된 Array Comprehensions에 대한 정책은 무엇입니까?
MayorMonty

Array(12)완전히 건너 뛰어 다른 2 바이트를 절약 할 수 있습니다 . y=>[for(_ of(m=0,1e11+""))if(new Date(y+400,++m).getDay()==2)m]
ETHproductions

8

MySQL은, (183) 134 (129) 106 바이트

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원하는 연도로 교체하십시오 . 운영.

개정 2 : help_topics임시 테이블을 작성하는 대신 기본 설치에서 테이블을 사용했습니다 .

개정 3- : aross의 트릭을 채택 하고에 대한 인용도 생략 할 수 있음을 알았습니다 "-1".
그러나 -1MySQL에서는 필수입니다. 전체 날짜가 필요합니다.

Rev.4 : (-6)과 m BETWEEN 1 AND 12같이 제한 을 수행 할 수 m>0 AND m<13있지만 전혀 필요하지는 않습니다. 유효하지 않은 값은 무시됩니다. 경고는 계산되지만 나열되지는 않습니다.


정말 테이블 shema mysql이 필요하십니까? mariadb.com/kb/en/mariadb/mysqlhelp_topic-table
Jörg Hülsermann

@ JörgHülsermann 나는 당신의 요점을 얻지 못합니다.
Titus

FROM help_topic없이 해야합니까 mysql.? 나는 그것을 시도하지 않았다
Jörg Hülsermann

@ JörgHülsermann 앞에 추가 USE mysql;한 경우에만 올바른 데이터베이스를 선택해야합니다.
Titus

5

펄, 64 바이트

에 +1 포함 -n

STDIN에 입력하십시오 :

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

배치, 160 152 바이트

@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%%

@ETHproduction의 답변 포트입니다. 197 189 바이트의 월 약어로 :

@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 34 33 바이트

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

@ Adám의 도움으로 15 바이트를 절약했습니다 .

내장 달력을 사용하여 월을 나타내는 문자열 배열을 생성 한 다음 각 문자열을 구문 분석하여 마지막 월요일이 마지막 달인지 여부를 판별합니다. 매월 월 번호로 출력합니다. 그건,Jan = 0 , Feb = 1, ..., Dec = 11.

의 출력 calendar

   _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               │                     │                     │
└─────────────────────┴─────────────────────┴─────────────────────┘

용법

   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

설명

[: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

잠깐, 달력은 실제로 ASCII 아트를 출력합니까?
Destructible Lemon

@DestructibleWatermelon 정확한하기 위해,의 출력 형식은 calendar각 상자는 2 차원 문자 배열을 포함 12 개 상자의 배열입니다
마일

나는 J에서 "각"을 수행하는 방법조차 모르지만, 이것은 이미 훨씬 짧습니다. I.7=;#&.>".&.>,&.>_2{.&.>calendar 2016모든 "열린"을 결합하면 꽤 짧게 얻을 수 있습니다.
Adám

아담 감사 @, 그것은 더 나은 방법을 사용하지만 내가 것 아직도 도움 그러나 생각 J.에서 동사 아니다
마일

나의 의도는 단지 영감을주기위한 것이었다. 나는 그것이 동사가 아니라는 것을 안다.
Adám

4

Mathematica, 62 57 바이트

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

익명의 기능. 숫자를 입력으로 사용하고 단일 요소 숫자 목록을 출력으로 반환합니다. 나는 그것이 더 이상 어떻게 작동하는지 솔직히 확신하지 못한다.


4

Perl + cal, 46 바이트

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

예:

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

2







10


$

1
엄밀히 말하면, 이것은 단지 perl :-p가 아니라 perl + cal입니다. 예를 들어, 내 Windows 컴퓨터에는 perl이 있지만 작동하지 않습니다.
철학

페어 포인트, 이것과 내 bash 시도를 업데이트했습니다.
steve

4

자바 7186182 172 바이트

4 바이트를 절약 해 준 kevin에게
감사합니다 10 바이트를 절약 해 준 @cliffroot에게 감사드립니다

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;}

언 골프

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;
     }

이 버전은 @cliffroot에서 제공합니다 ( 168 바이트 ).

 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;   }
    }

출력 샘플

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

1
내 대답을 쓴 후 나는 모든 것을 스스로 계산하는 것이 더 짧다는 것을 알았습니다 .. :) Btw, 당신은 골프 n%4==0를 할 수 있습니다 n%4<1. n%400==0n%400<1int c=...;int[]b=...,a=...int c=...,b[]=...,a[]=....
Kevin Cruijssen

1
b다음과 같이 부분 a에서 정의 할 수 있습니다 int.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;}적은 바이트 절약
cliffroot

1
또한 변경할 수 있습니다 bb[]={3,(n%4<1&n%100>0)|n%400<1?1:0,3,2,3,2,3,3,2,3,2,3}i+30i+282 개 바이트
cliffroot

1
그리고 또 다른 3 바이트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;}
cliffroot

3

파이썬 2, 100 바이트

어. 날짜가있는 수학은 내가 원하는만큼 간단하지 않습니다.

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]

온라인으로 사용해보십시오

같은 길이 :

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]

나는 이것으로 파이썬을 시도조차하지 않았다. 좋은 노력.
ElPedro

3

MATL , 21 바이트

12:"G@QhO6(YO9XO77=?@

월은 숫자로 표시됩니다.

온라인으로 사용해보십시오! 또는 모든 테스트 사례를 확인하십시오 .

설명

날짜 변환 내장 함수를 사용합니다. 주어진 연도에 대해 월요일의 마지막 날이 어느 달인지 테스트합니다.

대신 명시 적으로 달의 마지막 날 지정의 k(28, 29, 30 또는 31 일 수 있음), 우리는 지정 0달 번째 일 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 유틸리티, 56 바이트

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

date버전 8.25 가 필요한 것으로 보입니다. Ideone의 8.23 ​​버전은 잘리지 않습니다.


3

엑셀, 537 바이트

엑셀!

A1에서 입력 연도를받습니다. 16 진수 월 목록을 반환합니다. 1 = 1 월 C = 12 월 매월 한 자리 숫자이므로 구분 기호가 필요하지 않습니다.

=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","")

예 : A1에 2016이 포함되어 있습니다. B1에 위의 수식이 포함되어 있으며 2A2 월과 10 월을 의미하는 로 표시됩니다 .


3

PHP 109 180 159 바이트

for($z=$argv[1];$m++<12;)if(date(N,strtotime(sprintf("%04d-$m-",$z).cal_days_in_month(0,$m,$z)))<2)echo"$m,";
  • 제공된 연도를 모두 출력하지는 않습니다 (항상 질문을 읽으십시오).
  • 무시 된 통지 (Titus에게 감사)
  • 변경 whilefor지금 한 해의로 (다시, 감사 딛)

올드 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까지 모든 연도를 지원하며 한 PC에서 알지 못했던 정의되지 않은 var 경고를 제거했습니다. 예, 이전 버전보다 길지만 더 강력합니다.

올드 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 또는 32 비트 시스템에서 실행하면 2038 버그가 두려워하지만 64 비트 Linux 시스템에서는 문제가 없습니다.

date("t"...주어진 달의 마지막 날짜를 나타내는 것을 사용하려고 시도 했지만 결과는이 스레드에서 언급 한 것과 일치하지 않았습니다.


2
-2 : "$ z"는 따옴표가 필요하지 않음 -7 : 통지를 무시합니다 (기본 설정으로 인쇄되지 않음 : 초기화하지 않음 $z, 따옴표 없음 N) -1 : -43for 대신 : 연도를 반복하는 대신 요청에 따라 입력을받습니다. -3 : -16 대신 : 직접 출력 : 후행 쉼표가없는 경우 +9 :while joinimplodefor($z=$argv[1];$m++<12;)if(date(N,strtotime(sprintf("%04d-$m-",$z).cal_days_in_month(0,$m,$z)))<2)echo"$m,";echo$o=$o?",$m":$m;
Titus

아, 질문을 잘못 읽었습니다! 이 모든 년 동안 알았는데 .. 죄송합니다 : 다른 제안 B 감사가 아니라, 그들에 얻을 것이다
CT14.IT

3

PHP, 92 바이트

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

1 년 1 일 후 1 개월에 12 회 확인 화요일입니다. 그렇다면 그 달의 마지막 날 전날이 월요일입니다.


인쇄 대신 에코를 사용
Octopus

1
@Octopus는 삼항 연산자 안에 있지 않음
Jörg Hülsermann

3

C, 214 바이트

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);}}

엮다

gcc -std=c99 -o foo foo.c

언 골프

관련 전문가에게 크레딧을 제공합니다.

C 프로그램의 Michael KeithTom Craver주어진 날짜의 요일을 찾습니다 .

Q & ACollin Biedenkapp : 매월 마지막 날이 무엇인지 어떻게 알 수 있습니까?

/* 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
당신 if이 다른 방향으로 뒤집어서 else돌아와서 31==체인을 제거하면 어떻게 될까요?
AdmBorkBork

1
if (x == 1) {z part} else if (x == 3 || x == 5 || x == 8 || x == 10) return 30 else 31을 반환
RosLuP

1
어떻습니까 : 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 : return () 포인트 덕분에 100 바이트가 절약되었습니다.
steve

1
u (y, m) {return m-1? 30 + ((2773 >> m) & 1) : 28+ (y % 4 == 0 && y % 100 || y % 400 == 0);} 여기서 y는 연도이고 m은 월
RosLuP

3

C, 119 바이트

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);}

여기에는 윤년에 대한 매월 마지막 날의 요일 오프셋이 포함 된 표가 사용되며 기수 7을 사용하여 부호있는 32 비트 단어로 인코딩됩니다. 윤년이 아닌 경우 1을 오프셋에 1로 추가합니다. (당신이 볼 수 있듯이 y&3||y%25<1&&y&15윤일없이 년을 확인하는 데 사용됩니다). 그런 다음 매월 반복하여 마지막 날이 월요일인지 확인합니다. 실제로 매우 간단하고 추한 해킹이나 트릭이 없습니다. 여기에 약간 골퍼가 없습니다 :

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
  );
}

이것을 다시 방문하여 몇 문자를 저장하는 함수로 다시 작성할 수 있습니다. 은 printf또한 너무 많은 공간을 차지 ...


printf ( "% d,", m)는 1 또는 2, 3으로 무언가를 인쇄하므로 항상 하나의 ','가 있습니다. 더 많이 ... 나는 공백 만 사용하는 것을 선호합니다
RosLuP

실제로 출력에서 ​​공백도 선호하지만 일반적으로 골프 C 솔루션을 작성하여 공백이 필요하지 않으므로 문자 수를 확인하려고 할 때 반 골프 버전에서 모든 공백을 뺄 수 있습니다. .
Fors

3

PHP, 96 95 76 71 69 64 61 바이트

참고 : 연도 번호는과 같이 4 개의 문자로 채워 져야합니다 0070.

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

다음과 같이 실행하십시오.

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

설명

-1에서 -12까지 반복합니다. mktime, day 0(이전 달의 마지막 날) 및 month를 사용하여 날짜를 작성하십시오 2..13. 날짜를 day number 로 형식화하고 결과가 1이면 현재 숫자를 인쇄하십시오. 음수 부호 -가 구분 기호 로 사용됩니다.

밀레니엄 버그가 다시 발생합니다!

이 버전에서는 범위 0..100가로 해석됩니다 1970..2069. 0..69주마다 400 년 (146097 일, 정확히 20871 주)마다 반복되는 패턴이 있기 때문에 범위에 문제가 없지만 범위 70..99에 대해서는 1900이 연도에 추가되어 400의 배수가 아닙니다. 그 문제는 10k 범위에서 30 년 숫자에 대해 가장 간단한 방법은 연도 숫자에 400을 더하여 2 자리 해석 ( +4 바이트 ) 을 방지하는 것입니다 .

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

조정

  • !~-$i비교하기 위해 사용하여 바이트를 저장했습니다 ( 이진 부정 , 논리적 부정 , 모든 다른 수는 ), 괄호가 필요하지 않습니다$i1-10truefalse
  • last day ofYYYY-m표기법을 사용하여 날짜를 작성 하여 19 바이트 절약
  • 사용하여 5 바이트를 저장 date하고 strtotime대신date_create
  • 음수 부호를 출력 구분 기호 (음수는 존재하지 않음) YYYY-m로 사용하고 날짜 의 일부를 음수로 사용하여 음수를 세어 2 바이트를 절약했습니다.
  • mktime대신 5 바이트를 사용하여 저장했습니다 strtotime. 일을 사용하도록 되돌 렸습니다 0( mktime13 개월도 지원하므로 0-13== 31-12)
  • 사용 가능 -R하도록 $argn사용 하여 3 바이트 절약

mktime연도를 채울 필요가 없습니까?
Titus

@Titus, 예리합니다. 그럼 난 그냥 알아 낸 mktime것입니다 직관적 인수는 다음과 같이 촬영하고 있기 때문에, INT의. 그것은 당신이 연도를 채울 수 없다는 것을 의미합니다 ... 그래서 범위의 모든 0..100것은로 해석됩니다 1970..2070. 0..70400 년에 정확한 주 수가 있으므로 (400 년마다 달력이 패턴을 반복하므로) 70..991900 (400의 배수가 아님)을 추가 하기 때문에 범위에 문제가 없습니다 . 따라서 새로운 버전. 버그가 있습니다.
aross

$argv[1]+400줄리안과 그레고리력의 주중이 다르지 않으면 지금 내가 볼 수있는 유일한 해결책은 ...입니다.
Titus

@Titus, 그렇습니다. 규칙에 따르면 Gregorian cal 사용

3

엑셀, 428 97 96 바이트

A1에 입력하십시오. 분리되지 않은 16 진수 값을 출력합니다 (1 월 = 0, 12 월 = 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 년 이전 날짜를 처리 할 수 ​​있도록 10 바이트 ( "+2000")가 추가되었습니다.

@ Engineer Toast 덕분에 11 바이트가 절약되었습니다 .


@ Adám 의 솔루션 에서 크게 빌린 첫 번째 시도 (428 바이트) .

=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","")

1900 년 이전에는 어떻게 작동합니까? 테스트 사례 297 -> May6이 공식과 함께 반환 됩니다. 4가 아니어야합니까? 9 월 대신 1776제공 7A합니다 8.
엔지니어 토스트

그래도 작동한다면 Date(A1,3,0)대신 대신 사용할 수 있습니다EOMONTH(DATE(A1,2,1),0)
Engineer Toast

2

Bash + cal, 58 바이트

$ 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 cal(예 : OSX)에서는 작동하지만 GNU에서 후행 공백을주의하십시오 cal.
Digital Trauma

2

파이썬 2, 94 바이트

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

반복

명명되지 않은 함수는 정수 연도를 사용하여 월 숫자 목록을 출력합니다 [1-12].

또한 성공하지 않고 산술로 바이트 수를 이길려고했습니다 (110 바이트). :

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)

월 [Jan-Dec]이 월요일에 끝나는 지 여부를 나타내는 부울 값 목록을 리턴하는 이름없는 함수


2

자바 7, 200 249 바이트

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에서는 GregorianCalendarGregorian과 Julian 달력이 혼합되어 있습니다. 이 때문에 년1 잘못된 결과가 발생했습니다. 변경 Calendar c=Calendar.getInstance();GregorianCalendar c=new GregorianCalendar();c.setGregorianChange(new Date(1L<<63));단지 태양력의 사용을 강제로 수정이. 이것을 설명해 주신 stackoverflow.com의 @JonSkeet 에게 감사드립니다 .

언 골프 및 테스트 코드 :

여기에서 시도하십시오.

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));
  }
}

산출:

4 12
5 
9 
1 7 
2 10 
1 2 10 

2

C # 6 C를 # 171 167 135 바이트

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 덕분에 -32 바이트

월을 숫자로 인쇄하십시오. 공간이 구분 된; 후행 공간으로. 이제이 답변은 이전 버전의 C #에서도 작동합니다.


이전, 167 바이트

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 덕분에 -4 바이트

출력 월은 반환 문자열의 숫자이며 쉼표로 구분됩니다.

언 골프

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 예. 명시 적 캐스트가 필요합니다. 답변이 업데이트 됨
링크 Ng

LINQ는 재미 있지만, 이것은 126 바이트입니다 : 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);}}}) 또한,이 캐스팅 짧은 것 DayOfWeekint가 캐스팅하는 것 이상 int으로DayOfWeek
카데

@ Shebang 감사합니다. 나는 정말로 한 줄짜리 linq에서 골프를해서는 안됩니다 --- Jon Skeet 만 그렇게 할 수 있습니다. 내일 업데이트 할 시간이 있는지 확인하십시오. 피곤하다.
링크 Ng

Action<int>바이트를 절약하기 위해 이것을 변환 할 수 있습니다
TheLethalCoder

2

루비, 54 + 6 = 60 바이트

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

-rdate표준 라이브러리에서 Date 클래스를 가져 오려면 명령 행에 6 바이트를 사용하십시오.

설명 : Ruby stdlib의 훌륭한 Date클래스 덕분에 매우 간단 합니다. 뿐만 아니라이 같은 방법이 있습니까 monday?, tuesday?등, 생성자는 의미 '이전 필드로 표시되는 기간의 끝에서이 필드를 거꾸로 계산'을 해 과거의 어떤 필드에 음수를 취할 것입니다. $*는 축약 형 ARGV이므로 $*[0]첫 번째 명령 행 인수를 얻는 빠른 방법입니다.


2

PHP, 84 바이트

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

내 첫 번째 코드 골프. 이것은이 질문에서 지금까지 가장 짧은 PHP입니다.

편집 : 1 년 동안 작동하지 않는 것 같습니다. 나는 이유를 알아야하지만 지금 당장 가야합니다.


1
"PPCG에 오신 것을 환영합니다!" 하지만 당신은 내가 가진 것보다 더 오랫동안 여기에 등록되었습니다! : D 니스 첫 골프.
AdmBorkBork

오류는 1 <13 년에 1-13-1 및 1-14-1을 생성하면 충분하다는 것입니다. 당신이이 문제를 해결하면 순간에 unnessary 브래킷을 제거하고 삼항 연산자를 사용하는 방법에 대해 생각할 수있는
요 르그 Hülsermann을

이 문제를 해결해야합니다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 바이트

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

매월 마지막 날의 순서는 다음과 seq(as.Date(paste0(x,-2,-1)),,'m',12)-1같습니다.

  • paste0-2와 -1을 문자로 강제 변환합니다. x가 예를 들어 2016 인 경우 paste0(x,-2,-1)제공 "2016-2-1"은을 통해 2016 년 2 월 1 일로 변환합니다 as.Date.

  • seqPOSIXct인가 또는 날짜 오브젝트가 seq(from, to , by, length.out)여기 to특정되지 않고, by로 주어진다 'm'일치하는 'month'부분과 일치 덕분 및 length.out코스 (12)이다.

  • 결과 시퀀스는 해당 연도의 2 월부터 시작하여 12 개월의 첫날입니다. -1그러면 해당 연도의 1 월부터 시작하여 12 개월의 마지막 날을 알려줍니다.

테스트 사례 :

> 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

이전 버전의 95 바이트로 숫자 대신 월 이름을 출력합니다.

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

이 답변은 훌륭합니다. 나는 -objects에 seq대한 방법을 Date알지 못했고 이것은 삭제 된 답변에서 as.Date수년을 처리하지 못하는 문제를 해결합니다 10000.
Billywob

@Billywob 예 seq.Dateseq.POSIXt매우 인상적이다 : 그들은 심지어 같은 명령을 처리 할 수 있습니다 seq(time1, time2, by="10 min")또는 seq(date1, date2, by="quarter"). 시계열을 그릴 때 매우 유용합니다.
plannapus

2

apt, 24 바이트

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

온라인으로 테스트하십시오! false월요일로 끝나지 않는 달 대신숫자 배열을 출력합니다.

인터프리터 Ð에 함수 body에서 사용할 수없는 버그가있었습니다 £. 버그 수정 및 기타 기능 추가 후 현재 커밋에서 18 바이트입니다.

Do1@Ð400+UX e ¥2©X

1

자바, 143129 바이트

이것은 Java 8의 새로운 시간 API를 사용합니다.

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

산출

각 줄의 끝에 여분의 공간이 있습니다.

4 12 
5 
9 
1 7 
2 10 
1 2 10 

언 골프 및 테스트

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));
    }
}

면도

  1. 143 ~ 129 바이트 : DayOfWeek::ordinal열거 형 상수 대신 숫자 상수와 비교하는 데 사용 합니다.
    정확한 해결책이 아니라면 일반적인 아이디어에 대해 @TimmyD에게 감사드립니다! ;-)

슬프게도 @TimmyD, 그것은 열거 형입니다. 그러나 getValue()몇 바이트를 절약 할 수있는 방법 이 있습니다 .
Celos

@Celos ordinal()getValue()사용하지 않는 것이 좋습니다만, 1 바이트를 더 절약 합니다.
Olivier Grégoire

예, 좋은 생각입니다. 먼저 새로 고침하지 않고 댓글을 올렸으므로 답장과 수정 사항이 보이지 않습니다.
Celos

1

GNU awk, 80 바이트

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

$ gawk '{for(;m<13;a=mktime($0" "++m" 1 9 0 0")){if(strftime("%w",a-8e4)~1){print m-1}}}' <<<2016
2
10
$
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.