일년에 13 일 금요일이 몇 개입니까?


28

당신의 도전은 일년에 주어진 "금요일 13 일"의 수를 출력하는 프로그램을 작성하는 것입니다.

규칙 및 세부 사항 :

  • 를 통해 STDIN또는 프로그램에 전달 된 인수로 입력 할 수 있습니다 .
  • 결과를로 출력해야합니다 STDOUT.
  • 입력이 유효한 연도이며 그레고리력 이전의 날짜가 아니라고 가정 할 수 있습니다 (이 경우 정의되지 않은 동작이 허용됨).
  • 달력 / 날짜 라이브러리가 허용됩니다.

이것은 이므로 가장 짧은 코드 (바이트)가 이깁니다.

(관련 챌린지 링크)


7
필요한 입력 범위는 무엇입니까? 1800 년 이전에 줄리안에서 율리우스 력에서 그레고리력으로의 전환에 대해 어떤 가정을해야합니까?
— 피터 테일러

@PeterTaylor 나는 그것에 대해 생각하지 않았다. 날짜가 gregorian 이전 인 경우 정의되지 않은 동작을 가질 수 있습니다.
— Cruncher

1
그레고리력을 채택한 최초의 국가는 그레고리의 황소에 따라 1582 년 10 월에 그랬습니다. 예를 들어 그리스 3 월 1 일 1923 년에 도입을위한 나라는 말은 20 세기까지 변경되지 않은 새 달력을 채택
— Jeppe의 Stig 닐슨

@JeppeStigNielsen 나는 달력 등에 대해 잘 모른다. 그들이 그들을 채택했는지 여부는 그레고리력 날짜가 바뀌지 않습니다. 라이브러리는 내가 추측했던 방식으로 날짜를 계산할 수 있어야합니까?
— Cruncher

3
나는 여기서 주제가 아닌 것 같아요. 영미 프로그래머가 작성한 많은 라이브러리는 1752 년 9 월을 달력의 "올바른"변경 시간으로 사용합니다. 대영 제국이 바뀌었을 때였습니다. 새로운 달력은 물론 미국이 설립되었을 때 유지되었습니다. (호기심에 따라 일부 SQL 소프트웨어는 1752 년 9 월 문제에 대처하고 싶지 않기 때문에 최소 연도는 1753입니다.) 그러나 1752 년 9 월을 사용하는 것은 매우 모호합니다. 당신은 맞습니다 그레고리력 날짜는 역사적으로 사용되었는지 여부에 관계없이 동일합니다. 그것은 소위 다발성 그레고리력입니다.
— Jeppe Stig Nielsen

답변:


3

dfns 에서 cal 을 사용하는 APL (Dyalog APL) , 29 바이트

+/{13∊⍎,⍉3↑¯5↑⍉2↓cal⍵}¨⎕,¨⍳12

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

⍳ 12 1부터 12까지의 정수

⎕ ,¨ 숫자를 입력하고 12 개의 숫자 앞에 붙습니다.

{… }¨ 각 쌍에 기능을 적용하십시오…

 cal⍵ 그 해의 달력을 얻다

 2 ↓ 두 행 삭제 (자막 및 요일)

 ⍉ 전치 (행 대신 열의 주소를 지정할 수 있음)

 ¯5 ↑ 마지막 5 개 (금요일과 토요일에 각각 2 자리 + 1 자리)

 3 ↑ 처음 두 자리를 가져갑니다 (금요일에 두 자리 숫자를 더한 공백).

 ⍉ 전치 (그래서 우리는 독서 순서를 얻습니다)

 , 얽힘

 ⍎ APL 표현식으로 실행 (금요일 목록 제공)

 13 ∊ 13 명이 해당 목록의 회원입니까?

+/ 12 개의 부울 합


@Wrzlprmft의 알고리즘을 사용하면 라이브러리없이 53 바이트를 수행 할 수 있습니다.

'21232211321211'⊃⍨14|2 3 ¯1+.×⊢,0≠.=400 100 4∘.|-∘0 1

-∘0 1 0과 1을 빼다

400 100 4 ∘.| 2 년 (분할)의 나눗셈 나머지 테이블을이 숫자로 나눈 값 (아래)

0 ≠.= 내부 "product"는 0이지만 +. × 대신 ≠ 및 =를 사용합니다.

⊢ , 수정되지 않은 논쟁의 해를 앞당기 다

