LL Golf Hole 3 - 13日の金曜日を数え上げる
Posted feedbacks - Haskell
愚直なつくりをしています。 *Main> :main (10,[2009-02-13,2009-03-13,2009-11-13,2010-08-13,2011-05-13,2012-01-13,2012-04-13,2012-07-13,2013-09-13,2013-12-13])
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | module Main where
import Data.Time
import Data.Time.Calendar.WeekDate
import Control.Arrow
getCurrentZonedTime :: a -> IO ZonedTime
getCurrentZonedTime = (const getCurrentTimeZone &&& const getCurrentTime)
>>> joinTuple
>>> (=<<) (return . uncurry utcToZonedTime)
where joinTuple :: Monad m => (m a, m b) -> m (a, b)
joinTuple (x,y) = do { x' <- x; y' <- y; return (x',y') }
check :: Day -> Bool
check day = thirteen && friday
where thirteen = "31" == (take 2 $ reverse $ show day)
friday = case toWeekDate day of (_,_,5) -> True; _ -> False
friday13s lst = Kleisli getCurrentZonedTime
>>> arr (localDay . zonedTimeToLocalTime)
>>> arr (flip enumFromTo lst)
>>> arr (filter check)
>>> arr (length &&& id) >>> Kleisli print
main = runKleisli (friday13s (read "2013-12-31")) ()
|
方法は、各年の全月の13日が金曜日か調べるだけです。 が、目的の日付の曜日を調べる手軽な手段を見つけられなかったので、 ClockTime と CalendarTime を相互変換して、 曜日を得るために addToClockTime すると言う、なんか変な事になっています。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | module Main (main) where
import Time
import Control.Monad
import System.IO.Unsafe
crossProduct :: [a] -> [b]-> [(a,b)]
crossProduct = liftM2 p
where
p x y = (x,y)
isJason :: (Int,Int) -> Bool
isJason (year,month) = week == Friday
where
mon = toEnum (month-1) :: Month
clock = toClockTime $ CalendarTime year mon 13 0 0 0 0 Sunday 0 "JST" 9 False
time = addToClockTime (TimeDiff 0 0 0 0 0 0 0) clock
week = ctWDay $ unsafePerformIO $ toCalendarTime time
isAfter :: CalendarTime -> (Int,Int) -> Bool
isAfter cal (year,month) =
year > ctYear cal || month > (fromEnum $ ctMonth cal) || 13 <= ctDay cal
main :: IO ()
main = do
time <- getClockTime
cal <- toCalendarTime time
putStrLn $ show $
filter (isAfter cal) $
filter (isJason) $ crossProduct [(ctYear cal)..2013] [1..12]
|
今日の日付の取得の仕方があやしいです。
1 2 3 4 5 6 7 8 9 10 11 12 13 | import Data.Time
import Data.Time.Calendar.OrdinalDate
isFriday d =
case sundayStartWeek d of
(_, 5) -> True
otherwise -> False
main = do
today <- getZonedTime >>= \ zt -> (return.localDay.zonedTimeToLocalTime) zt
let fridays = filter isFriday $ filter (today <=) [fromGregorian y m 13 | y <- [2008..2013], m <-[1..12]]
mapM_ (putStrLn.show) fridays
putStrLn $ (show $ length fridays) ++ " days"
|
あまり無駄にArrowを使わないで欲しいです…
1 | getCurrentZonedTime = liftM2 utcToZonedTime getCurrentTimeZone getCurrentTime
|





takano32
#6985()
[
Ruby
]
Rating4/8=0.50
今日から2013年12月31日までの、13日の金曜日とその総数を表示してください。
余力のあるものはこのプログラムを短くしてみたり、短くしてみたり、短くしてください。
※LL Future実行委員の高野光弘です。この出題は LL Future公式の出題であり、優れたものについてはLL Golfのセッションでご紹介させていただくかもしれません。ご理解の上、ご投稿ください。また、LL Futureのチケットは現在も発売中です。よろしければ、メインイベントの方にもぜひご参加ください。
see: DateTime - Rubyリファレンスマニュアル
Rating4/8=0.50-0+
[ reply ]