미신 프로그래밍


19

당신의 도전은 매우 간단합니다. 1 년을 입력으로 받으면 그레고리력에 따라 13 일 금요일 을 포함하는 해당 연도의 모든 달을 인쇄하십시오 . 그레고리오 력은 1582 년까지 소개되지 않았지만 간단하게하기 위해 AD는 0001 AD 이후로 사용 된 것으로 가장합니다.

규칙

  • 전체 프로그램 또는 기능이 허용됩니다.

  • 함수 인수, STDIN 또는 명령 행 인수로 입력을 취할 수 있습니다.

  • 날짜 및 시간 내장을 사용할 수 없습니다.

  • 입력 값이 유효한 연도라고 안전하게 가정 할 수 있습니다. 입력이 1보다 작거나, 유효한 정수가 아니거나, 언어 고유 숫자 유형보다 큰 경우에는이를 처리 할 필요가 없으며 정의되지 않은 동작이 발생합니다.

  • 표준을 지정하는 한 출력은 숫자, 영어 또는 사람이 읽을 수있는 다른 형식 일 수 있습니다.

  • 윤년을 고려하십시오. 그리고 윤년은 4 년마다 발생하지 않는다는 것을 기억하십시오 !

이에 대해 여러 가지 방법이 있기 때문에 어떻게해야하는지 말하고 싶지 않습니다. 그러나 시작 위치가 혼란 스러울 수 있으므로 날짜를 기준으로 요일을 결정하는 몇 가지 신뢰할 수있는 방법이 있습니다.

샘플 IO

2016 --> May
0001 --> 4, 7
1997 --> Jun
1337 --> 09, 12
123456789 --> January, October

평상시와 같이 이것은 코드 골프이므로 표준 허점이 적용되어 가장 짧은 답변이 이깁니다.


5
13 일 금요일에 실행되면 13 일 금요일이 아닌 달을 되돌리고 출력해야합니다. (승리에 대한 프리키 프라이데이 참조)
애디슨 크럼프


이 예가 맞 0001 --> 5습니까? 이 페이지 (및 내 코드) 에 따르면 4 월과 7 월이어야합니다.
faubi

@faubiguy 내 나쁜, 맞아. 줄리안 달력에있었습니다. 그 문제를 해결하겠습니다.
DJMcMayhem

"날짜 또는 시간 내장을 사용할 수 없습니다"라는 말로 유닉스 시간으로 변환 할 수 없습니까?
busukxuan

답변:


1

피시스, 73 바이트

L?>b2QtQfq%+++13+/-*2.6?qT2 12%-T2 12 .2 1*5%yT4*4%yT100*6%yT400 7 5r1 13

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

내 파이썬 답변에서와 같이 가우스 알고리즘 사용. ~ 55 바이트의 코드는 평일 계산을위한 것이므로 더 나은 알고리즘을 선택하면 생각보다 많이 줄일 수 있지만 적어도 지금은 작동합니다! :)


2

파이썬 2 157 144 136 바이트

내 솔루션은 가우스 알고리즘을 사용합니다. 입력은 정수로서 연도입니다. 출력은 금요일 13이 숫자 (1-12) 인 월 목록입니다. 아마도 더 많은 골프가 가능하지만 늦어지고 있습니다 ... 내일 이걸 편집하고 조금 더 내립니다. 그 동안 제안은 언제나 환영합니다!

def f(i):y=lambda m:(i-1,i)[m>2];print[m for m in range(1,13)if(13+int(2.6*((m-2)%12,12)[m==2]-.2)+y(m)%4*5+y(m)%100*4+y(m)%400*6)%7==5]

편집 : for 루프를 목록 종합으로 바꾸고 다른 작은 조정을 수행하여 144로 줄였습니다.

edit2 : Morgan Thrapp의 제안으로 136 개까지 골프를 치고 그가 발견 한 버그를 수정했습니다. 고마워요! :)


1

펄 - 141 107 103 바이트

$y=<>-1;map{$y++if++$i==3;print"$i "if($y+int($y/4)-int($y/100)+int($y/400))%7==$_}'634163152042'=~/./g

