주어진 해의 매월 마지막 일요일 찾기


21

140 문자 안에 알려진 F # 솔루션Rosetta Code 문제입니다.

stdout 또는 입력 연도의 문자열 변수에 필요한 결과 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 년 :

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

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

날짜가 대부분의 언어에서 어색함을 나타 내기 때문에 가능합니다. 날짜 라이브러리를 허용하는 것 이상으로 볼 수 있기를 바랍니다! 그러나 기본 언어 외부의 경우 게시물 이름으로 선언하십시오 (예 : C # + Jon Skeet 's NodaTime).

설명 :

  • 연도 범위 1900 ~ 3015
  • 그레고리 언 달력
  • 그렇지 않은 경우 영국 / 런던에 대한 기존의 모든 것이 중요합니다.
  • 커맨드 라인 스위치 또는 stdin을 사용하는 프로그램은 정상이며 결과는 stdout입니다.
  • 연도 값을 가져 와서 문자열을 반환하는 함수도 좋습니다.

표준 허점은 제외되었습니다 . APL, J, K 솔루션을 기대하고 새로운 날짜 라이브러리를 봅니다.


SP3000 @ - 1752은 :-) 특히 어색 수 있습니다
비위 ossifrage

@ MartinBüttner : 날짜 라이브러리를 사용하고 사람들이 언어로 사용하는 사람들을 선언하도록 질문을 편집했습니다.
Phil H

1
유효한 입력 기간과 그레고리 안 채택에 대한 고려 사항을 지정해야합니다. (연도 범위에 1930 년 이전이 포함 된 경우 로케일에 관계없이 그레고리력을 전체 범위에 사용해야하거나 출력이 로케일에 따라 다를 수 있거나 마감 날짜를 지정해야합니다. 율리우스 력을 사용하여 3 년 동안 테스트 케이스를 사용해야합니다.
Peter Taylor

1
@squeamishossifrage : 사양을 설정하기위한 연구 프로젝트를 피하고 싶기 때문에 1900 년과 Gregorian으로 제한했습니다.
Phil H

1
@ Adám : 답장을 기다리게해서 죄송합니다. :) 그렇습니다.
Phil H

답변:


1

Dyalog APL 에서 dfns , 19 바이트

안하는 것보다 늦게하는 것이 낫다!

연도에 대한 프롬프트는 날짜 목록을 yyyy md 형식으로 반환 합니다.

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

숫자를 입력하라는 프롬프트를 표시하고

{... 익명 함수 (아래에 있음)가 각각에 적용됨

⍳12 1에서 12까지의 숫자 (개월)

위의 익명 기능은 다음과 같습니다.

⍺⍵, 왼쪽 및 오른쪽 인수 앞에 (예 : 연도 및 월)

2↑ 첫 두 문자

⊢⌿ 최하단

cal 달력

⍺⍵ 왼쪽 인수 및 오른쪽 인수 (연도 및 월)

TryAPL 온라인 :

  1. 가져 오기 및 해당 종속성을 보려면 여기클릭후이 페이지로 돌아갑니다 cal.

  2. 테스트 케이스를 실행 하려면 여기클릭하십시오 .


아주 좋아요 날짜가 무엇을 의미하는지 이해하는 APL 라이브러리를 원했지만 cal은 합리적입니다!
Phil H

@PhilH 날짜요일 ?
Adám

1
@PhilH MiServer 의 Dates 네임 스페이스도 있습니다.
Adám

1
@PhilH And Dyalog APL의 이진 기본 요소 + - < = 닷넷 날짜 객체와 작업 .
Adám

7

루비, 91 + 6 = 97

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

꽤 잘 작동합니다. select(&:sunday?)예쁘고 놀랍게도 *' '모든 서식 자체가 수행됩니다.


좋은 트릭! chunk대신을 사용하여 세 개의 문자를 더 저장할 수 있습니다 group_by.
Cristian Lupascu

그래서 할 수 있습니다.
histocrat

6

배쉬 4.x + ncal, 57

공백 대신 줄 바꾸기 구분 기호가 정상 -n이면 echo명령문 에서 스위치와 후행 공백을 제거 할 수 있습니다 . 그리고 나는 그것이 여전히 shebang없이 작동 할 것이라고 생각합니다. 그래서 나는 그것을 제거했습니다.

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

원본 스크립트 (73 바이트) :

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

용법:

$ 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
$

참고 : 4.0 이전의 Bash 버전은 월의 선행 0을 생략합니다. 로 변경 {01..12}하여 5자를 추가하면이 문제를 해결할 수 있습니다 `seq -w 1 12)`. 또한 tail -c-3일부 시스템에서 출력이ncal 후행 공백 포함 있지만 그 사실을 알지 못합니다.


1
차이점은 Bash 버전뿐만 아니라 Darwin과 실제로 관련이 있습니까? Bash 4.0에 추가되었습니다 (나중에 버그가 있었지만). 어쨌든, `…`좋은 습관 대신을 사용하여 1 문자를 절약 할 수 있습니다 $(…).
manatwork

아. 다윈은 버전 3.2.53을 사용하고 있다고 말했다. 데비안은 4.1.5를 사용하고 있습니다.
squeamish ossifrage

@manatwork PS 방금 틱에 대한 귀하의 의견을 발견했습니다. 잘 잡아라, 고마워!
squeamish ossifrage

#!/bin/bash골프 목적으로 계산할 필요는 없다고 생각합니다 .
Digital Trauma

@DigitalTrauma 좋아요. 공백 대신 줄 바꿈을 사용할 수있는 것처럼 보입니다. 57 아래로 :-) 지금 바이트
점잔 빼는 ossifrage에게

