일년에 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↑⍉2cal⍵}¨⎕,¨⍳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.