이렇게하면 수정 된 버전의 율리우스 일 수식을 사용하여 3 월 13 일의 요일 을 계산 한 다음 매월 1 주일의 오프셋 수를 사용하여 나머지 일의 요일을 찾습니다. 3 월부터 시작하여 전년의 마지막 2 개월부터 시작하여 현재 연도의 첫 10 개월 (윤년을 두 번 계산하지 않기 위해)으로 시작합니다.


1

씨 - 164 153 112 바이트

Schwerdtfeger의 방법을 크게 수정 한 멋진 솔루션을 찾았습니다. 부호있는 32 비트 워드에 맞게 수정 된 기수 7을 사용하여 필요한 테이블을 정수로 인코딩합니다. 월은 ASCII 문자로 출력되며 1 월은 1, 2 월 등으로 2인코딩되고 10 월은 :, 11 월은 다음과 같이 인코딩됩니다.; 12 월은으로 인코딩됩니다 <.

t=1496603958,m;main(y){for(scanf("%d",&y),y--;(y%100+y%100/4+y/100%4*5+t+5)%7||putchar(m+49),t;t/=7)2-++m||y++;}

여기에 약간 골퍼가 없습니다 :

t=1496603958,m;
main(y){
  for(
    scanf("%d",&y),y--;
    (y%100+y%100/4+y/100%4*5+t+5)%7||putchar(m+49),t;
    t/=7
  )
    2-++m||y++;
}

나는 그것을 더 작게 만드는 몇 가지 방법이 있다고 확신하지만, 알고리즘 또는 약간의 변형은 13 일 금요일 (코드 크기와 관련하여)이 발생하는 달을 찾는 데 거의 이상적이라고 생각합니다. 노트:

  1. 64 비트 단어를 사용할 수 있다면 성가신 추가를 제거 할 수 있습니다 (+5 )를 .
  2. m우리 가보고있는 달은 추론 할 수 있기 때문에 변수 는 실제로 필요하지 않습니다.t .

나는 이전 답변을 아래에 남겨두고 다른 답변에서는 볼 수없는 완전히 다른 방법을 사용합니다.