6

IBM DFSORT, 11 71, 72 또는 80 자의 3 줄

 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) 

열 출력 형식의 두 가지 대답은 시간의 시험을 견뎌냈습니다. OUTFIL REPEAT =에서 현재 레코드를 여러 번 복사하는 "루프"를 제공합니다.

다음 해에 12 번째 레코드를 다루는 무조건적인 방법으로 해결할 수 없으므로 더 길어 보이지만 더 짧은 값을 얻는 다른 기술 IFTHEN=(WHEN= , 두 번 및 기타 항목을 다른 기술. 그네에 대한 이익 (첫 번째 방법은 가장 간단한 방법입니다)은 원형 교차로 (특히 구문 요구 사항)를 크게 잃습니다.

이 함수는 내장 함수 (DFSORT의 모든 함수가 내장)를 사용하여 해당 월의 마지막 날을 찾습니다. 그런 다음 하루 (함수)를 추가하여 다음 달의 첫 달에 도달하고 PREVDSUN 함수를 사용하여 이전 일요일 (이전 달과 같이 항상 이전 달의 마지막 일요일이 됨)을 가져옵니다.

연도 (입력)를 유효한 날짜로 전환 할 때 두 자리 시퀀스 번호가 해당 월에 사용되며 시작점은 유효 기간만큼 중요하지 않으므로 해당 값도 해당 날짜에 복사됩니다. 매월 마지막 날 이후 : 5,2보다 짧습니다 C'01'.

세부 사항은 다음과 같습니다.

옵션 복사-입력 파일을 출력으로 복사

OUTFIL-선택 및 서식이 다른 여러 출력 파일을 허용하여 형식이 지정된 보고서를 생성합니다. 을 (를) 사용 INREC하므로 짧을수록 선호됩니다 REPEAT=.

REPEAT = 12-각 레코드의 12 개 사본을 생성합니다. 이 예에서는 SEQNUM으로 인해 (이전 버전과 달리) 하나의 입력 레코드 만있을 수 있습니다.

5 :-레코드의 5 열에서 시작합니다.

SEQNUM, 2, ZD-시퀀스 번호는 기본적으로 1 자리, 2 자리 숫자, "zoned decimal"(서명되지 않은 경우 문자와 동일)로 시작합니다.

1,8-길이 8의 바이트 1을 현재 위치 (9)에 복사합니다. Y4T가 8을 볼 필요가 있기 때문에 그렇지 않으면 다른 날짜 형식이 사용됩니다.

Y4T-ccyymmdd 형식 날짜 (8 바로 앞에 있음).

LASTDAYM-마지막 날 (주, 분기 및 연도 가능)

TOJUL =-날짜 함수에 대한 출력 날짜 변환 출력 (TOJUL은 TOGREG보다 한 문자 미만 임)

9,7-이제 길이가 7이므로 Y4T는 CCYYDDD가됩니다.

ADDDAYS-다음 달 / 연도에 들어가면 자동으로 조정되는 며칠 추가 (ADDMONS 및 ADDYEARS 일 수 있음)

PREVDSUN- "-"구분 기호를 사용하여 올바른 출력 형식을 얻기 위해 이전 일요일이있는 TOGREG에 율리우스 날짜가 표시됩니다 (구분 기호로 원하는 항목이 될 수 있음)

12X-공백을 제거하여 공백을 제거했습니다.

위의 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-23
2014-12-28

SORT에게해야 할 일을 알려주는 것이 필요합니다. 기본값은 없습니다. OPTION COPY가장 짧고 SORT FIELDS=COPY같지만 더 깁니다.

이번에 OUTFIL는 REPEAT를 사용하기 위해 수행 한 작업 자체 . 작업 코드는 160 (2 * 80), 144 (2 * 72), 140 (72 + 69) 또는 138 (70 + 68) 중 하나입니다 (선행 공백, 강제 연속 및 후행 공백 제외).

수신자가 무엇을하고 있는지 알아야한다는 점을 감안할 때 DFSORT 코드는 1900 년부터 1 년 동안 매월 마지막 일요일을 나열한다고 말할 수 있다고 생각합니다. ) 999까지

