1年で13日の金曜日はいくつですか?


28

あなたの挑戦は、1年を与えられて「金曜日13日」の数を出力するプログラムを書くことです。

ルールと詳細:

  • を介してSTDIN、またはプログラムに渡される引数として入力を受け取ることができます。
  • 結果をに出力する必要がありますSTDOUT
  • 入力は有効な年であり、グレゴリオ暦より前の日付ではないと想定できます(これらの場合、未定義の動作は許可されます)。
  • カレンダー/日付ライブラリが許可されています。

これはであるため、最短のコード(バイト単位)が優先されます。

(関連チャレンジリンク)


7
入力に必要な範囲はどのくらいですか?1800年よりずっと前になった場合、ユリウス暦からグレゴリオ暦への切り替えについて、どのような仮定が必要ですか?
ピーターテイラー

@PeterTaylor私はそれについて考えていませんでした。日付がグレゴリオ暦より前の日付である場合、未定義の動作を設定できます。
ランチャー

1
グレゴリオ暦を最初に採用した国は、グレゴリー自身の雄牛に続いて1582年10月にそうしました。新しいカレンダーを採用する国は、後半20世紀までは変化しなかった、例えばギリシャは3月1日1923にそれを導入
ジャップスティグ・ニールセン

@JeppeStigNielsenカレンダーなどについてはあまり知りません。彼らがそれらを採用したかどうかは、グレゴリオ暦の日付を変えません。ライブラリは、私が推測するかなりの方法で日付を計算できるはずですか?
ランチャー

3
私はここでオフトピックになっていると思います。英米のプログラマーによって書かれた多くのライブラリーは、カレンダーの「正しい」変更時刻として1752年9月を使用しています。これは大英帝国が変わったときでした。もちろん、新しいカレンダーは米国が設立されたときに保持されていました。(好奇心として、いくつかのSQLソフトウェアは、1752年9月の問題に対処したくないため、1753年を最小年として持っています。)ただし、1752年9月の使用は非常にアングロセントリックです。グレゴリオ暦の日付は、歴史的に使用されたかどうかにかかわらず同じです。それはいわゆる予後グレゴリオ暦です。
ジェッペスティグニールセン

回答:


3

APL(Dyalog APL)CAL からDFNS、29のバイト

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

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

⍳ 12 1から12までの整数

⎕ ,¨ 数値を入力して、12個の数字のそれぞれに追加します

