aboutsummaryrefslogtreecommitdiff
path: root/haskell
diff options
context:
space:
mode:
authorCharles <sircharlesaze@gmail.com>2019-09-05 02:40:30 +0200
committerCharles <sircharlesaze@gmail.com>2019-09-05 02:40:30 +0200
commit87f0a52d00b38198bbfa36b5febb257078080d6e (patch)
tree1ac2375d5fe33184c7b34ac8316e6d427e3d8412 /haskell
parente552bfe30c1640ed106a8dd95c3b0cbfbd3d5060 (diff)
downloadproject_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.hs30
-rw-r--r--haskell/wip/058-spiral_primes.hs56
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]