好恶心的大模拟,但是用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
原文:https://www.cnblogs.com/shanxieng/p/13967246.html