특히 적절한 내장 함수가있는 경우 코드가 너무 긴 이유는 무엇입니까?

필드 정의는 일시적입니다. 필드는 즉시 사용할 수 있도록 데이터 내의 특정 위치 (레코드)로만 정의됩니다. 달리 말하면, 필드는 그와 같이 정의되지 않지만 각 용도와 용도로만 정의됩니다. 날짜 함수는 소스에 사용되는 날짜 형식 중 많은 형식을 알아야하며 출력은 날짜 형식이어야하므로이를 지정해야합니다.

이제 율리우스 데이트를 했으니 .. 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) 

일부 필요 JCL

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

입력 파일 (JCL의 또 다른 행과 세 개의 인스 트림 데이터 항목) :

//SORTIN DD *
2014 
1900 
2000 

생산 :

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

실제로 9999 년까지 작동합니다.

DFSORT는 IBM의 메인 프레임 정렬 제품입니다. 데이터는 조작 할 수 있지만 정렬이 중요하고 정렬이 크고 오래 실행되므로 DFSORT 제어 카드에는 루프 구성이 없으므로 SORT를 루프에 넣을 수 없습니다. 골프와 같은 작업에 약간 시간이 오래 걸립니다.

답을 게시해야하는 이유는 DFSORT에 PREVDday기능 이 있기 때문 입니다. 그래서 지난 일요일 한 달에 쉽습니다. 다음 달의 첫째 날부터 일요일 (PREVDSUN)입니다.

하나의 "오퍼랜드 (operand)"(오버레이) 내에서하는 것도 재미있었습니다 sprintf.

여기에 골퍼가 없습니다 :

 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) 

상당히 남용하지는 않지만,이 모든 것을 하나의 오버레이에 넣으려고 시도하는 것은 일반적이지 않으며, 모든 것이 하나의 오버레이로 들어가는 데 필요한 겉보기에 불필요한 것들이 있습니다. 골프를 할 여지가 있지만 최대 한 줄만 제거하기 때문에 유혹을받지 않습니다.

INREC는 각 레코드마다 처리됩니다.

OVERLAY를 사용하면 기존 레코드의 내용을 변경할 수 있습니다. 프로세스에서 레코드 길이보다 길어도 문제가되지 않습니다.

1,4는 다가오는 해입니다. 여기에 리터럴 0201이 추가 된 후 연속 1,8은 11 번 반복하여 96 바이트의 긴 척을 제공합니다.

확장 된 현재 레코드의 12 년째에 1이 추가되고 그 달은 1 (1 월)이됩니다.

나머지 10 개월은 3에서 11로 변경됩니다.

그런 다음이 유형의 것의 12 가지가 (오버레이로 인해) 역순으로 있습니다.

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

n :은 레코드의 열 번호입니다. X는 공백을 삽입합니다. 89,8은 해당 열 / 길이에서 데이터를 가져오고 Y4T는이를 CCYYMMDD 날짜로 처리하고, PREVDSUM은 이전 일요일을 처리하고 TOGREG = Y4T (-)는 그 데이터를 Gregorian CCYY-MM-DD 날짜로 출력합니다.

오버레이의 특정 부분의 소스와 대상이 파괴적으로 겹치면 쓰레기가 생길 수 있기 때문에 최종적으로 11:X,18,120,6X)재정렬되어 약간의 혼란이 가해집니다.

