閏年判定ワンライナー

久々のワンライナーネタ。
http://d.hatena.ne.jp/minsaa/20090406/1238987334を読んでて思いついたので。
以下、グレゴリオ暦を使うという前提で。


条件分岐を連ねるならPerlでは三項演算子かな?閏年のときだけ1を返すようにしてみた。

perl -le 'print +($_=pop) % 4 ? 0 : $_ % 100 ? 1 : $_ % 400 ? 0 : 1'

入力の受け方によっては

perl -lne 'print $_ % 4 ? 0 : $_ % 100 ? 1 : $_ % 400 ? 0 : 1'

とか。


実行例:

$ perl -le 'print +($_=pop) % 4 ? 0 : $_ % 100 ? 1 : $_ % 400 ? 0 : 1' 2008
1
$ perl -le 'print +($_=pop) % 4 ? 0 : $_ % 100 ? 1 : $_ % 400 ? 0 : 1' 2009
0
$ echo 2008 | perl -lne 'print $_ % 4 ? 0 : $_ % 100 ? 1 : $_ % 400 ? 0 : 1'
1
$ echo 2009 | perl -lne 'print $_ % 4 ? 0 : $_ % 100 ? 1 : $_ % 400 ? 0 : 1'
0
$ jot 2009 | perl -lne 'print $_,$",$_ % 4 ? 0 : $_ % 100 ? 1 : $_ % 400 ? 0 : 1'
1 0
2 0
3 0
4 1
5 0
6 0
7 0
8 1
9 0
...
1998 0
1999 0
2000 1
2001 0
2002 0
2003 0
2004 1
2005 0
2006 0
2007 0
2008 1
2009 0


確かめるには400年に97回の閏年が現れることを確認する。
閏年 - Wikipedia

$ jot 400 | perl -lne 'print $_ % 4 ? 0 : $_ % 100 ? 1 : $_ % 400 ? 0 : 1' | grep 1 | wc -l
      97

大丈夫そう。


ちなみに予想通りCPANモジュールも用意されていたw
Date::Leapyear - search.cpan.org

perl -MDate::Leapyear -lne 'print isleap($_) ? 1 : 0'
$ jot 400 | perl -MDate::Leapyear -lne 'print isleap($_) ? 1 : 0' | grep 1 | wc -l
      97

追記

別に無理して三項演算子つかわなくても普通の条件文の組み合わせでやった方が短いな、と後になって気付いた。

perl -lne 'print $_ % 4 || !($_ % 100) && $_ % 400 ? 0 : 1'