迷信的なプログラミング


19

あなたの挑戦は非常に簡単です。入力として年を指定し、グレゴリオ暦に従って13日金曜日を含むその年のすべての月を印刷します。グレゴリオ暦は1582年まで導入されていませんが、簡単にするために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

「日付や時刻の組み込みを使用することは許可されていません」ということで、Unixの時刻に変換することもできませんか?
-busukxuan

回答:


1

Pyth、73バイト

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

オンラインでお試しください!

Pythonの答えのように、Gauss-Algorithmを使用します。〜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か月になります(うるう年を2回計算するのを避けるため)。


1

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

基本的にグレゴリオ暦をシミュレートし、一度に1日ずつ進み、金曜日と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月のものだったことがわかりませんでした
-RosLuP

0

Excel、137バイト

A1で入力年を取得します。出力は、16進数の分離されていないリストです。(1月= 0、12月= B)

1月と8月にGaussのアルゴリズムを使用します。

=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、それを指摘してくれてありがとう。更新しました。
ヴェルニッシュ

0

C、276 219バイト

#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.