매뉴얼 및 논문은 http://www-01.ibm.com/support/docview.wss?uid=isg3T7000080 에서 찾을 수 있으며 900+ 페이지 DFSORT 애플리케이션 프로그래밍 안내서가 포함되어 있습니다.

모든 IBM 제품과 마찬가지로 모든 매뉴얼을 무료로 사용할 수 있습니다 (세계에서 매우 적은 수의 사람들 만이 이해하는 척하는 엄청나게 적은 양의 매우 비싼 매뉴얼 제외).

모든 DFSORT 제어 카드는 공백으로 시작해야합니다. 열 72는 연속 용으로 만 사용됩니다 (공백이 아닌 모든 것이 가능하지만 *는 일반적인 것임). 열 72 다음에는 시퀀스 번호 영역이 무시되며 각 레코드를 80 바이트로 만듭니다.

또 다른 해결책이 올 것입니다.


5

배쉬, 63 바이트

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

산출:

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 바이트
Digital Trauma

-vparam to date는 BSD 날짜와 관련이 있습니다. 따라서 이것은 OSX에서 작동하지만 대부분의 Linux에서는 작동하지 않습니다. 아마도 대답에 명시되어 있어야합니다.
Digital Trauma

@DigitalTrauma는 Mac 및 Linux에서 작동합니다.
michael501

4

파이썬 2-189 바이트

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

STDIN을 통해 날짜를 입력하십시오.

할 수있는 훨씬 더 많은 골프. 이 프로그램은 재미를 위해 약간 선외로 진행됩니다.

  • 수입품 없음, 특히 내장 날짜 기능을 사용하지 않음
  • 요일 계산에 Zeller의 합동 을 사용합니다.

노트

  • 1322는 2 월이 아닌 달에 30 일 또는 31 일이 있는지 확인하기위한 매직 조회 테이블 입니다.
  • 아니 zfill 때문에 입력 범위 년 동안 필요하지 않으며, 일 그들은 항상 20 이상의 수있는 바와 같이,

파이썬 2-106 바이트

재미없는 솔루션 :

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.monthrange월이 시작되는 요일 ( w)과 월의 일 수 ( )를 반환합니다 n. 이 솔루션은 캐치 때문에 약간의 직관적이지 않습니다. 반환 된 요일은 일요일이 아닌 월요일 에 0부터 시작합니다 ! 그러나 이것은 n1 기반 이라는 사실에 의해 상쇄됩니다 .


1
매우 바보 같은 Pyth 답변 :$from calendar import monthrange as gt$V12AGH>QhN%"%d-%02d-%d"(QhN-H%+GH7
FryAmTheEggman

3

자바 스크립트 (ES6) 155 145

편집 재귀 만든 경우 고정 시간대 문제가 더 짧아 질 수 없습니다. 아마도.

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(' ')
}

사용할 수 있습니다 new Date(y,0,++i,9). 또한 JS에는 이러한 윤년에 대한 정보가 없으므로 2100 년 동안 윤년이 전혀 없으므로 2100 년 이상은 실패합니다 Feb 29.
Optimizer

@Optimizer JS가 아닙니다 : 2100,2200,2300은 윤년이 아닙니다. 2014 년은 윤년이며 JS는 알고 있습니다. 시간 9를 사용하는 것에 관해서는, 나는 확인할 수 없지만 당신이 예를 들어 멜버른에 있다면 그것은 효과가 없다고 생각합니다 ...
edc65

아 .. 우리가 400 년마다 3 일 동안 떨어지는 것을 몰랐어요. 9에 대해-시간대를 -1000 (하와이)에서 +1100 (멜버른) new Date(2014,0,26,9)으로 변경했으며 일요일 ISO뿐만 아니라 올바른 문자열을 제공 getDay()했습니다 0.
Optimizer

3

자바 스크립트, ES6, 222 219 199 바이트

rosetta 위키에서 JavaScript 답변을 보지 못했습니다.

여기 우리는 간다 :

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(" ")}

S원하는 출력으로 문자열을 반환 하는 함수 를 만듭니다 . 이 기능은 윤년을 관리합니다.

ES6로 인해 최신 Firefox에서만 작동합니다.

팁이 200 바이트로 줄어든 apsiller 덕분에

아래에서 ungolfed 버전을 여기에서 실행할 수있는 스택 스 니펫으로 찾으십시오.

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())))


