challenge 除算・余剰を使わずに閏年

ある西暦が閏年か否かを判定するプログラムを書いてください。 ただし、除算・余剰を求める演算子、組み込み関数、ライブラリ関数等を使用してはいけません。 また、閏年は以下のように定義されています。 1. 西暦年が4で割り切れる年は閏年 2. ただし、西暦年が100で割り切れる年は平年 3. ただし、西暦年が400で割り切れる年は閏年

Posted feedbacks - Haskell

無限リストつかいます。

実行例:
*Main> :main 1900
False
*Main> :main 2000
True
*Main> :main 2008
True
*Main> :main 2100
False

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
module Main (main) where

import System.Environment

main :: IO ()
main = print . (ys !!) . read . head =<< getArgs

y4s = [True,False,False,False]
y100s = False : tail (take 100 $ cycle y4s)
y400s = True : tail (take 400 $ cycle y100s)

ys = cycle y400s

それぞれの条件を無限リストにした。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
isLeapYear x = d !! x
    where a = cycle $ True  : replicate 3   False
          b = cycle $ False : replicate 99  True
          c = cycle $ True  : replicate 399 False
          d = zipWith3 (\a b c -> (a && b) || c) a b c

main = do putStr ">> "
          l <- getLine
          print $ isLeapYear $ read l
          main

400(= 2^4 * 5^2) の倍数

⇔ 100(= 2^2 * 5^2) の倍数かつ 16(=2^4) の倍数

ですね。なるほど、賢い。

1
2
3
4
5
6
import Data.Bits
leapYear :: Int -> Bool
leapYear year =
    case reverse $ show $ year of
      '0':'0':_ -> year .&. 0x0f == 0
      _ -> year .&. 0x03 == 0

Index

Feed

Other

Link

Pathtraq

loading...