ログイン新規登録
@@ -1 +1 @@
-閏年判定コードを極限までMinifyしてみる
+370d3c8a8027d973fd42
@@ -1,165 +1 @@
-# 動機
-
-<blockquote class="twitter-tweet" data-lang="en"><p lang="ja" dir="ltr">なるっち「うるう年判定?そんなの簡単じゃん!」カタカタ<br><br>if ((y % 4 == 0 &amp;&amp; y % 100 != 0) || y % 400 == 0)<br><br>ねねっち「もっと短くなるんじゃない?」ッターン!<br><br>if(y%25&gt;0&gt;y%4|y%16&lt;1)<br><br>なるっち「・・・!」 <a href="https://t.co/5z7B4PAaqD">pic.twitter.com/5z7B4PAaqD</a></p>&mdash; とさか2 (@nanTosaka2) <a href="https://twitter.com/nanTosaka2/status/881068767324684288?ref_src=twsrc%5Etfw">July 1, 2017</a></blockquote>
-
-1年以上前のツイートを掘り起こすのも申し訳ないんですが、あるOSS(JavaScript)で閏年判定コードが長ったらしくなっているのをMinifyする際にこのツイートを思い出して読んでみたところ、「これまだまだMinifyできるのでは?」と思ったのが動機です。ごめんなさい。
-
-## 閏年の定義
-
-グレゴリオ暦では閏年は次のように判定されます
-
-```js
-if (year % 4 === 0) {
- if (year % 100 === 0) {
- if (year % 400 === 0) {
- return true; // 西暦年が400で割り切れるなら、その年は閏年である。
- }
- return false; // 西暦年が400で割り切れないが、100で割り切れるなら、その年は閏年ではない。
- }
- return true; // 西暦年が100で割り切れないが、4で割り切れるなら、その年は閏年である。
-}
-return false; // 西暦年が4で割り切れないなら、その年は閏年ではない。
-```
-
-## Minifyされていく過程
-
-`y`には西暦年が入っているものとします。
-
-### なるっちの書いた初期コード
-
-```cpp
-if ((y % 4 == 0 && y % 100 != 0) || y % 400 == 0)
-```
-
-### ねねっちがMinifyしたコード
-
-```cpp
-if(y%25>0>y%4|y%16<1) // 21字
-```
-
-### リプライで更にMinifyされたコード
-
-<blockquote class="twitter-tweet" data-lang="en"><p lang="ja" dir="ltr">なるっち「短くしたいの?」カタカタ<br><br>if(!(y%25?y%4:y%16))<br><br>なるっち「論理逆にしてもいい?」カタカタ<br><br>if(y%25?y%4:y%16)</p>&mdash; fujita nozomu (@fujitanozomu) <a href="https://twitter.com/fujitanozomu/status/881406122556497924?ref_src=twsrc%5Etfw">July 2, 2017</a></blockquote>
-
-```cpp
-if(!(y%25?y%4:y%16)) // 20字
-```
-
-### 上のコードはカッコでくくれば少し小さくなりませんでした
-
-```js
-if(!(y%(y%25?4:16))) // 20字
-```
-
-### エアコンのない暑苦しい部屋でおかしくなった頭の産物
-
-ビット演算すれば1文字ぐらい削れるかなと思ったけど結局無理だった。
-
-
-```js
-if(!(y&(y%25?3:15))) // 20字
-```
-
-## コードの構造
-
-読めない人向けに雑な説明をば。
-
-### `y%25>0>y%4`の意味
-
-<blockquote class="twitter-tweet" data-lang="en"><p lang="ja" dir="ltr">うみこ「なるほど...C/C++では比較演算の結果が0/1になることと演算子の優先順位を利用してるんですね」(低音) <a href="https://t.co/yf3PeQ2rpi">pic.twitter.com/yf3PeQ2rpi</a></p>&mdash; とさか2 (@nanTosaka2) <a href="https://twitter.com/nanTosaka2/status/881134825389699074?ref_src=twsrc%5Etfw">July 1, 2017</a></blockquote>
-<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
-
-これはツイ主さんの説明が全てを語ってくれていますが一応。
-
-`y%25>0>y%4`は`(y%25 > 0) > y%4`のような順番で計算されるので、一見`(boolean) > y%4`といった式になって計算できないように見えますが、`true`は0b1、`false`は0b0と見ることもできるため、それぞれ`y%25`が0より大きければ`1 > y%4`、そうでなければ`0 > y%4`という式になります。
-
-
-### `==`がコード上に登場しない理由
-
-上の逆ですね。
-
-```cpp
-if (0) {
- // 到達しない
-}
-```
-
-```cpp
-if (1) {
- // 到達する
-}
-```
-
-```cpp
-if (1990000000) {
- // 到達する
-}
-```
-
-となります。
-
-### 定義に存在しない数字 `25` の出処
-
-これはねねっちがMinifyしたコードの
-
-```cpp
-if(y%25>0>y%4|y%16<1)
-```
-
-にて既出ですね。
-定義上では*400で割り切れないが、100で割り切れるなら、その年は閏年ではない*ので、100の倍数を別判定に弾き出せる`25`(=`100/4`)が登場しました。
-
-### 定義に存在しない数字 `3` `15` の出処
-
-これは最終的に至った
-
-```js
-if(!(y&(y%25?3:15)))
-```
-
-が初登場です。`y%25`(`y`が`25`で割り切れるか否か)で分岐してそれぞれ`!(y&3)`、`!(y&15)`という使われ方をします。
-ちなみに`&`とは、ビット演算子の一つであるANDです。
-これらはそれぞれ`0b11`、`0b1111`に相当し、
-
-```
- 0b10101010 (= 170) 0b11001100 (= 204)
-& 0b00000011 (= 3) & 0b00001111 (= 15)
------------- ------------
- 0b00000010 (= 2) 0b00001100 (= 12)
-```
-
-といった感じに除数が2<sup>n</sup>(nは自然数)の剰余演算を行うことができます。
-(ここで1文字ぐらい削れないかなと思ったけど無理だった)
-
-## Minifyして得られる物
-
-<dl>
-<dt>当然コード量が減るので、JavaScriptなどではトラフィック量の削減に繋がります。</dt>
-<dd>→まあこんなところをケチってるよりはもっと別の大きなところを先にケチったほうがいいと思いますが。</dd>
-</dl>
-
-<dl>
-<dt>当然コード量が減るので、処理が簡素になり高速化・効率化されたりすることがあります。</dt>
-<dd>→当然そうならないこともあります。場合によってはMinifyのために産業廃棄物を掘り起こしているかもしれません。</dd>
-</dl>
-
-<dl>
-<dt>当然コード量が減るので、純粋にコードを読む量が減り全体的な可読性の向上が見込めます。</dt>
-<dd>→大抵の場合読みやすいコードは生まれません。チームが全員プロでない限りは推奨できません。</dd>
-</dl>
-
-~~結論:そんなものはない~~
-
-## あとがき
-
-<!--
-~~死にそうなので誰かエアコンください~~と思ったけど
--->
-
-夜は涼し
-
-<!--
-いわ
--->
-
-くて快適ですね……
+`@see <https://qiita.com/1ed873c7e9a8edd9c695d2fa438cc1ed/items/370d3c8a8027d973fd42/revisions/6>`

ログインして続ける

ソーシャルアカウントでログイン・新規登録

メールアドレスでログイン・新規登録