2 3 ¯1 +.× 이 번호의 내부 제품

14 | 14로 나눈 나머지 나눗셈

'21232211321211' ⌷⍨ 이 문자열로 색인


29 자이지만 1 바이트 이상입니까?
— Cruncher

@Cruncher 제목에 설명 링크를 추가했습니다. TIO 링크를 열면 오른쪽에 "29 자, 29 바이트 (SBCS)"가 표시됩니다 (예 : 단일 바이트 문자 세트).
— Adám

글쎄, 나는 이것이 새로운 승자라고 생각한다.이 SE 후에 질문 후에 오랫동안 받아 들여진 대답을 바꾸는 표준 관행입니까?
— Cruncher

@Cruncher 예. 그리고 OP 이후 오랫동안 받아 들여질 배지도 있습니다.
— Adám

12

매스 매 티카 49 46 45 44 42

A와 순수 기능 : 42 개 문자

DayName@{#,m,6}~Table~{m,12}~Count~Friday&

예

DayName@{#,m,6}~Table~{m,12}~Count~Friday&[2013]

2


명명 된 함수 로서 : 44 문자

f=DayName@{#,m,6}~Table~{m,12}~Count~Friday&

예

f[1776]
f[2012]
f[2013]
f[2014]

2
3
2
1


한 글자 더 짧은 :f=DayName@{#,m,6}~Table~{m,12}~Count~Friday&
— Mr.Wizard

@ 미스터 마법사 예. Mathematica가 여러 경우의 삽입 표기법을 구문 분석 할 수 있다는 것이 놀랍습니다.
— DavidC

데이비드 당신이이 결합 된 표기법을 사용하는 것을 보지 못했다는 것이 놀랍 습니다 . : ^) (예 : (1) , (2) )
— Mr.Wizard

8

루비, 49 48 47 46

f=->m{(1..12).count{|i|Time.gm(m,i,6).friday?}}

편집 : Jan 덕분에 일주일 전으로 돌아가고 Time.new에서 Time.gm으로 전환하여 캐릭터를 면도했습니다.

편집 : 조금 더 난독 화하면서 46으로 갈 수 있습니다.

f=->m{(1..12).count{|i|Time.gm(m,i,8).wday<1}}

5
한 문자는 6 일 금요일의 수를 계산하는 경우 저장
— 존 드보락

2
@JanDvorak 영리한!
— histocrat

왜 6? 나는 그것을 얻지 못했습니다.
— NARKOZ

3
6 일이 금요일이면 13 일도 금요일입니다
— TwiNight

8 일이 일요일이면 1 일도 사용되므로을 사용할 수 있습니다 Time.gm(m,i).wday<1. 또한 왜 함수의 이름을 지정하는지 모르겠습니다.
— Lee W

8

파워 쉘, 68 63 58 52 50

팁 주셔서 감사합니다 Iszi.

$n=$args;(1..12|?{!+(date $n-$_).DayOfWeek}).Count

해당 월의 1 일이 일요일이면 13 일이 금요일이라는 사실을 사용합니다.

나는 또한 시도했다 :

(1..12|?{!+(date $args-$_).DayOfWeek}).Count

그러나 $args스크립트 블록 내에서는 동일하지 않습니다 .


1
나는 그 달의 첫날을 사용하는 아이디어를 좋아합니다.
— Cruncher

좋은 트릭이 있습니다. 그러나 @는 불필요합니다.
— Iszi

또 다른 것은, 나는 많은 대본에서 똑같이 유죄입니다. 문제는 입력이 인수에서 나올 수 있음을 지정합니다. 교체 $n로 $args루프에서, 당신은없이 할 수있는 $n=read-host;완전히. 저장 8. 위에서 언급 한대로 @를 제거하면 54로
— 줄어 듭니다.

수정 : 52로 내려갑니다!
— Iszi

두 번째 스크립트가 작동하지 않는 이유를 알아 내려고 노력하고 있습니다. 흥미로운 것은 내가 밖으로 변경할 수 있습니다 $args에 대한 $input따라서 파이프 라인에서 연도를 공급, 그리고 스크립트가 실행되지만 항상 3. 출력
— Iszi

5

R 76 72 57

sum(format(as.Date(paste(scan(),1:12,1,sep="-")),"%w")<1)

쉽게 대체하여 4 다운이를받을 수 "%a %d")=="Fri 13"와 "%w%d)=="513")숫자로 다우을 사용하고 공백을 제거하여.
— chmullig

매우 감사!
— flodel

+1 seq한 달에 한 번만하는 것이 실제로는 더 짧습니다! sum(format(as.Date(paste(scan(),1:12,13,sep="-")),"%w%d")=="513")65 자뿐입니다!
— plannapus

와우 나는 그것이 <문자를 정수로 강요 할 것이라고 추측하지 않았을 것입니다. 좋은 트릭!
— plannapus

@plannapus 다소 일반적입니다. 문자 코드는 모두 숫자이므로 자바조차도 int와 char를 비교할 수 있습니다
— Cruncher

5

파이썬 2.7 90 86

from datetime import*
s=c=0
exec's+=1;c+=date(%d,s,9).weekday()<1;'%input()*12
print c

월요일 9 일에는 링과 같은 고리가 없을 수도 있지만 제대로 작동합니다.

편집합니다 해 통지에 반 date보다 짧은 datetime:)


정말 좋은 해결책!
— leancz

2
다음을 수행하여 문자를 저장할 수 있습니다.from datetime import*
— user80551

좋은! 나는 효과적으로 동일한 것을 끝내었지만 exec를 피했습니다 : f=lambda y:sum([date(y,m,13).weekday()==4 for m in range(1,13)]).... 가져 오기 (86 바이트)와 같은 크기의 솔루션.
— iwaseatenbyagrue

5

라이브러리 또는 내장 날짜 기능을 사용하지 않는 경우 :

골프 스크립트 – 51

~..({4/.25/.4/--@}2*2*\3*+-
14%' [3/=RI[)a%:*.'\=5%

' [3/=RI[)a%:*.' 뿐만 아니라 'feefefgeeffgfe'

파이썬 – 82 79

본질적으로 동일한 알고리즘입니다.

l=lambda y:y/4-y/100+y/400
i=input()
print"21232211321211"[(2*i+3*l(i)-l(i-1))%14]

이 트릭을 사용하면 다음 과 같이 더 골프화 될 수 있습니다.

l=lambda y:y/4-y/100+y/400
i=input()
print 94067430>>(4*i+6*l(i)-2*l(i-1))%28&3

이것은 달력으로, 마지막 날과 그들이 도약하고 있는지에 따라 구별되는 14 개의 다른 연도 만 있다는 사실을 이용합니다. l인수까지의 윤년 수를 계산합니다 (Gregorian 달력이 1 년으로 거꾸로 확장 된 경우). (2*i+3*l(i)-l(i-1))%14는 약식으로 l(i)-l(i-1)+(i+l(i))%7*2, l(i)-l(i-1)인수가 윤년인지 여부를 알려주고 i+l(i)마지막 날 (일반 연도, 윤년 중 2)의 이동을 요약합니다.


이것이 나의 첫 골프 스크립트 골프이기 때문에, 더 골프를 치는 것에 대한 힌트를 주시면 감사하겠습니다.
— Wrzlprmft

나는 실제로 14 년만의 독특한 해가 있다는 사실을 이용하여 그러한 해결책을 생각하고 있었지만, 그것을 능숙하게 만들 수있는 최고의 언어는 확실하지 않았다. 나는 이것이 라이브러리가없는 가장 짧은 대답이라고 생각합니다. 윤년이 4 년마다 균등하다면, 이길 수있을 것입니다
— Cruncher

4

기음 301+ 287

main(int x,char**v){char p[400],*a[]={"abbababbacaacbac","bacabbb","baabbaca","abbb","aabbacaac","abbbbcaac","abbbbaabb"},*b="adcadcadcaebcadcadcafbcadcadcagbcadcadcadc";int c=0,i,y=atoi(v[0]);for(i=0;i<42;i++)strcpy(&p[c],a[b[i]-'a']),c+=strlen(a[b[i]-'a']);printf("%d",p[y%400]-'`');}

가장 짧은 대답은 아니지만 라이브러리를 사용하지 않습니다.


이봐, 당신은 설명없는 골퍼 답변을 제공 할 의향이 있습니까? 나는 당신이 한 일에 관심이 있습니다
— Cruncher

1
@Cruncher, 그레고리오 력은 400 년주기를 따른다는 기준으로 룩업 테이블입니다.
— Peter Taylor

1
더 명확하게 (그리고 더 길게) C # : static char GetNumberOfFriday13s(int year) { const string perpetualCalendar = "1221212213113213122221122131122121221311321312222112213112212122131132131222211221311221212213113213112213113213122221122131122121221311321312222112213112212122131132131222211221311221212213113213122213113213122221122131122121221311321312222112213112212122131132131222211221311221212213113213122221122213122221122131122121221311321312222112213112212122131132131222211221311221212213113213122221122131"; return perpetualCalendar[year % 400];. 부정적인 년 동안 작동하지 않습니다.
— Jeppe Stig Nielsen

귀엽다! 작은 버그로서 v[0]이어야합니다 v[1]. 이것도 약간 골프를 칠 수 있습니다. 을 사용 strcat하고 직접 인쇄 할 문자를 저장하고 문자 a[]상수 대신 숫자 상수를 뺍니다. :)
— user1354557

1
압축도 개선했습니다 : main(int x,char**v){char p[400],*a[]={"1221212213113213","2131222","21122131","1222","112213113","122223113","122221122"},*b="adcadcadcaebcadcadcafbcadcadcagbcadcadcadc";*p=0;for(;*b;b++)strcat(p,a[*b-97]);putchar(p[atoi(v[1])%400]);}(215 자)
— user1354557

4

C ( 151 개 145 137 개 131 개 130 문자)

내장 캘린더 도구를 사용하지 않는 다른 솔루션이 하나 밖에 없다는 것을 알고 놀랐습니다. 다음은 C에서도 (매우 난독 화 된) 수학적 접근 방식입니다.

f(x){return(x+(x+3)/4-(x+99)/100+!!x)%7;}main(int x,char**v){int y=atoi(v[1])%400,a=f(y+1);putchar('1'+((f(y)&3)==1)+(a>2&&a-5));}

(위의 오류없이 GCC에서 컴파일)

대체 솔루션 : C (287-> 215 자)

나는 오히려 Williham Totland의 솔루션 과 그의 압축 사용을 즐겼습니다 . 두 개의 작은 버그를 수정하고 길이를 단축하기 위해 코드를 수정했습니다.

main(int x,char**v){char p[400],*a[]={"1221212213113","213122221122131","12213113","22213113","22221122","2131"},*b="abababafcbababafdbababafebababab";*p=0;for(;*b;b++)strcat(p,a[*b-97]);putchar(p[atoi(v[1])%400]);}


4

bash 47 36

seq -f$1-%g-6 12|date -f-|grep -c ^F

seq기본 시작을 로 사용하여 10자를 저장해 주셔서 감사합니다 @DigitalTrauma 1.

date -f<(printf "%s\n" $1-{1..12}-6)|grep -c ^F

(사용하여 이전 버전 echo때문에 빈 줄의 존재하는 버그 때 <(echo $1-{1..12}-6$'\n')오늘날까지이 기능은 벌금을했다 그래서. 이다 금요일.

보자 :

set -- 2013
seq -f$1-%g-6 1 12|date -f-|grep -c ^F
2

date -f<(printf "%s\n" $1-{1..12}-13)|grep -c ^F
2

이다 로케일 이 일을하지 않으면 따라,시, 당신은 할 수 있습니다

export LANG=C

또는

LANG=C date -f<(printf "%s\n" $1-{1..12}-13)|grep -c ^F

기능으로; +7-> 43

f(){ seq -f$1-%g-6 12|date -f-|grep -c ^F;}

f 2013
2

for i in {2010..2017};do echo $i $(f $i) ;done
2010 1
2011 1
2012 3
2013 2
2014 1
2015 3
2016 1
2017 2

보너스 : +78-> 121

거기에서 내 기능이되면 :

f(){ o=();for t in $(seq -f$1-%g-6 12|date -f- +%a,%b);do [ "${t:0:1}" = "F" ]&&o+=(${t#*,});done;echo ${#o[@]} ${o[@]};}

또는

f(){ o=();
     for t in $(seq -f$1-%g-6 1 12|date -f- +%a,%b);do
         [ "${t:0:1}" = "F" ]&&o+=(${t#*,})
       done
     echo ${#o[@]} ${o[@]}
}

for i in {2010..2017};do echo $i $(f $i) ;done
2010 1 Aug
2011 1 May
2012 3 Jan Apr Jul
2013 2 Sep Dec
2014 1 Jun
2015 3 Feb Mar Nov
2016 1 May
2017 2 Jan Oct

이것은 로케일에 따라 다릅니다.
— Peter Taylor

예, 이것은 기본을 기반으로 C합니다. 그러나 버그가 있습니다 ...
— F. Hauri

printf 형식 문자열을 인용하고 대신 \를 이탈하여 문자를 저장하십시오.%s\\n
— Digital Trauma

1
또는 seq8 개의 문자를 버리는 데 사용하십시오 :date -f<(seq -f$1-%g-6 1 12)|grep -c ^F
— Digital Trauma

1
실제로 2 개의 문자를 더 면도 할 수 있습니다. 시작 시퀀스 번호를 생략하면 seq는 기본적으로 1에서 시작하여 원하는대로 시작합니다.seq -f$1-%g-6 12|date -f-|grep -c ^F
— Digital Trauma

4

자바 스크립트, 70

f=function(a){b=0;for(c=12;c--;)b+=!new Date(a,c,1).getDay();return b}

왜 -1입니까?
— Lukasz 'Severiaan'Grela

1
좋아 보인다! ,b,c함수 선언에서 제거하여 몇 바이트를 더 절약 할 수 있습니다 (골프를 위해 vars를 누출 해도 좋습니다 !) . : 대신 테스트 결과 b로 캐스팅 Number할 수 있습니다 . 그러나 7 바이트를 절약 해야하는 대신 (일요일은 0을 반환 하기 때문에 작동 하며 13 일이 금요일이면 1 일이 일요일 일 것입니다)을 사용하여 다른 바이트를 저장할 수 있습니다! +=&&b++b+=/^F/.test(new Date(a,c,6))!new Date(a,c,1).getDay()getDaytest
— Dom Hastings

@DomHastings : 팁을위한 thx!
— guy777

3

케이

64 자

{+/6={x-7*x div 7}(.:')x,/:(".",'"0"^-2$'$:1+!:12),\:".13"}[0:0]

stdin에서 읽습니다.


좋아, 무슨 일이야? : P
— Williham Totland

연도 별 읽기, 매월 13 일의 날짜 목록 작성, 테스트 요일 = 금요일, 부울의 합계 결과 목록
— skeevey

3

공통 리스프 (CLISP), 149

(print 
    (loop for i from 1 to 12 count 
        (= 4 (nth-value 6 
            (decode-universal-time
                (encode-universal-time 0 0 0 13 i
                    (parse-integer (car *args*)) 0))))))

오 세상에, 나는 lisp를 읽을 수 없었습니다.
— Cruncher

2

기음# 110 101 93 92

int f(int y){int c=0;for(int i=1;i<13;i++)c+=new DateTime(y,i,8).DayOfWeek>0?0:1;return c;}

C # Linq 88

int g(int y){return Enumerable.Range(1,12).Count(m=>new DateTime(y,m,8).DayOfWeek==0);}

linq에 대한 Jeppe Stig Nielsen과 8 일 일요일 점검 제안에 감사드립니다.

>대신 제안 해 주신 Danko Durbić에게 감사합니다 ==.


대신 c+=(int)new DateTime(y,i,13).DayOfWeek==5?1:0;, 동등한 것을 사용하십시오 c+=new DateTime(y,i,8).DayOfWeek==0?1:0;. 비결은 빼는 것입니다 5. 왜냐하면 캐스트를 제거 할 수 있고 int숫자 8는 숫자보다 한 자릿수가 작기 때문 13입니다. 일요일 여덟째!
— Jeppe Stig Nielsen

Linq와 함께 : int g(int y){return Enumerable.Range(1,12).Count(m=>new DateTime(y,m,8).DayOfWeek==0);}. 물론 람다로서 이것은입니다 y=>Enumerable.Range(1,12).Count(m=>new DateTime(y,m,8).DayOfWeek==0).
— Jeppe Stig Nielsen

를 비교하여 한 문자를 저장할 수 있습니다 .DayOfWeek<1.
— Danko Durbić '12

@ DankoDurbić이 c#답변에 적용 할 수 있지만 적용 방법을 잘 모르겠습니다 linq.
— 카미

내 실수; 분명히 - DayOfWeek이외의 다른 정수와 비교할 수 없습니다 . 0error CS0019: Operator '<' cannot be applied to operands of type 'System.DayOfWeek' and 'int'
— Danko Durbić '12

2

PHP, 55 바이트

for(;++$i<13;)$c+=!date(w,strtotime($argn.-$i));echo$c;

로 실행하십시오 echo <year> | php -nR '<code>'.

기본적으로 Oleg가 시도한 것과 Damir Kasipovic 가 더 나은 골프를 하면서 했던 것과 동일합니다
. 일요일로 시작하는 매월 13 일 금요일이 있습니다.
그래서 나는 달을 반복하고 일요일 인 첫날을 세어 본다.

고장

for(;++$i<13;)          // loop $i from 1 to 12
    $c+=!                   // 4. if result is not truthy (weekday==0), increment $c
        date(w,             // 3. get weekday (0 stands for Sunday)
            strtotime(      // 2. convert to timestamp (midnight 1st day of the month)
                $argn.-$i   // 1. concatenate year, "-" and month
            )
        )
    ;
echo$c;                 // output

1

K, 42

{+/1={x-7*x div 7}"D"$"."/:'$+(x;1+!12;1)}

.

k){+/1={x-7*x div 7}"D"$"."/:'$+(x;1+!12;1)}'1776 2012 2013 2014
2 3 2 1

1

배쉬 ( 52 47 자)

for m in {1..12};do cal $m $Y;done|grep -c ^15

1

리볼, 63

f: 0 repeat m 12[d: do ajoin["6-"m"-"y]if d/weekday = 5[++ f]]f

Rebol 콘솔의 사용 예 :

>> y: 2012
== 2012

>> f: 0 repeat m 12[d: do ajoin["6-"m"-"y]if d/weekday = 5[++ f]]f
== 3

주어진 해의 모든 금요일 13 일을 수집하는 대안 솔루션은 다음과 같습니다.

>> collect[repeat m 12[d: do ajoin["13-"m"-"y]if d/weekday = 5[keep d]]]
== [13-Jan-2012 13-Apr-2012 13-Jul-2012]

1

배쉬 앤 세드, 39

ncal $1|sed '/F/s/13/\
/g'|grep -c ^\ 2

ncal 왼쪽 아래에 요일이있는 특정 연도의 달력을 인쇄합니다.

sed/g13 줄을 모두 줄 바꿈 하는 플래그로

grep -c "2"로 시작하는 행을 계산합니다 (20은 항상 13을 따릅니다)

이전 버전의 버그를 찾아 해결책을 제안한 @DigitalTrauma에게 감사드립니다!


나에게는 효과가 없다-금요일 줄은 13 개 이상을 포함하더라도 한 번만 인쇄된다.
— Digital Trauma

1
이런 식으로 할 수있는 최선은 38이라고 생각합니다.ncal $1|sed /F/s/13/\\n/g|grep -c ^\ 2
— Digital Trauma

1
@DigitalTrauma 당신이 맞아요. 어느 시점 에서이 스크립트가 작동했습니다. 내가 고칠 게
— 아니 찰스

1
@DigitalTrauma는 훨씬 더 긴 버전이 작동하는 것처럼 보입니다. 수정 해 주셔서 감사합니다!
— 아니 찰스

흥미롭게도, 내가 제안한 인용되지 않은 sed 표현은 GNU sed (Linux)에서는 작동하지만 BSD sed (OSX)에서는 작동하지 않습니다. GNU 버전을 선택하면 이식 비용으로 1 문자를 얻을 수 있다고 생각합니다.
— Digital Trauma

1

스칼라, 76 68 자

78 자 이내 :

def f(y:Int)=0 to 11 count(new java.util.GregorianCalendar(y,_,6).get(7)==6)

DAY_OF_WEEK = 7및에 마법의 숫자를 사용하는 것을 제외하고는 평범하지 않습니다 FRIDAY = 6.

68 자 버전 :

def f(y:Int)=0 to 11 count(new java.util.Date(y-1900,_,6).getDay==5)

예, Java는 API 간의 요일 상수 값을 변경했습니다.


new java.util.GregorianCalendar너무 부끄러운
— Cruncher

1

파이썬 195/204

지금monthdatescalendar 까지 주어진 연도의 달력을 반환 하므로 이전 연도에만 작동합니다 . 나는 많은 최적화 잠재력이 남아 있다고 생각합니다 :).

import calendar, sys
c=calendar.Calendar()
f=0
for m in range(1,12):
 for w in c.monthdatescalendar(int(sys.argv[1]),m):
  for d in w:
   if d.weekday() == 4 and d.day == 13:
    f=f+1
print(f)

다른 솔루션은 모든 날짜에 작동하지만 더 작지 않습니다.

import datetime,sys
y=int(sys.argv[1])
n=datetime.date
f=n(y,1,1)
l=n(y,12,31)
i=0
for o in range(f.toordinal(), l.toordinal()):
 d=f.fromordinal(o)
 if d.day == 13 and d.weekday() == 4:
  i=i+1
print(i)

첫 번째 예에서 범위는 (1,13)이어야합니다. 그렇지 않으면 2013 년과 같이 12 월 금요일 13 일을 놓치게됩니다.
— leancz

1
당신은 골프를 귀찮게하지 않았다. 그 공간 중 일부를 제거하십시오.
— mbomb007

1

펄 6, 55 53

{sum (1..12).map: {Date.new($_,$^a,1).day-of-week>6}}

이전 답변 :

{sum (1..12).map: {Date.new($_,$^a,13).day-of-week==5}}


0

파이썬 (v2) 120

import datetime as d,sys
s=0
for m in range(1, 13):
    if d.datetime(int(sys.argv[1]),m,6).weekday()==4: s=s+1
print s

0

펄 + lib POSIX 55

찾고 있지의 아이디어로 13th하지만 처음과 같은 sunday입니다 03 개 문자 저장이하자가! @ Iszi와 Danko Durbić에게 감사드립니다!

$==$_;$_=grep{!strftime"%w",0,0,0,1,$_,$=-1900}(0..11)

이 방법으로 2010에서 2017까지 (샘플의 경우) 계산할 수 있습니다.

perl -MPOSIX -pE '$==$_;$_=grep{!strftime"%w",0,0,0,1,$_,$=-1900}(0..11)' <(
    printf "%s\n" {2010..2017})
11321312

(OK, 개행 은 없지만 요청되지 않았습니다.)

이전 게시물 : 63

$==grep{5==strftime"%w",0,0,0,13,$_,$ARGV[0]-1900}(0..11);say$=

실제로 :

for i in {2010..2017};do
    echo $i $(
        perl -MPOSIX -E '
            $==grep{5==strftime"%w",0,0,0,13,$_,$ARGV[0]-1900}(0..11);say$=
            ' $i );
  done
2010 1
2011 1
2012 3
2013 2
2014 1
2015 3
2016 1
2017 2

0

에서는 스몰 토크 (이죠 / Pharo 맛) 정수에서이 방법을 구현하는 ( 86 개 문자)

countFriday13^(1to:12)count:[:m|(Date year:self month:m day:13)dayOfWeekName='Friday']

그런 다음 다음과 같이 사용하십시오 2014countFriday13.

물론 더 짧은 이름을 사용할 수는 있지만 스몰 토크는 아닙니다


0

C ++-너무 많은 바이트 :(

날짜 라이브러리를 사용하지 않는 솔루션을 시도했습니다.

나는 꽤 멋진 해결책을 찾았습니다. 불행히도 나는 이것보다 더 짧을 수는 없습니다. 더 나은 방법이 있어야한다고 느끼기 때문에 실제로 버그가 있습니다.

솔루션은 이 알고리즘 을 기반으로하며 그 자체는 44 바이트에 불과합니다. 불행히도 멋지게 포장하려면 100 바이트가 더 필요합니다 ...

#include<stdlib.h>
main(int,char**v){int f=0,d,m,y;for(m=1;m<13;++m)d=13,y=atoi(v[1]),(d+=m<3?y--:y-2,23*m/9+d+4+y/4-y/100+y/400)%7-5||++f;return f;}

리턴 코드를 통해 출력합니다 (C ++에서 또는를 사용 cout하거나 printf다른 것을 필요로하므로 #include솔루션을 더 많이 날려 버릴 수 있습니다).

드라이버 / 테스트 프로그램 :

# Make sure we're not running an old version
rm doomsday.exe

gcc doomsday.cpp -o doomsday.exe

./doomsday.exe 1776
echo 1766: $?

./doomsday.exe 2012
echo 2013: $?

./doomsday.exe 2013
echo 2013: $?

./doomsday.exe 2014
echo 2014: $?

echo `wc doomsday.cpp -c` characters

드라이버 프로그램의 출력 :

$ ./test_doomsday 
1766: 2
2013: 3
2013: 2
2014: 1
150 doomsday.cpp characters

44가 아닌 알고리즘에 대해 88을 계산합니다. 알고리즘은 무엇이며 워핑은 무엇입니까? ($m<3?$y--:$y-2)+3대신에 d=13,, d+=m<3?y--:y-2,그리고 d+4잘 작동하고 많이 절약 할 수 있습니다. +5대신 +3및 -5작동해야하며 2 바이트를 절약합니다. for(m=0;++m<13;)1 바이트를 저장합니다. m=0함수 헤드로 이동 하면 다른 바이트가 절약됩니다. ()%7||++f루프 헤드 로 이동 하면 다른 루프 헤드가 절약됩니다. 149 바이트에서 136 바이트로 줄였습니다.
— Titus

0

Clojure에서, 207 187 바이트

를 제거하여 -20 바이트 import및 누락 된 일부 공백.

(import '[java.time LocalDate DayOfWeek])#(loop[d(LocalDate/parse(str %"-01-01"))c 0](if(=(.getYear d)%)(recur(.plusDays d 1)(if(and(=(.getDayOfMonth d)13)(= (.getDayOfWeek d) DayOfWeek/FRIDAY))(inc c)c))c))

주어진 해의 1 월 1 일부터 매일 반복됩니다. 요일이 13 일 금요일이면 카운트가 증가합니다. 내년에 도달 할 때까지 계속 반복됩니다.

(import '[java.time LocalDate DayOfWeek])

(defn count-friday-13ths [year]
  (loop [d (LocalDate/parse (str year "-01-01")) ; Starting date
         c 0] ; The count
    (if (= (.getYear d) year) ; If we haven't moved onto the next year...
      (recur (.plusDays d 1) ; Add a day...
             (if (and (= (.getDayOfMonth d) 13) ; And increment the count if it's Friday the 13th
                      (= (.getDayOfWeek d) DayOfWeek/FRIDAY))
               (inc c) c))
      c))) ; Return the count once we've started the next year.

0

PHP, 내장 없음, 81 바이트

echo 0x5da5aa76d7699a>>(($y=$argn%400)+($y>102?$y>198?$y>299?48:32:16:0))%28*2&3;

로 실행하십시오 echo <year> | php -nR '<code>'.

고장

평일은 400 년마다 반복됩니다.
1600에서 1999 사이의 결과 (예를 들어)에는 단 3 개의 간격이있는 28 길이의 기간이 있습니다.

  0:2212122131132131222211221311
 28:2212122131132131222211221311
 56:2212122131132131222211221311
 84:2212122131132131122
103:       131132131222211221311
124:2212122131132131222211221311
152:2212122131132131222211221311
180:2212122131132131222
199:       131132131222211221311
220:2212122131132131222211221311
248:2212122131132131222211221311
276:221212213113213122221122
300:            2131222211221311
316:2212122131132131222211221311
344:2212122131132131222211221311
372:2212122131132131222211221311

이러한 격차에 대해 연도를 조정 한 후 간단한 해시로 결과를 얻을 수 있습니다.

$y=$argn%400;foreach([300,199,103]as$k)$y<$k?:$y+=16;
echo"2212122131132131222211221311"[$y%28];

짧지 않지만 (95 바이트) 예쁘다. 그리고 우리는 골프를 할 수 있습니다

  • 오프셋에 3 진 체인을 사용하여 4 바이트
  • 해시 맵을 base4 문자열에서 정수로 변환하여 8 바이트
  • 16 진 표현을 사용하여 하나 더
  • 하나는 표현을 병합하여.

CompuChip의 C ++ 응답 포트 를 84 바이트로 줄일 수 있습니다.for(;++$m<13;23*$m/9+($m<3?$y--:$y-2)+5+$y/4-$y/100+$y/400)%7?:$f++)$y=$argn;echo$f;
— Titus

0

Japt -x , 10 바이트

CÆ5¥ÐUXD e

시도 해봐

CÆ5¥ÐUXD e     :Implicit input of integer U
C              :12
 Æ             :  Map each X in the range [0,C) (months are 0-indexed in JavaScript)
  5¥           :  Check if 5 is equal to
    ÐUXD       :  new Date(U,X,13)
         e     :  0-based index of day of the week
               :Implicitly reduce by addition and output
당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.