首页 > 其他 > 详细

CSP2020 haskell题解

时间:2020-11-13 09:20:24      阅读:21      评论:0      收藏:0      [点我收藏+]

儒略历

好恶心的大模拟,但是用haskell还是简单了一点(并没有)

首先判断是否在1583.10.15日前,然后将时间进到1600.1.1。

往前跳的时候先以400年为周期跳,然后是100年,4年。

import Data.Char

main = do
    n <- readInt
    work n
    return ()

work :: Int -> IO()
work 0 = return ()
work n = do
    x <- readInt
    solve x
    work (n - 1)
    return ()

solve :: Int -> IO()
solve n =
    if n < 2299161 then
        printans (solve1 n)
    else
        printans (solve2 (n - 2299161))

printans :: (Int, Int, Int) -> IO()
printans (d, m, y) = do
    if y > 0 then
        putStrLn (show d ++ ‘ ‘ : show m ++ ‘ ‘ : show y)
    else
        putStrLn (show d ++ ‘ ‘ : show m ++ ‘ ‘ : show (1 - y) ++ " BC")

days :: [Int]
days = [31,28,31,30,31,30,31,31,30,31,30,31]

days‘ :: [Int]
days‘ = [31,29,31,30,31,30,31,31,30,31,30,31]

solve1 :: Int -> (Int, Int, Int)
solve1 n = let y1 = -4712 + 4 * (n `div` (3 * 365 + 366)) ; x = n `mod` (3 * 365 + 366) in
    fun1 x y1

solve2 :: Int -> (Int, Int, Int)
solve2 n = if n <= 16 then (15 + n, 10, 1582)
    else if n < 47 then (n - 16, 11, 1582)
    else if n < 78 then (n - 46, 12, 1582)
    else let n2 = n - 78 in
        if n2 < 6209 then
            let y1 = 1583 + 4 * (n2 `div` (3 * 365 + 366)) ; n3 = n2 `mod` (3 *365 + 366) in
                if n3 >= 365 then
                    if n3 >= 366 + 365 then
                        if n3 >= 365 * 2 + 366 then getmd days (n3 - 365 - 366 - 365) (y1 + 3) 1
                        else getmd days (n3 - 365 - 366) (y1 + 2) 1
                    else getmd days‘ (n3 - 365) (y1 + 1) 1
                else getmd days n3 y1 1
        else
            let n4 = (n2 - 6209) `mod` (303 * 365 + 97 * 366) ; y2 = 1600 + 400 * ((n2 - 6209) `div` (303 * 365 + 97 * 366)) in
                if n4 >= (75 * 365 + 25 * 366) then
                    let y3 = y2 + 100 + 100 * ((n4 - 75 * 365 - 25 * 366) `div` (76 * 365 + 24 * 366)) ; n5 = (n4 - 75 * 365 - 25 * 366) `mod` (76 * 365 + 24 * 366) in
                        if n5 >= (365 * 4) then
                            fun2 (n5 - 365 * 4) (y3 + 4)
                        else getmd days (n5 `mod` 365) (y3 + n5 `div` 365) 1
                else
                    fun2 n4 y2

fun1 :: Int -> Int -> (Int, Int, Int)
fun1 x y =
    if x >= 366 then
        let y2 = y + 1 + ((x - 366) `div` 365) ; n = (x - 366) `mod` 365 in
            getmd days n y2 1
    else getmd days‘ x y 1

fun2 :: Int -> Int -> (Int, Int, Int)
fun2 x y = let y2 = y + 4 * (x `div` (3 * 365 + 366)) ; n = x `mod` (3 * 365 + 366) in
    fun1 n y2

getmd :: [Int] -> Int -> Int -> Int -> (Int, Int, Int)
getmd (d:ds) x y m = if x >= d then getmd ds (x - d) y (m + 1)
    else (x + 1, m, y)

readInt :: IO Int
readInt = do
    ch <- getChar
    if isDigit ch then
        f (ord ch - ord ‘0‘)
    else if ch == ‘-‘ then
        fmap (*(-1)) readInt
    else readInt
    where
        f ans = do
            ch <- getChar
            if isDigit ch then
                f (ans * 10 + ord ch - ord ‘0‘)
            else
                return ans

CSP2020 haskell题解

原文:https://www.cnblogs.com/shanxieng/p/13967246.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!