Compare commits
11 Commits
a0fef78e65
...
8f5004d6ff
Author | SHA1 | Date |
---|---|---|
Bill Ewanick | 8f5004d6ff | |
Bill Ewanick | 38ba59c3e4 | |
Bill Ewanick | 7590b3c192 | |
Bill Ewanick | 9bf9588724 | |
Bill Ewanick | 83ff425eb4 | |
Bill Ewanick | 1b689521c1 | |
Bill Ewanick | bd0b941a6a | |
Bill Ewanick | 8eb0cec5e0 | |
Bill Ewanick | a1e47d4d32 | |
Bill Ewanick | f5fa301f71 | |
Bill Ewanick | 9db5fd08e6 |
|
@ -0,0 +1,7 @@
|
||||||
|
{
|
||||||
|
"cSpell.words": [
|
||||||
|
"concat",
|
||||||
|
"coprime",
|
||||||
|
"foldl"
|
||||||
|
]
|
||||||
|
}
|
|
@ -45,6 +45,14 @@
|
||||||
aeson
|
aeson
|
||||||
random
|
random
|
||||||
neat-interpolation
|
neat-interpolation
|
||||||
|
|
||||||
|
# maths
|
||||||
|
primes
|
||||||
|
arithmoi
|
||||||
|
|
||||||
|
# graphing libraries!
|
||||||
|
Chart
|
||||||
|
Chart-cairo
|
||||||
]
|
]
|
||||||
);
|
);
|
||||||
in
|
in
|
||||||
|
|
|
@ -0,0 +1,121 @@
|
||||||
|
{-
|
||||||
|
Summation of Primes
|
||||||
|
Problem 10
|
||||||
|
|
||||||
|
The sum of the primes below 10 is 2 + 3 + 5 + 7 = 17.
|
||||||
|
|
||||||
|
Find the sum of all the primes below two million.
|
||||||
|
|
||||||
|
|
||||||
|
https://wiki.haskell.org/Prime_numbers
|
||||||
|
|
||||||
|
Compile with `ghc -O3 src/projectEuler/question10.hs`
|
||||||
|
Run with `time src/projectEuler/question10`
|
||||||
|
-}
|
||||||
|
{-# OPTIONS_GHC -O2 #-}
|
||||||
|
|
||||||
|
import Control.Monad (forM_, when)
|
||||||
|
import Data.Array.Base (IArray (unsafeAt),
|
||||||
|
MArray (unsafeWrite),
|
||||||
|
UArray (UArray),
|
||||||
|
unsafeFreezeSTUArray)
|
||||||
|
import Data.Array.ST (MArray (newArray), readArray,
|
||||||
|
runSTUArray, writeArray)
|
||||||
|
import Data.Array.Unboxed (UArray, assocs)
|
||||||
|
import Data.Bits (Bits (shiftL, shiftR))
|
||||||
|
import Data.Int (Int64)
|
||||||
|
import Data.List (genericIndex, genericTake)
|
||||||
|
import Data.Word (Word64)
|
||||||
|
-- https://hackage.haskell.org/package/arithmoi-0.13.0.0
|
||||||
|
import Math.NumberTheory.Primes (Prime (unPrime), primes)
|
||||||
|
|
||||||
|
main :: IO ()
|
||||||
|
main = do
|
||||||
|
print "Hello! Welcome to the prime number generator."
|
||||||
|
-- print "Please enter which nth prime you'd like: "
|
||||||
|
-- n <- getLine
|
||||||
|
-- let n' = read n :: Integer
|
||||||
|
-- print $ "Finding the " ++ n ++ "th prime."
|
||||||
|
-- print $ primes() `genericIndex` (10^ (10 :: Int))
|
||||||
|
print $ last $ take (10^ (10 :: Int)) primes
|
||||||
|
|
||||||
|
ans :: Integer
|
||||||
|
ans = sum $ takeWhile (< 2_000_000) $ map unPrime primes
|
||||||
|
|
||||||
|
|
||||||
|
primes1 :: [Integer]
|
||||||
|
primes1 = sieve [2..]
|
||||||
|
where
|
||||||
|
sieve (p : xs) = p : sieve [x | x <- xs, x `mod` p > 0]
|
||||||
|
|
||||||
|
primes2 :: [Integer]
|
||||||
|
primes2 = 2:([3..] `minus` composites)
|
||||||
|
where
|
||||||
|
composites = union [multiples p | p <- primes2]
|
||||||
|
|
||||||
|
multiples n = map (n*) [n..]
|
||||||
|
|
||||||
|
(x:xs) `minus` (y:ys) | x < y = x:(xs `minus` (y:ys))
|
||||||
|
| x == y = xs `minus` ys
|
||||||
|
| x > y = (x:xs) `minus` ys
|
||||||
|
union = foldr merge [ ]
|
||||||
|
where
|
||||||
|
merge (x:xs) ys = x:merge' xs ys
|
||||||
|
merge' (x:xs) (y:ys) | x < y = x:merge' xs (y:ys)
|
||||||
|
| x == y = x:merge' xs ys
|
||||||
|
| x > y = y:merge' (x:xs) ys
|
||||||
|
|
||||||
|
|
||||||
|
{-
|
||||||
|
https://wiki.haskell.org/Prime_numbers
|
||||||
|
Using Page-Segmented ST-Mutable Unboxed Array
|
||||||
|
-}
|
||||||
|
-- type Prime = Word64
|
||||||
|
|
||||||
|
-- cSieveBufferLimit :: Int
|
||||||
|
-- cSieveBufferLimit = 2^17 * 8 - 1 -- CPU L2 cache in bits
|
||||||
|
|
||||||
|
-- primes :: () -> [Prime]
|
||||||
|
-- primes() = 2 : _Y (listPagePrms . pagesFrom 0) where
|
||||||
|
-- _Y g = g (_Y g) -- non-sharing multi-stage fixpoint combinator
|
||||||
|
-- listPagePrms pgs@(hdpg@(UArray lwi _ rng _) : tlpgs) =
|
||||||
|
-- let loop i | i >= fromIntegral rng = listPagePrms tlpgs
|
||||||
|
-- | unsafeAt hdpg i = loop (i + 1)
|
||||||
|
-- | otherwise = let ii = lwi + fromIntegral i in
|
||||||
|
-- case fromIntegral $ 3 + ii + ii of
|
||||||
|
-- p -> p `seq` p : loop (i + 1) in loop 0
|
||||||
|
-- makePg lwi bps = runSTUArray $ do
|
||||||
|
-- let limi = lwi + fromIntegral cSieveBufferLimit
|
||||||
|
-- bplmt = floor $ sqrt $ fromIntegral $ limi + limi + 3
|
||||||
|
-- strta bp = let si = fromIntegral $ (bp * bp - 3) `shiftR` 1
|
||||||
|
-- in if si >= lwi then fromIntegral $ si - lwi else
|
||||||
|
-- let r = fromIntegral (lwi - si) `mod` bp
|
||||||
|
-- in if r == 0 then 0 else fromIntegral $ bp - r
|
||||||
|
-- cmpsts <- newArray (lwi, limi) False
|
||||||
|
-- fcmpsts <- unsafeFreezeSTUArray cmpsts
|
||||||
|
-- let cbps = if lwi == 0 then listPagePrms [fcmpsts] else bps
|
||||||
|
-- forM_ (takeWhile (<= bplmt) cbps) $ \ bp ->
|
||||||
|
-- forM_ (let sp = fromIntegral $ strta bp
|
||||||
|
-- in [ sp, sp + fromIntegral bp .. cSieveBufferLimit ]) $ \c ->
|
||||||
|
-- unsafeWrite cmpsts c True
|
||||||
|
-- return cmpsts
|
||||||
|
-- pagesFrom lwi bps = map (`makePg` bps)
|
||||||
|
-- [ lwi, lwi + fromIntegral cSieveBufferLimit + 1 .. ]
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
-- sieveUA :: Int -> UArray Int Bool
|
||||||
|
-- sieveUA top = runSTUArray $ do
|
||||||
|
-- let m = (top-1) `div` 2
|
||||||
|
-- r = floor . sqrt $ fromIntegral top + 1
|
||||||
|
-- sieve <- newArray (1,m) True -- :: ST s (STUArray s Int Bool)
|
||||||
|
-- forM_ [1..r `div` 2] $ \i -> do
|
||||||
|
-- isPrime <- readArray sieve i
|
||||||
|
-- when isPrime $ do -- ((2*i+1)^2-1)`div`2 == 2*i*(i+1)
|
||||||
|
-- forM_ [2*i*(i+1), 2*i*(i+2)+1..m] $ \j -> do
|
||||||
|
-- writeArray sieve j False
|
||||||
|
-- return sieve
|
||||||
|
|
||||||
|
-- primesToUA :: Int -> [Int]
|
||||||
|
-- primesToUA top = 2 : [i*2+1 | (i,True) <- assocs $ sieveUA top]
|
|
@ -0,0 +1,110 @@
|
||||||
|
{-
|
||||||
|
In the 20x20 grid below, four numbers along a diagonal line have been marked in *red*.
|
||||||
|
|
||||||
|
08 02 22 97 38 15 00 40 00 75 04 05 07 78 52 12 50 77 91 08
|
||||||
|
49 49 99 40 17 81 18 57 60 87 17 40 98 43 69 48 04 56 62 00
|
||||||
|
81 49 31 73 55 79 14 29 93 71 40 67 53 88 30 03 49 13 36 65
|
||||||
|
52 70 95 23 04 60 11 42 69 24 68 56 01 32 56 71 37 02 36 91
|
||||||
|
22 31 16 71 51 67 63 89 41 92 36 54 22 40 40 28 66 33 13 80
|
||||||
|
24 47 32 60 99 03 45 02 44 75 33 53 78 36 84 20 35 17 12 50
|
||||||
|
32 98 81 28 64 23 67 10*26*38 40 67 59 54 70 66 18 38 64 70
|
||||||
|
67 26 20 68 02 62 12 20 95*63*94 39 63 08 40 91 66 49 94 21
|
||||||
|
24 55 58 05 66 73 99 26 97 17*78*78 96 83 14 88 34 89 63 72
|
||||||
|
21 36 23 09 75 00 76 44 20 45 35*14*00 61 33 97 34 31 33 95
|
||||||
|
78 17 53 28 22 75 31 67 15 94 03 80 04 62 16 14 09 53 56 92
|
||||||
|
16 39 05 42 96 35 31 47 55 58 88 24 00 17 54 24 36 29 85 57
|
||||||
|
86 56 00 48 35 71 89 07 05 44 44 37 44 60 21 58 51 54 17 58
|
||||||
|
19 80 81 68 05 94 47 69 28 73 92 13 86 52 17 77 04 89 55 40
|
||||||
|
04 52 08 83 97 35 99 16 07 97 57 32 16 26 26 79 33 27 98 66
|
||||||
|
88 36 68 87 57 62 20 72 03 46 33 67 46 55 12 32 63 93 53 69
|
||||||
|
04 42 16 73 38 25 39 11 24 94 72 18 08 46 29 32 40 62 76 36
|
||||||
|
20 69 36 41 72 30 23 88 34 62 99 69 82 67 59 85 74 04 36 16
|
||||||
|
20 73 35 29 78 31 90 01 74 31 49 71 48 86 81 16 23 57 05 54
|
||||||
|
01 70 54 71 83 51 54 69 16 92 33 48 61 43 52 01 89 19 67 48
|
||||||
|
|
||||||
|
The product of these numbers is 26x63x78x14 = 1788696.
|
||||||
|
|
||||||
|
What is the greatest product of four adjacent numbers in the same direction (up, down, left, right, or diagonally) in the 20x20 grid?
|
||||||
|
-}
|
||||||
|
import Data.List (genericDrop, genericIndex, genericTake)
|
||||||
|
|
||||||
|
grid :: [[Integer]]
|
||||||
|
grid =
|
||||||
|
[ [08, 02, 22, 97, 38, 15, 00, 40, 00, 75, 04, 05, 07, 78, 52, 12, 50, 77, 91, 08]
|
||||||
|
, [49, 49, 99, 40, 17, 81, 18, 57, 60, 87, 17, 40, 98, 43, 69, 48, 04, 56, 62, 00]
|
||||||
|
, [81, 49, 31, 73, 55, 79, 14, 29, 93, 71, 40, 67, 53, 88, 30, 03, 49, 13, 36, 65]
|
||||||
|
, [52, 70, 95, 23, 04, 60, 11, 42, 69, 24, 68, 56, 01, 32, 56, 71, 37, 02, 36, 91]
|
||||||
|
, [22, 31, 16, 71, 51, 67, 63, 89, 41, 92, 36, 54, 22, 40, 40, 28, 66, 33, 13, 80]
|
||||||
|
, [24, 47, 32, 60, 99, 03, 45, 02, 44, 75, 33, 53, 78, 36, 84, 20, 35, 17, 12, 50]
|
||||||
|
, [32, 98, 81, 28, 64, 23, 67, 10, 26, 38, 40, 67, 59, 54, 70, 66, 18, 38, 64, 70]
|
||||||
|
, [67, 26, 20, 68, 02, 62, 12, 20, 95, 63, 94, 39, 63, 08, 40, 91, 66, 49, 94, 21]
|
||||||
|
, [24, 55, 58, 05, 66, 73, 99, 26, 97, 17, 78, 78, 96, 83, 14, 88, 34, 89, 63, 72]
|
||||||
|
, [21, 36, 23, 09, 75, 00, 76, 44, 20, 45, 35, 14, 00, 61, 33, 97, 34, 31, 33, 95]
|
||||||
|
, [78, 17, 53, 28, 22, 75, 31, 67, 15, 94, 03, 80, 04, 62, 16, 14, 09, 53, 56, 92]
|
||||||
|
, [16, 39, 05, 42, 96, 35, 31, 47, 55, 58, 88, 24, 00, 17, 54, 24, 36, 29, 85, 57]
|
||||||
|
, [86, 56, 00, 48, 35, 71, 89, 07, 05, 44, 44, 37, 44, 60, 21, 58, 51, 54, 17, 58]
|
||||||
|
, [19, 80, 81, 68, 05, 94, 47, 69, 28, 73, 92, 13, 86, 52, 17, 77, 04, 89, 55, 40]
|
||||||
|
, [04, 52, 08, 83, 97, 35, 99, 16, 07, 97, 57, 32, 16, 26, 26, 79, 33, 27, 98, 66]
|
||||||
|
, [88, 36, 68, 87, 57, 62, 20, 72, 03, 46, 33, 67, 46, 55, 12, 32, 63, 93, 53, 69]
|
||||||
|
, [04, 42, 16, 73, 38, 25, 39, 11, 24, 94, 72, 18, 08, 46, 29, 32, 40, 62, 76, 36]
|
||||||
|
, [20, 69, 36, 41, 72, 30, 23, 88, 34, 62, 99, 69, 82, 67, 59, 85, 74, 04, 36, 16]
|
||||||
|
, [20, 73, 35, 29, 78, 31, 90, 01, 74, 31, 49, 71, 48, 86, 81, 16, 23, 57, 05, 54]
|
||||||
|
, [01, 70, 54, 71, 83, 51, 54, 69, 16, 92, 33, 48, 61, 43, 52, 01, 89, 19, 67, 48]
|
||||||
|
]
|
||||||
|
|
||||||
|
points :: Integer -> [(Integer, Integer)]
|
||||||
|
points n = [ (x,y) | x <- [1..n], y <- [1..n] ]
|
||||||
|
|
||||||
|
allDiagonals :: Integer -> [[(Integer, Integer)]]
|
||||||
|
allDiagonals n =
|
||||||
|
[ [(i, j), b, c, d]
|
||||||
|
| (i, j) <- points n
|
||||||
|
, i+3 <= n
|
||||||
|
, j+3 <= n
|
||||||
|
, b <- [(i + 1, j + 1)]
|
||||||
|
, c <- [(i + 2, j + 2)]
|
||||||
|
, d <- [(i + 3, j + 3)]
|
||||||
|
]
|
||||||
|
|
||||||
|
allUpDown :: Integer -> [[(Integer, Integer)]]
|
||||||
|
allUpDown n =
|
||||||
|
[ [(i, j), b, c, d]
|
||||||
|
| (i, j) <- points n
|
||||||
|
, i <= n
|
||||||
|
, j+3 <= n
|
||||||
|
, b <- [(i, j + 1)]
|
||||||
|
, c <- [(i, j + 2)]
|
||||||
|
, d <- [(i, j + 3)]
|
||||||
|
]
|
||||||
|
|
||||||
|
allLeftRight :: Integer -> [[(Integer, Integer)]]
|
||||||
|
allLeftRight n =
|
||||||
|
[ [(i, j), b, c, d]
|
||||||
|
| (i, j) <- points n
|
||||||
|
, i+3 <= n
|
||||||
|
, j <= n
|
||||||
|
, b <- [(i + 1, j)]
|
||||||
|
, c <- [(i + 2, j)]
|
||||||
|
, d <- [(i + 3, j)]
|
||||||
|
]
|
||||||
|
|
||||||
|
allSequences :: Integer -> [[(Integer, Integer)]]
|
||||||
|
allSequences n = allDiagonals n ++ allUpDown n ++ allLeftRight n
|
||||||
|
|
||||||
|
s20x20 :: [[(Integer, Integer)]]
|
||||||
|
s20x20 = allSequences 20
|
||||||
|
|
||||||
|
getValue :: [[Integer]] -> (Integer, Integer) -> Integer
|
||||||
|
getValue grid (x,y) = row `genericIndex` y'
|
||||||
|
where row = (head . genericDrop (x-1) . genericTake x) grid
|
||||||
|
y' = y-1 -- compensate for 1 index numbering above
|
||||||
|
|
||||||
|
-- |
|
||||||
|
-- λ> ans
|
||||||
|
-- 51267216
|
||||||
|
-- (0.13 secs, 38,281,312 bytes)
|
||||||
|
ans :: Integer
|
||||||
|
ans = maximum $ map (product . map (getValue grid)) s20x20
|
||||||
|
|
||||||
|
main :: IO ()
|
||||||
|
main = print ans
|
|
@ -0,0 +1,32 @@
|
||||||
|
-- module Main where
|
||||||
|
import Data.IntSet (size)
|
||||||
|
import Data.List (unfoldr)
|
||||||
|
import Math.NumberTheory.ArithmeticFunctions (divisorsSmall)
|
||||||
|
|
||||||
|
main :: IO ()
|
||||||
|
main = print ans
|
||||||
|
|
||||||
|
-- triangleNumber :: Integer -> [Integer]
|
||||||
|
-- triangleNumber 1 = [1]
|
||||||
|
-- triangleNumber n = sum [1..n] : triangleNumber (n-1)
|
||||||
|
triangleNumber i = (i * (i + 1)) `div` 2
|
||||||
|
triangleNumbers = map triangleNumber [1..]
|
||||||
|
-- triangleNumbers :: [Int]
|
||||||
|
-- triangleNumbers = unfoldr (\b-> Just (sum [1..b],b+1)) 1
|
||||||
|
|
||||||
|
-- isDivisible a b = a `rem` b == 0
|
||||||
|
-- divisors n = filter (isDivisible n) [1..(floor . sqrt) n ]
|
||||||
|
|
||||||
|
-- Triangle Numbers With More than N divisors
|
||||||
|
tnwmtNd :: Int -> [Int]
|
||||||
|
tnwmtNd n = filter ((>= n) . size . divisorsSmall) triangleNumbers
|
||||||
|
|
||||||
|
ans :: Int
|
||||||
|
ans = head $ tnwmtNd 500
|
||||||
|
{-
|
||||||
|
λ> main
|
||||||
|
76576500
|
||||||
|
(0.00 secs, 114,944 bytes)
|
||||||
|
|
||||||
|
First triangle number to have over 500 divisors is 76576500
|
||||||
|
-}
|
|
@ -0,0 +1,32 @@
|
||||||
|
-- https://projecteuler.net/problem=7
|
||||||
|
-- Find the 10_001 prime number
|
||||||
|
|
||||||
|
primes1 :: [Integer]
|
||||||
|
primes1 = 2:3:prs
|
||||||
|
where
|
||||||
|
1:p:candidates = [6*k+r | k <- [0..], r <- [1,5]]
|
||||||
|
prs = p : filter isPrime candidates
|
||||||
|
isPrime n = not (any (divides n) (takeWhile (\p -> p*p <= n) prs))
|
||||||
|
divides n p = n `mod` p == 0
|
||||||
|
|
||||||
|
|
||||||
|
primes2 = 2:([3..] `minus` composites)
|
||||||
|
where
|
||||||
|
composites = union [multiples p | p <- primes2]
|
||||||
|
|
||||||
|
multiples n = map (n*) [n..]
|
||||||
|
|
||||||
|
(x:xs) `minus` (y:ys) | x < y = x:(xs `minus` (y:ys))
|
||||||
|
| x == y = xs `minus` ys
|
||||||
|
| x > y = (x:xs) `minus` ys
|
||||||
|
union = foldr merge [ ]
|
||||||
|
where
|
||||||
|
merge (x:xs) ys = x:merge' xs ys
|
||||||
|
merge' (x:xs) (y:ys) | x < y = x:merge' xs (y:ys)
|
||||||
|
| x == y = x:merge' xs ys
|
||||||
|
| x > y = y:merge' (x:xs) ys
|
||||||
|
|
||||||
|
|
||||||
|
primes3 = sieve [2..]
|
||||||
|
where
|
||||||
|
sieve (p : xs) = p : sieve [x | x <- xs, x `mod` p > 0]
|
|
@ -0,0 +1,66 @@
|
||||||
|
{-
|
||||||
|
The four adjacent digits in the 1000-digit number that have the greatest product are 9 x 9 x 8 x 9 = 5832.
|
||||||
|
|
||||||
|
73167176531330624919225119674426574742355349194934
|
||||||
|
96983520312774506326239578318016984801869478851843
|
||||||
|
85861560789112949495459501737958331952853208805511
|
||||||
|
12540698747158523863050715693290963295227443043557
|
||||||
|
66896648950445244523161731856403098711121722383113
|
||||||
|
62229893423380308135336276614282806444486645238749
|
||||||
|
30358907296290491560440772390713810515859307960866
|
||||||
|
70172427121883998797908792274921901699720888093776
|
||||||
|
65727333001053367881220235421809751254540594752243
|
||||||
|
52584907711670556013604839586446706324415722155397
|
||||||
|
53697817977846174064955149290862569321978468622482
|
||||||
|
83972241375657056057490261407972968652414535100474
|
||||||
|
82166370484403199890008895243450658541227588666881
|
||||||
|
16427171479924442928230863465674813919123162824586
|
||||||
|
17866458359124566529476545682848912883142607690042
|
||||||
|
24219022671055626321111109370544217506941658960408
|
||||||
|
07198403850962455444362981230987879927244284909188
|
||||||
|
84580156166097919133875499200524063689912560717606
|
||||||
|
05886116467109405077541002256983155200055935729725
|
||||||
|
71636269561882670428252483600823257530420752963450
|
||||||
|
|
||||||
|
Find the thirteen adjacent digits in the 1000-digit number that have the greatest product.
|
||||||
|
What is the value of this product?
|
||||||
|
-}
|
||||||
|
module Main where
|
||||||
|
|
||||||
|
import Data.Char (ord)
|
||||||
|
import Data.List (sort)
|
||||||
|
import Data.List.Split (splitOn)
|
||||||
|
|
||||||
|
thousandDigitNum :: Integer
|
||||||
|
thousandDigitNum = 7316717653133062491922511967442657474235534919493496983520312774506326239578318016984801869478851843858615607891129494954595017379583319528532088055111254069874715852386305071569329096329522744304355766896648950445244523161731856403098711121722383113622298934233803081353362766142828064444866452387493035890729629049156044077239071381051585930796086670172427121883998797908792274921901699720888093776657273330010533678812202354218097512545405947522435258490771167055601360483958644670632441572215539753697817977846174064955149290862569321978468622482839722413756570560574902614079729686524145351004748216637048440319989000889524345065854122758866688116427171479924442928230863465674813919123162824586178664583591245665294765456828489128831426076900422421902267105562632111110937054421750694165896040807198403850962455444362981230987879927244284909188845801561660979191338754992005240636899125607176060588611646710940507754100225698315520005593572972571636269561882670428252483600823257530420752963450
|
||||||
|
|
||||||
|
digits :: Integer -> [Integer]
|
||||||
|
digits = go []
|
||||||
|
where
|
||||||
|
go acc 0 = acc
|
||||||
|
go acc n = go (digit:acc) rest
|
||||||
|
where
|
||||||
|
digit = n `rem` 10
|
||||||
|
rest = n `div` 10
|
||||||
|
|
||||||
|
main :: IO ()
|
||||||
|
main = print ans
|
||||||
|
|
||||||
|
ans :: [[Integer]]
|
||||||
|
ans = (windowsOf 13 . digits) thousandDigitNum
|
||||||
|
-- "9878799272442"
|
||||||
|
|
||||||
|
-- what dose it mean to have the greatest product in adjacent digits?
|
||||||
|
-- why ask it like that???
|
||||||
|
-- doesn't have 0
|
||||||
|
-- otherwise is the largest number in the larger 1000-digit number
|
||||||
|
chunksWithoutZero :: Int -> [String]
|
||||||
|
chunksWithoutZero n = (filter (\str -> length str >= n) . filter (/= "") . splitOn "0" . show) thousandDigitNum
|
||||||
|
|
||||||
|
windowsOf :: Int -> [a] -> [[a]]
|
||||||
|
windowsOf n = drop (n-1) . go []
|
||||||
|
where
|
||||||
|
go acc [] = acc
|
||||||
|
go acc lst = go (lst':acc) (tail lst)
|
||||||
|
where
|
||||||
|
lst' = take n lst
|
|
@ -0,0 +1,105 @@
|
||||||
|
import Debug.Trace (trace)
|
||||||
|
import Graphics.Rendering.Chart.Backend.Cairo
|
||||||
|
import Graphics.Rendering.Chart.Easy
|
||||||
|
{-
|
||||||
|
Special Pythagorean Triplet
|
||||||
|
Problem 9
|
||||||
|
|
||||||
|
A Pythagorean triplet is a set of three natural numbers, `a < b < c`, for which,
|
||||||
|
|
||||||
|
`a^2 + b^2 = c^2`.
|
||||||
|
|
||||||
|
For example, `3^2 + 4^2 = 9 + 16 = 25 = 5^2`.
|
||||||
|
|
||||||
|
There exists exactly one Pythagorean triplet for which `a + b + c = 1000`.
|
||||||
|
|
||||||
|
Find the product `abc`.
|
||||||
|
-}
|
||||||
|
|
||||||
|
main :: IO ()
|
||||||
|
main = print answer
|
||||||
|
|
||||||
|
answer :: String
|
||||||
|
answer = "I dunno"
|
||||||
|
|
||||||
|
|
||||||
|
solve :: Integer -> [(Integer, Integer, Integer)]
|
||||||
|
solve x = takeWhile (\(a,b,c) -> a + b + c <= 1000) $ primitiveTriplesUnder x
|
||||||
|
|
||||||
|
euclid'sFormula :: Num c => (c, c) -> (c, c, c)
|
||||||
|
euclid'sFormula (m, n) = (a,b,c)
|
||||||
|
where
|
||||||
|
a = m^2 - n^2
|
||||||
|
b = 2*m*n
|
||||||
|
c = m^2 + n^2
|
||||||
|
|
||||||
|
listOfMNs :: Integer -> [(Integer, Integer)]
|
||||||
|
listOfMNs x =
|
||||||
|
[ (m,n)
|
||||||
|
| n <- [2,4..x] -- one of them is even
|
||||||
|
, m <- [n+1,n+3..x]
|
||||||
|
, gcd m n == 1 -- coprime
|
||||||
|
]
|
||||||
|
|
||||||
|
listOfMNs' :: Integer -> [(Integer, Integer)]
|
||||||
|
listOfMNs' x =
|
||||||
|
[ (m,n)
|
||||||
|
| n <- [2,4..] -- one of them is even
|
||||||
|
, m <- [n+1,n+3..]
|
||||||
|
, gcd m n == 1 -- coprime
|
||||||
|
, a m n + b m n + c m n <= x
|
||||||
|
] where
|
||||||
|
a m n = m^2 - n^2
|
||||||
|
b m n = 2*m*n
|
||||||
|
c m n = m^2 + n^2
|
||||||
|
|
||||||
|
|
||||||
|
primitiveTriplesUnder :: Integer -> [(Integer, Integer, Integer)]
|
||||||
|
primitiveTriplesUnder = map euclid'sFormula . listOfMNs
|
||||||
|
|
||||||
|
|
||||||
|
test :: [(Integer, Integer, Integer)]
|
||||||
|
test = [ (a,b,c)
|
||||||
|
| a <- [3..],
|
||||||
|
b <- take 10 [a+1..],
|
||||||
|
c <- takeWhile (\c -> a^2 + b^2 <= c^2) [b+1..]
|
||||||
|
]
|
||||||
|
|
||||||
|
ls :: [(Integer, Integer)]
|
||||||
|
ls = filter (\(m,n) -> gcd m n == 1) $ zip [5,9..] [2,4..]
|
||||||
|
|
||||||
|
diags :: Integer -> [(Integer, Integer)]
|
||||||
|
diags n = [(x,y) | x<-[0..n], y<-[0..n]]
|
||||||
|
|
||||||
|
|
||||||
|
graph :: IO ()
|
||||||
|
graph = toFile def "test.png" $ do
|
||||||
|
layout_title .= "Points"
|
||||||
|
plot (line "points" [ [ (x,y) | (x,y) <- listOfMNs 30] ])
|
||||||
|
|
||||||
|
|
||||||
|
-- main'' = print ans'
|
||||||
|
ans' :: Integer -> [(Integer, Integer, Integer)]
|
||||||
|
ans' limit = [(a, b, c)
|
||||||
|
| a <- [1 .. limit]
|
||||||
|
, b <- [a + 1 .. limit]
|
||||||
|
, c <- [limit - a - b]
|
||||||
|
, b < c
|
||||||
|
]
|
||||||
|
|
||||||
|
{-
|
||||||
|
- Solution to Project Euler problem 9
|
||||||
|
- Copyright (c) Project Nayuki. All rights reserved.
|
||||||
|
-
|
||||||
|
- https://www.nayuki.io/page/project-euler-solutions
|
||||||
|
- https://github.com/nayuki/Project-Euler-solutions
|
||||||
|
-}
|
||||||
|
|
||||||
|
|
||||||
|
-- Computers are fast, so we can implement a brute-force search to directly solve the problem.
|
||||||
|
perim = 1000
|
||||||
|
main = putStrLn (show ans)
|
||||||
|
ans = head [a * b * (perim - a - b) | a <- [1..perim], b <- [a+1..perim], isIntegerRightTriangle a b]
|
||||||
|
isIntegerRightTriangle a b = a < b && b < c
|
||||||
|
&& a * a + b * b == c * c
|
||||||
|
where c = perim - a - b
|
Loading…
Reference in New Issue