(この記事はQiitaで僕が書いたものを移行した記事です。記事中のコメントはQiitaの該当記事を参照ください)
今年2016年はうるう年です。2月は29まであり1年が366日でオリンピックが開かれます。
そして、うるう年判定はプログラマにとって熱いものがこみ上げますよね。縛りを入れるとなかなか難易度がちょうど良くなり楽しいです。
まず参加エントリーNo. 1の僕のコードから
オーソドックスなやつ
まずは縛りなし
function isLeapYear(y) { y = Number(y); return y % 400 === 0 || y % 100 !== 0 && y % 4 === 0; }
簡潔ですね。
剰余(%)縛り
次は剰余なしで
function isLeapYear(y) { y = Number(y); const dividedBy4 = (y >> 2 << 2) === y; const dividedBy100 = (0 | y / 100) * 100 === y; const dividedBy400 = dividedBy100 && (0 | y / 100) >> 2 << 2 === (0 | y / 100); return dividedBy400 || !dividedBy100 && dividedBy4; }
整数に丸めて変わらないかで判定しています。(dividedByFourとかいう文法ガン無視の変数名は気にしないでください)
さらに「整数に丸める操作」縛り
Math.floorやparseIntといった整数に丸める処理を縛ります。もちろんここで>>といったビット演算も縛り対象となります。
そろそろキツイ…
function isLeapYear(y) { y = Number(y); let dividedBy4 = y.toString(2).slice(-2); dividedBy4 = dividedBy4 === '00' || dividedBy4 === '0'; let dividedBy100 = y.toString(10).slice(-2); dividedBy100 = dividedBy100 === '00' || dividedBy100 === '0'; let dividedBy400 = Number(y.toString(10).slice(0, -2)).toString(2).slice(-2); dividedBy400 = dividedBy100 && (dividedBy400 === '00' || dividedBy400 === '0'); return dividedBy400 || !dividedBy100 && dividedBy4; }
うーん、暗黒ですね。一応解説しますと4の倍数かは2進法に変換後、下2桁が00かどうかで判断しています。100の倍数かは10進法で下2桁が00か、400の倍数かは10進法で下2桁を除いた数が4の倍数か + 100の倍数かで判定しています。
dividedByFourはこうも直せます。
const dividedByFour = '13579'.indexOf(y.slice(-2, -1)) !== -1 && '26'.indexOf(y.slice(-1)) !== -1 || ('24680'.indexOf(y.slice(-2, -1)) !== -1 || y.slice(-2, -1) === '') && '048'.indexOf(y.slice(-1)) !== -1;
「400進法」
…400進法で下1桁が0ならば400の倍数じゃないか…!!と閃いたのですがJavaScriptのtoStringは32進法までしか対応してなかったので20進法に直した時下2桁が0かで判定にしたいと思います。まさか20進法なんて使う日が来るとは…
function isLeapYear(y) { y = Number(y); let dividedBy4 = y.toString(2).slice(-2); dividedBy4 = dividedBy4 === '00' || dividedBy4 === '0'; let dividedBy100 = y.toString(10).slice(-2); dividedBy100 = dividedBy100 === '00' || dividedBy100 === '0'; let dividedBy400 = y.toString(20).slice(-2); dividedBy400 = dividedBy400 === '00' || dividedBy400 === '0'; return dividedBy400 || !dividedBy100 && dividedBy4; }
きたれ、真のうるう年判定王!!
自分に課した縛り + コードという形で募集します。言語は自由です。