이는 관련 문제에 대한 솔루션을 기반으로합니다 ( /codegolf//a/22531/7682 ).

Y,M,D,d;main(y){for(scanf("%d",&y);Y<=y;++D>28+(M^2?M+(M>7)&1^2:!(Y&3)&&(Y%25||!(Y&15)))&&(D=1,M=M%12+1)<2&&Y++)(d=++d%7)^1||D^13||y^Y||printf("%d,",M);}

기본적으로 그레고리력을 시뮬레이트하여 한 번에 하루 씩 전진하여 금요일과 13 일인 달을 인쇄합니다. 다음은 약간 더 읽기 쉬운 형식입니다.

Y,M,D,d;
main(y){
  for(
    scanf("%d",&y);
    Y<=y;
    ++D>28+(
      M^2
        ?M+(M>7)&1^2
        :!(Y&3)&&(Y%25||!(Y&15))
    )&&(
      D=1,
      M=M%12+1
    )<2&&Y++
  )
    (d=++d%7)^1||D^13||y^Y||
      printf("%d,",M);
}

인상적인 ecc이지만 123456789에서 찾을 수 없음-> 10 월 1 월 10 월
RosLuP

흠, 그것은 나를 위해한다. 플랫폼 의존적 인 이유가 있습니까? Clang으로 컴파일 할 때 상당히 현대적인 Macbook Pro에서 작동합니다. 에 1:대해 출력 123456789되며 :여기서 10을 나타냅니다. 위의 인코딩을 명확히했습니다.
Fors

예 1 : 여기도 있습니다. 나는 ':'이 10 월을위한
것이라고

0

Excel, 137 바이트

A1에서 입력 연도를받습니다. 출력은 분리되지 않은 16 진 목록입니다. (1 월 = 0, 12 월 = B)

1 월과 8 월에 가우스 알고리즘을 사용합니다.

=CHOOSE(MOD(6+5*MOD(A1-1,4)+4*MOD(A1-1,400),7)+1,"","",1,"","",0,"")&CHOOSE(MOD(5*MOD(A1-1,4)+4*MOD(A1-1,400),7)+1,9,35,"8B",5,"2A",7,4)

이 답변은 현재 날짜 및 시간 기본 제공을 사용하며, 이는 챌린지의 규칙에 명시 적으로 명시되어 있습니다.
Fors

@Fors, 지적 해 주셔서 감사합니다. 업데이트되었습니다.
Wernisch

0

C, 276219 바이트

#define R return
#define L(i) for(;i-->0;) 
u(y,m){R m-1?30+((2773>>m)&1):28+(y%4==0&&y%100||y%400==0);}s(y,m,g){g+=4;L(m)g+=u(y,m),g%=7;L(y)g+=1+u(y,1),g%=7;R g;}z(y,m,r){m=12;L(m)s(y,m,13)-4||(r|=1<<(m+1));R r;}

stdout의 stdin 출력에서 ​​입력 http://ideone.com/XtuhGj를 시도하십시오 [디버그 기능은 z입니다]

w(y,m,r){m=12;L(m)s(y,m,u(y,m))||(r|=1<<(m+1));R r;}
/*    
// ritorna il numero dei giorni di anno=y mese=m con mese in 0..11
// m==1 significa febbraio   y%4?0:y%100?1:!(y%400) non funziona
u(y,m){R m-1?30+((2773>>m)&1):28+(y%4==0&&y%100||y%400==0);}

// argomenti anno:y[0..0xFFFFFFF]  mese:m[0..11]  giorno:g[1..u(y,m)]
// ritorna il numero del giorno[0..6]
s(y,m,g)
{g+=4; // correzione per il giorno di partenza anno mese giorno = 0,1,1
 L(m)g+=  u(y,m),g%=7; // m:0..m-1  somma mod 7 i giorni del mese dell'anno y
 L(y)g+=1+u(y,1),g%=7; // y:0..y-1  somma mod 7 gli anni da 0..y-1
                       // g+=1+u(y,1) poiche' (365-28)%7=1 e 1 e' febbraio
 R g;
}

// argomenti anno:y[0..0xFFFFFFF], m=0 r=0 
// calcola tutti gli ultimi giorni del mese dell'anno y che cadono di lunedi'
// e mette tali mesi come bit, dal bit 1 al bit 12 [il bit 0 sempre 0] in r
w(y,m,r){m=12;L(m)s(y,m,u(y,m))||(r|=1<<(m+1));R r;}

// argomenti anno:y[0..0xFFFFFFF], m=0 r=0 
//ritorna in r il numero dei mesi che ha giorno 13 di venerdi[==4]
// e mette tali mesi come bit, dal bit 1 al bit 12 [il bit 0 sempre 0] in r
z(y,m,r){m=12;L(m)s(y,m,13)-4||(r|=1<<(m+1));R r;}
*/

#define P printf
#define W while 
#define M main 
#define F for
#define U unsigned
#define N int
#define B break
#define I if
#define J(a,b)  if(a)goto b
#define G goto
#define P printf
#define D double
#define C unsigned char
#define A getchar()
#define O putchar
#define Y malloc
#define Z free
#define S sizeof
#define T struct
#define E else
#define Q static
#define X continue
M()
{N y,m,g,r,arr[]={1,297,1776,2000,2016,3385}, arr1[]={2016,1,1997,1337,123456789};
 C*mese[]={"gen","feb","mar","apr","mag","giu","lug","ago","set","ott","nov","dic"};
 C*giorno[]={"Lun","Mar","Mer","Gio","Ven","Sab","Dom"};
 P("Inserisci Anno mese giorno>");r=scanf("%d %d %d", &y, &m, &g);
 P("Inseriti> %d %d %d r=%d\n", y, m, g, r);
 I(r!=3||m>12||m<=0||g>u(y,m-1))R 0;
 r=s(y,m-1,g);// 12-> 11 -> 0..10
 P("Risultato=%d giorno=%s\n", r, giorno[r]);
 r=w(y,0,0);P(" r=%d ", r);P("\n");
 F(m=0;m<6;++m)
        {P("N anno=%d -->",arr[m]); 
         r=w(arr[m],0,0); // ritorna in r i mesi tramite i suoi bit...
         F(y=1;y<13;++y) I(r&(1<<y))P("%s ",mese[y-1]);
         P("\n");
        }
 F(m=0;m<4;++m)
        {P("N anno=%d -->",arr1[m]); 
         r=z(arr1[m],0,0); // ritorna in r i mesi tramite i suoi bit...
         F(y=1;y<13;++y) I(r&(1<<y))P("%s ",mese[y-1]);
         P("\n");
        }

}
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.