diff --git a/Euler.hs b/Euler.hs index 21352a9..13236fa 100644 --- a/Euler.hs +++ b/Euler.hs @@ -7,6 +7,7 @@ module Euler , primes , zipArraysWith , RangeIx(..) + , digitsOf ) where import Control.Applicative @@ -49,3 +50,6 @@ zipArraysWith :: (IArray arrA a, IArray arrB b, IArray arrC c, RangeIx i) => (a -> b -> c) -> arrA i a -> arrB i b -> arrC i c zipArraysWith f as bs = array newRange $ [ (i, f (as!i) (bs!i)) | i <- range newRange ] where newRange = intersectBounds (bounds as) (bounds bs) + +digitsOf :: (Read a, Show a, Integral a) => a -> [a] +digitsOf = map (read . (:[])) . show diff --git a/Problem19.hs b/Problem19.hs new file mode 100644 index 0000000..3997bcd --- /dev/null +++ b/Problem19.hs @@ -0,0 +1,27 @@ +import Data.Monoid + +data Month = Jan | Feb | Mar | Apr | May | Jun | Jul | Aug | Sep | Oct | Nov | Dec deriving (Eq,Ord,Enum,Bounded,Show) +data Day = Sun | Mon | Tue | Wed | Thu | Fri | Sat deriving (Eq,Ord,Enum,Bounded,Show) +type Year = Int + +leapYear yr = yr `mod` 400 == 0 || (yr `mod` 4 == 0 && yr `mod` 100 /= 0) + +daysInMonth :: (Month, Year) -> Int +daysInMonth (mn, yr) + | mn `elem` [ Sep, Apr, Jun, Nov ] = 30 + | mn == Feb = if leapYear yr then 29 else 28 + | otherwise = 31 + +nextMonth (Dec, yr) = (Jan, yr + 1) +nextMonth (mn, yr) = (succ mn, yr) + +compareMonths (m1,y1) (m2,y2) = compare y1 y2 <> compare m1 m2 + +addDays d n = toEnum $ (fromEnum d + n) `mod` 7 + +startDay = ((Jan, 1900), Mon) : [ (nextMonth m, addDays d n) | (m, d) <- startDay, let n = daysInMonth m ] + +main = print $ length $ filter ((== Sun) . snd) $ + takeWhile (\(m,_) -> m `compareMonths` (Dec, 2000) /= GT) $ + dropWhile (\(m,_) -> m `compareMonths` (Jan, 1901) == LT) $ + startDay diff --git a/Problem20.hs b/Problem20.hs new file mode 100644 index 0000000..b1cad21 --- /dev/null +++ b/Problem20.hs @@ -0,0 +1,2 @@ +import Euler +main = print $ sum $ digitsOf $ product [1..100]