haskell 基礎題解(56)

2021-09-26 21:19:19 字數 2288 閱讀 2705

【題目】給定年份,月份,在控制台輸出該月的月曆

比如,2023年9月的月曆:

很明顯,這個問題的要點是:對給定的年、月,需要知道這個月有多少天,還需要知道它的1號是星期幾。

可以參考以前關於日期問題的演算法。

---

-判斷某個年份是否為閏年

b閏年 :

:int

-> bool

b閏年 year | year `mod` 400==

0= true

| year `mod` 100==

0= false

| year `mod` 4==

0= true

| otherwise = false--

--從公元2023年1月開始,逐月的天數無限表

monthdays :

: [int]

monthdays = concat [ [31

,f x,31,

30,31,

30,31,

31,30,

31,30,

31] | x<

-[1900..] ]

where f x =

if b閏年 x then

29else28-

---從2023年1月1日 到 y年m月之前過去的天數

days :

:int

->

int-

>

intdays y m =

let n =

(y-1900)*

12+ m -

1in sum $ take n monthdays--

-已知2023年1月1日是星期1,求之後的 y年 m月 1日是星期幾

monthweek :

:int

->

int-

>

intmonthweek y m = days y m `mod` 7--

-單行按每行n個元素折成多行

foldline :

:int

-> [a] -

> [[a]]

foldline n xs

| length xs <= n = [xs]

| otherwise = take n xs : foldline n (drop n xs)--

-把乙個串前邊添空格,補到指定的長度為止

fillspace :

:int

->

string

->

string

fillspace n s

| length s >= n = s

| otherwise = ' ' : fillspace (n-

1) s--

--已知 y年 m月,求當月的月曆表

calendar :

:int

->

int-

> [string]

calendar y m =

let passmon =

(y-1900)*

12+ m -

1 thismon = monthdays !! passmon

weekbegin = monthweek y m

t = replicate weekbegin " "

++ map show [1..thismon]

t2 = foldline 7 t

t3 = map (map (fillspace 2

)) t2

t4 = map unwords t3

in"mo tu we th fr sa su"

: t4

main :

: io (

)main = putstr $ unlines $ calendar 2019

9

這裡算日期的基點取了 2023年1月1日,而不是公元元年。

星期的說法本就是後來的事。用今天的星期推公元元年星期是不准的。原因複雜。

我們現行的曆法是:格里高利教皇曆法。

2023年9月,英國議會決定把原來的愷撒曆法改為現行的格里高利曆法(200多年前就修定好了,卻沒人執行),因為這兩個曆法當前日期差11天,議會決定當年9月3日到到9月13日刪去。也就是說9月2日後,直接是9月14日。

所以在日期轉換,算星期等問題上,如果日期在2023年9月之前,要小心處理了。

haskell 基礎題解(06)

題目 如果乙個數的所有真因子 不包含它自身的因子 之和恰等於其自身,則該數為完全數,也稱為完美數 perfect number 完全數有許多奇妙的性質。但它們很稀少,你來求前幾個吧。最小的乙個是 6,因為 6 1 2 3 這個完全數的定義已經很清楚了,如果沒有什麼妙法,就地毯式搜尋也可以。下法就是 ...

haskell 基礎題解(07)

題目 11 1 1 2 1 1 3 3 1 1 4 6 4 1 這個陣勢叫楊輝三角,國外叫帕斯卡三角。前一行的數字中,每兩個相鄰的數字相加就得到下一行的數字。左右兩邊的數永遠是 1 寫個程式,輸出前幾行的楊輝三角。import data.list intersperse yang hui int y...

haskell基礎題解(14)

題目 用自然數蛇形填充乙個 n 階的方陣。當n 5時,形如 這個問題用 haskell 解決時與 題目13 差別甚微。實際上,從函式式的思考習慣看,只要讓有些行作成後反轉一下就可以了。上 ju n f x x 0.n 1 where f row even row take n row n 1.odd...