parseInt 대신 + prompt ()를 사용하여 일부 바이트를 제거 할 수 있습니다.
Jacob

@Jacob이 프롬프트는 바이트 수에 추가되지 않습니다.
Optimizer

OIC. 질문을 읽었어야했는데 ...
Jacob

@apsillers 감사합니다! 문제를 해결하고 팁을 기준으로 많이 줄였습니다.
Optimizer

입력 2100출력 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-02이 잘못되었습니다.
Qwertiy

3

Rebol-120116 80 79 76

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


Ungolfed + 일부 주석 :

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 콘솔의 일요일 계산 예 :

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

잠재적 인 87 : d : 1-1-1 d / 년 : 입력 인쇄 수집 [반복 m 12 [d / 월 : m + 1 유지 d-d / 주중]]
rgchris

@rgchris 감사합니다 Chris. 그것의 다른 7 문자를 면도 할 수있었습니다.
draegtun

좋은!! 나쁘지만 FOR 를 지름길 이라고 생각하지 마십시오 .
rgchris

2

CJam, 122 102 바이트

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

이것은 날짜 라이브러리 형식을 사용하지 않습니다. 아직도 골프를 많이 할 수 있다고 생각합니다.

여기에서 테스트하십시오.


3
CJam의 답변이 코드 골프 도전에서 한 번의 최고 답변이되지 않도록 너무 놀랍습니다. 나는 행복하게 죽을 수 있습니다 .. 오늘은 좋은 날입니다 (확실히 6 바이트로 떨어질 때까지)
Brandon

@Brandon : 그것이 제가 흥미로울 것이라고 생각한 이유였습니다. 정말 쉽지만 지금까지 실망한 놀라운 라이브러리를 기대하고 있습니다.
Phil H

1

R, 128 자

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

줄 바꿈으로 :

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

언 골프

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

편집 : 마지막 일요일 만 인쇄하도록 수정 :)


필요한 출력 형식이 아닙니다. + 이것은 코드 골프입니다
edc65

1

q, 67

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

q에 사용할 수있는 날짜 라이브러리가 없습니까?
Phil H

1

"아, 아니, 다시!"

자바 - 259 246 바이트

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

언 골프 버전 :

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

용법:

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

산출:

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

또 다른 "차기에 대한 Java 응답을 넣어 보자"라는 대답이 있습니다. 오 잘 그러나 적어도 당신이 내 대답 의이 시점에 도달하기를 귀찮게했기 때문에 좀 더 당신을 낳고 내 추론을 설명하려고 노력할 것입니다.

이 메소드 g는 원하는 연도를 수신하고 매월 GregorianCalendar오브젝트를 작성 합니다 (월은 0에서 11 사이 임). 그런 다음 첫 번째 c.set요일을 일요일로 설정하고 두 번째 요일은 공식 문서 에 표시된 것처럼 해당 월 의 마지막 주를 원한다고 선언합니다 . 그 일요일 날 밖으로 인쇄 (우리가이 권리를하고 있다면, 올해는 다음과 같이 인쇄 할 것이다 , 그러나 사용하여 다시 13 자 떨어져 면도를), 달 9 월까지 앞에 0을 추가 포맷하는 (그리고 여기서 월은 0-11로 표시되고 마지막 일요일이 인쇄되므로 값이 증가합니다. 그리고이 절차는 다른 11 개월 동안 반복됩니다.System.out.printlnc.get(c.YEAR)y


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

줄 바꿈

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 년 출력

"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"

필수 출력 형식이 아님
edc65

거기에 고정되어 있습니다. 보다 나은?
대런 브린

0

C # 171

문자열을 반환하는 함수.

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

언 골프

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를 사용하여 :

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

언 골프

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

산출

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

수학-171

익명 함수로 싸서 문자열을 반환

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

최초의 수학 골프. 나는 그것이 상당히 줄어들 수 있다고 생각합니다.


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

더 나빠질 수 있습니다 ^^

내 두 번째이자 마지막 항목 (더 작게 얻을 수 있다고 생각하지 마십시오)

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

루비 76

명령 줄 매개 변수를 사용합니다 ruby sundays.rb 1900. 날짜 라이브러리를 사용합니다.

require'date';puts (1..12).map{|m|d=Date.new($*[0].to_i,m,-1);d-d.wday}*" "
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.