diff options
| author | Charles <sircharlesaze@gmail.com> | 2019-09-05 02:40:30 +0200 |
|---|---|---|
| committer | Charles <sircharlesaze@gmail.com> | 2019-09-05 02:40:30 +0200 |
| commit | 87f0a52d00b38198bbfa36b5febb257078080d6e (patch) | |
| tree | 1ac2375d5fe33184c7b34ac8316e6d427e3d8412 /haskell | |
| parent | e552bfe30c1640ed106a8dd95c3b0cbfbd3d5060 (diff) | |
| download | project_euler-87f0a52d00b38198bbfa36b5febb257078080d6e.tar.gz project_euler-87f0a52d00b38198bbfa36b5febb257078080d6e.tar.bz2 project_euler-87f0a52d00b38198bbfa36b5febb257078080d6e.zip | |
problem 099 haskell, wip 058
Diffstat (limited to 'haskell')
| -rw-r--r-- | haskell/099-largest_exponential.hs | 30 | ||||
| -rw-r--r-- | haskell/wip/058-spiral_primes.hs | 56 |
2 files changed, 86 insertions, 0 deletions
diff --git a/haskell/099-largest_exponential.hs b/haskell/099-largest_exponential.hs new file mode 100644 index 0000000..68fcc00 --- /dev/null +++ b/haskell/099-largest_exponential.hs @@ -0,0 +1,30 @@ +------ +-- Largest exponential +-- Problem 99 +-- +-- Comparing two numbers written in index form like 211 and 37 is not difficult, +-- as any calculator would confirm that 211 = 2048 < 37 = 2187. +-- However, confirming that 632382518061 > 519432525806 would be much more difficult, +-- as both numbers contain over three million digits. +-- Using base_exp.txt (right click and 'Save Link/Target As...'), a 22K text file +-- containing one thousand lines with a base/exponent pair on each line, determine which +-- line number has the greatest numerical value. +-- NOTE: The first two lines in the file represent the numbers in the example given above. +------ + + +import Data.List(elemIndex, maximumBy) +import Data.Maybe(fromJust) + +main = do + content <- readFile "../data/099_base_exp.txt" + let base_exp = map (map (\s -> read s :: Integer) . split ',') $ lines content + print (fst $ maximumBy (\(i, be1) (j, be2) -> compare be1 be2) + $ map (\(i, be) -> (i, head be ^ last be)) $ zip [1..] base_exp) + +split :: Eq a => a -> [a] -> [[a]] +split _ [] = [[]] +split delim str = + let (before, remainder) = span (/= delim) str + in before : case remainder of [] -> [] + x -> split delim $ tail x diff --git a/haskell/wip/058-spiral_primes.hs b/haskell/wip/058-spiral_primes.hs new file mode 100644 index 0000000..3c620ec --- /dev/null +++ b/haskell/wip/058-spiral_primes.hs @@ -0,0 +1,56 @@ +------ +-- Spiral primes +-- Problem 58 +-- +-- Starting with 1 and spiralling anticlockwise in the following way, +-- a square spiral with side length 7 is formed. +-- +-- 37 36 35 34 33 32 31 +-- 38 17 16 15 14 13 30 +-- 39 18 5 4 3 12 29 +-- 40 19 6 1 2 11 28 +-- 41 20 7 8 9 10 27 +-- 42 21 22 23 24 25 26 +-- 43 44 45 46 47 48 49 +-- +-- It is interesting to note that the odd squares lie along the bottom right diagonal, +-- but what is more interesting is that 8 out of the 13 numbers lying along both diagonals +-- are prime; that is, a ratio of 8/13 ≈ 62%. +-- If one complete new layer is wrapped around the spiral above, a square spiral +-- with side length 9 will be formed. If this process is continued, what is the side +-- length of the square spiral for which the ratio of primes along both diagonals +-- first falls below 10%? +------ + + +main = do + print $ firstDropBellow 0.1 3 0 + +firstDropBellow :: Double -> Int -> Int -> (Int, Int, Double) +firstDropBellow percent counter n + | primesRatio < percent = (n, 2 * n + 1, primesRatio) + | otherwise = firstDropBellow percent (counter + countPrimes) (n + 1) + where primesRatio = (fromIntegral countPrimes + fromIntegral counter) + / fromIntegral (4 * n + 1) + countPrimes = length $ filter id (map isPrime corners) + corners = [dur, ddl, dul] + dur = 4 * n ^ 2 - 2 * n + 1 + ddl = 4 * n ^ 2 + 2 * n + 1 + dul = 4 * n ^ 2 + 1 + +isPrime :: Int -> Bool +isPrime 2 = True +isPrime 3 = True +isPrime x + | x < 2 = False + | x `mod` 2 == 0 || x `mod` 3 == 0 = False + | otherwise = divCheck 5 + where divCheck d + | d * d > x = True + | x `mod` d == 0 || x `mod` (d + 2) == 0 = False + | otherwise = divCheck (d + 6) + +-- diagUpRight = [4 * x ^ 2 - 2 * x + 1 | x <- [1..]] +-- diagdownLeft = [4 * x ^ 2 + 2 * x + 1 | x <- [1..]] +-- diagUpLeft = [4 * x ^ 2 + 1 | x <- [1..]] +-- diags = [diagUpRight, diagdownLeft, diagUpLeft] |