{ 各ペアで、関数を適用します…

cal⍵ その年月のカレンダーを取得する

2 ↓ 2行(キャプションと日)をドロップします

 転置(行ではなく列をアドレス指定できるように)

¯5 ↑ 最後の5つ(金曜日と土曜日にそれぞれ2桁と1つのスペース)

3 ↑ 最初の2つ(金曜日に2桁とスペースを追加)を取る

 転置(読み取り順序を取得)

, ラヴェル

 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 ≠.= 0の内部「製品」、ただし+。×の代わりに≠および=を使用

⊢ , 変更されていない引数の年を追加する

2 3 ¯1 +.× これらの数字の内積

14 | 14で除算したときの除算余り

'21232211321211' ⌷⍨ この文字列へのインデックス


29文字ですが、これらは1バイト文字以上ですよね?
ランチャー

@Cruncher見出しに説明リンクを追加しました。TIOリンクを開くと、右側に「29文字、29バイト(SBCS)」、つまり1バイト文字セットと表示されていることがわかります。
アダム

さて、私はこれが新しい勝者だと思いますが、このSEの標準的な実践は、質問のずっと後に受け入れられた答えを変更することですか?
ランチャー

@Cruncherはい。そして、OPのかなり後に受け入れられるために必要なバッジさえあります。
アダム

12

Mathematica 49 46 45 44 42

純粋な関数として: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


1文字短く:f=DayName@{#,m,6}~Table~{m,12}~Count~Friday&
Mr.Wizard

@ 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のおかげで1週間前に戻ってキャラクターを剃り、Time.newからTime.gmに切り替えて別のキャラクターを剃った

編集:それをもう少し難読化することを犠牲にして、私は46で得ることができます

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

5
あなたが6日金曜の数を数える場合は、1つ-charが節約
ジョン・ドヴォルザーク

2
@JanDvorak賢い!
histocrat

なぜ6?わかりませんでした。
NARKOZ

3
6日は金曜日であれば、13日も金曜日です
TwiNight

8日が日曜日の場合、1日も同様であるため、を使用できますTime.gm(m,i).wday<1。また、なぜ関数に名前を付けているのかわかりません。
リーW

8

Powershell、68 63 58 52 50

ヒントについてはIsziに感謝します。

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

月の1日目が日曜日の場合、13日目は金曜日になります。

私も試しました:

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

ただし$args、スクリプトブロック内では同じではありません。


1
私は月の最初の日を使用するというアイデアが好きです。
ランチャー

ナイストリック、そこ。ただし、@は不要です。
イッツィ

別のことですが、私は多くのスクリプトで同じことを犯しています。チャレンジは、入力が引数から取得できることを指定します。ループ内で置換$n$args$n=read-host;完全になしで行うことができます。保存8.上記のように@を削除すると、54になります。
Iszi13年

訂正:52になりました!
イジ

2番目のスクリプトが機能しない理由を理解しようとしていて、私は途方に暮れています。面白いのは、私が変えることができるということである$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ここで、月に1回だけ行うことは実際には短くなりますが!sum(format(as.Date(paste(scan(),1:12,13,sep="-")),"%w%d")=="513")65文字のみです!
plannapus

うわー、それは<文字を整数に強制するだろうとは思わなかったでしょう。ナイストリック!
plannapus

@plannapusかなり一般的です。文字コードはすべて数字であるため。Javaでもintとcharを比較できます
ランチャー

5

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

ライブラリまたは組み込みの日付関数を使用しない:

Golfscript – 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引数までのうるう年の数を計算します(グレゴリオ暦が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)最終日のシフト(閏年では通常年に1、2)までの合計。


これは私の最初のゴルフスクリプトゴルフですので、さらにゴルフをするためのヒントをいただければ幸いです。
Wrzlprmft

私はそのような解決策について、実際には14年しかユニークではないという事実を利用して考えていましたが、それを競争力のあるものにするのに最適な言語はわかりませんでした。これは、ライブラリがない最短の答えだと思います。うるう年が均等に4年ごとである場合、これで勝つことができるかもしれません
ランチャー14

4

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

最短の答えではありませんが、ライブラリを使用しません。


ねえ、あなたは説明されていない答えを提供したいと思いますか?あなたが何をしたか正確に興味があります
ランチャー

1
@Cruncher、これはグレゴリオ暦が400年のサイクルに従うことに基づいたルックアップテーブルです。
ピーターテイラー

1
より明示的に(長い)、C#: static char GetNumberOfFriday13s(int year) { const string perpetualCalendar = "1221212213113213122221122131122121221311321312222112213112212122131132131222211221311221212213113213112213113213122221122131122121221311321312222112213112212122131132131222211221311221212213113213122213113213122221122131122121221311321312222112213112212122131132131222211221311221212213113213122221122213122221122131122121221311321312222112213112212122131132131222211221311221212213113213122221122131"; return perpetualCalendar[year % 400];。マイナスの年は機能しません。
スティグニールセン

可愛い!小さなバグとして、する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文字)

組み込みのカレンダーツールを使用しない他のソリューションが1つしかないことに驚いています。これも(非常に難読化された)数学的なアプローチです。これも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のソリューションと彼の圧縮の使用を楽しんだ。2つの小さなバグを修正し、コードを調整して長さを短くしました。

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

バッシュ47 36

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

seqデフォルトでstartを使用して10文字を保存してくれた@DigitalTraumaに感謝します1

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

(以前のバージョンechoではwhenが空行であるためにバグが発生していました<(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

であり、ロケール、それは仕事をしない場合は、する必要があります依存、SI

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

これはロケールに依存しているようです。
ピーターテイラー

はい、これはデフォルトに基づいていますC。しかし、バグが...そこにある
F. HAURI

:あなたのprintfのフォーマット文字列をunquotingと\代わりにエスケープすることにより、文字の保存%s\\n
デジタルトラウマ

1
または使用seq:8つの文字ドロップするdate -f<(seq -f$1-%g-6 1 12)|grep -c ^F
デジタルトラウマ

1
実際には、さらに2文字を削ることができます。:あなたは開始シーケンス番号を省略した場合、配列は、それはあなたが望むものを、デフォルトでは1から始まりますseq -f$1-%g-6 12|date -f-|grep -c ^F
デジタルトラウマ

4

JavaScript、70

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

そして、なぜそれは-1ですか?
ルカシュ「セベリア」グレラ

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
ドムヘイスティングス

@DomHastings:あなたのヒントのためのTHX !!!
guy777

3

k

64文字

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

stdinからの読み取り


さて、ここで何が起こっているのでしょうか?:P
ウィリーハムトットランド

年、毎月の13日の日付のビルドリスト、週=金曜日の試験日、ブール値のリストを、その和で読む
skeevey

3

Common Lisp(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の..読むことができなかったん
たけ

2

C# 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日の日曜日のチェックの提案に感謝します。

>代わりに提案してくれたDankoDurbićに感謝し==ます。


代わりにc+=(int)new DateTime(y,i,13).DayOfWeek==5?1:0;、同等のものを使用しc+=new DateTime(y,i,8).DayOfWeek==0?1:0;ます。秘subtractは減算5することです。なぜならキャストを取り除くことができint、また数字8が数字より1桁少ないから13です。日曜日8
ジェッペスティグニールセン

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)です。
ジェッペスティグニールセン

を比較して、1文字を保存できます.DayOfWeek<1
ダンコドゥルビッチ

@DankoDurbićこれはc#回答に適用できますが、適用方法がわかりませんlinq

私の間違い; 明らかに- DayOfWeek以外の整数と比較することはできません。0error CS0019: Operator '<' cannot be applied to operands of type 'System.DayOfWeek' and 'int'
ダンコドゥルビッチ

2

PHP、55バイト

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

で実行しecho <year> | php -nR '<code>'ます。

基本的にオレグが試みたものとダミール・カシポヴィッチが試みたものと同じで、ゴルフが良くなっているだけ
です。日曜日から始まる毎月、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

Rebol、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

Bash and Sed、39

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

ncal 左下の曜日を指定した年のカレンダーを印刷します。

sed/gフラグを使用すると、13行すべてが改行で沈みます

grep -c 「2」で始まる行をカウントします(20は常に13に続きます)

古いバージョンのバグを見つけて解決策を提案してくれた@DigitalTraumaに感謝します!


かなり私のために動作しません-金曜日ラインは彼らだけが含まれている場合でも、一度に印刷されている複数の13
デジタルトラウマ

1
:私はこのような何かを行うことができます最高の38だと思うncal $1|sed /F/s/13/\\n/g|grep -c ^\ 2
デジタルトラウマ

1
@DigitalTraumaそのとおりです。ある時点で、このスクリプトは機能していました。修正させてください。
チャールズではない

1
@DigitalTraumaは、もっと長いバージョンが機能していたようです。修正してくれてありがとう!
チャールズではない14

興味深いことに、引用されていないsed式はGNU sed(Linux)で動作しますが、BSD sed(OSX)では動作しません。GNUバージョンを選択すると、移植性を犠牲にして1文字を獲得できると思います。
デジタル外傷14

1

Scala、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はとても長くなければならないのは残念だ:(
ランチャー14

1

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

あなたの最初の例では範囲は、そうでなければ、2013年のように、12月金曜日の13thsを逃すと思います(1,13)であるべき
leancz

1
あなたもゴルフを気にしませんでした。これらのスペースの一部を削除します。
mbomb007


0

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

Perl + lib POSIX 55

探しているではないという考えでは13thなく、まず、およびなどsunday0、このletが3文字の保存!@ IsziとDankoDurbićに感謝します!

$==$_;$_=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

スモールトーク(スクイーク/ファロ風味)、整数でこの方法を実施する(86文字)

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

次に、次のように使用します2014countFriday13

もちろん、短い名前を使用することもできますが、それはSmalltalkではありません


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機能ヘッドに移動すると、もう1バイト節約されます。()%7||++fループヘッドに移動すると、もう1つ保存されます。149バイトから136バイトに減少。
タイタス

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バイト、
  • もう1つは、16進表現を使用して、
  • 1つは式をマージすることです。

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;
タイタス

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.