Difference between revisions of "Euler problems/121 to 130"
m |
|||
(7 intermediate revisions by 4 users not shown) | |||
Line 1: | Line 1: | ||
− | == [http://projecteuler.net/index.php?section= |
+ | == [http://projecteuler.net/index.php?section=problems&id=121 Problem 121] == |
Investigate the game of chance involving coloured discs. |
Investigate the game of chance involving coloured discs. |
||
Line 18: | Line 18: | ||
</haskell> |
</haskell> |
||
− | == [http://projecteuler.net/index.php?section= |
+ | == [http://projecteuler.net/index.php?section=problems&id=122 Problem 122] == |
Finding the most efficient exponentiation method. |
Finding the most efficient exponentiation method. |
||
Line 46: | Line 46: | ||
</haskell> |
</haskell> |
||
− | == [http://projecteuler.net/index.php?section= |
+ | == [http://projecteuler.net/index.php?section=problems&id=123 Problem 123] == |
Determining the remainder when (pn − 1)n + (pn + 1)n is divided by pn2. |
Determining the remainder when (pn − 1)n + (pn + 1)n is divided by pn2. |
||
Solution: |
Solution: |
||
<haskell> |
<haskell> |
||
− | primes = 2 : filter ((==1) . length . primeFactors) [3,5..] |
||
− | |||
− | primeFactors n = factor n primes |
||
− | where |
||
− | factor _ [] = [] |
||
− | factor m (p:ps) | p*p > m = [m] |
||
− | | m `mod` p == 0 = p : [m `div` p] |
||
− | | otherwise = factor m ps |
||
− | |||
− | isPrime :: Integer -> Bool |
||
− | isPrime 1 = False |
||
− | isPrime n = case (primeFactors n) of |
||
− | (_:_:_) -> False |
||
− | _ -> True |
||
− | |||
problem_123 = |
problem_123 = |
||
+ | fst . head . dropWhile (\(n,p) -> (2 + 2*n*p) < 10^10) $ |
||
− | head[a+1|a<-[20000,20002..22000], |
||
+ | zip [1..] primes |
||
− | let n=2*(a+1)*primes!!(fromInteger a), |
||
− | n>10^10 |
||
− | ] |
||
</haskell> |
</haskell> |
||
− | == [http://projecteuler.net/index.php?section= |
+ | == [http://projecteuler.net/index.php?section=problems&id=124 Problem 124] == |
Determining the kth element of the sorted radical function. |
Determining the kth element of the sorted radical function. |
||
Solution: |
Solution: |
||
<haskell> |
<haskell> |
||
− | import List |
+ | import Data.List |
+ | import Data.Ord (comparing) |
||
− | primes :: [Integer] |
||
+ | |||
− | primes = 2 : filter ((==1) . length . primeFactors) [3,5..] |
||
+ | compress = map head . group |
||
− | |||
+ | |||
− | primeFactors :: Integer -> [Integer] |
||
+ | rad = product . compress . primeFactors |
||
− | primeFactors n = factor n primes |
||
− | where |
||
− | factor _ [] = [] |
||
− | factor m (p:ps) | p*p > m = [m] |
||
− | | m `mod` p == 0 = p : factor (m `div` p) (p:ps) |
||
− | | otherwise = factor m ps |
||
− | problem_124=snd$(!!9999)$sort[(product$nub$primeFactors x,x)|x<-[1..100000]] |
||
+ | radfax = (1,1) : zip [2..] (map rad [2..]) |
||
+ | |||
+ | sortRadfax n = sortBy (comparing snd) $ take n radfax |
||
+ | problem_124=fst$sortRadfax 100000!!9999 |
||
</haskell> |
</haskell> |
||
− | == [http://projecteuler.net/index.php?section= |
+ | == [http://projecteuler.net/index.php?section=problems&id=125 Problem 125] == |
Finding square sums that are palindromic. |
Finding square sums that are palindromic. |
||
Solution: |
Solution: |
||
<haskell> |
<haskell> |
||
− | import Data.List |
+ | import Data.List as L |
− | import Data. |
+ | import Data.Set as S |
+ | |||
+ | hi = 100000000 |
||
+ | |||
+ | ispalindrome n = (show n) == reverse (show n) |
||
+ | |||
+ | -- the "drop 2" ensures all sums use at least two terms |
||
+ | -- by ignoring the 0- and 1-term "sums" |
||
+ | sumsFrom i = |
||
+ | takeWhile (<hi) . |
||
+ | drop 2 . |
||
+ | scanl (\s n -> s + n^2) 0 $ [i..] |
||
+ | |||
+ | limit = |
||
+ | truncate . sqrt . fromIntegral $ (hi `div` 2) |
||
+ | problem_125 = |
||
− | toFloat = (flip encodeFloat 0) |
||
+ | fold (+) 0 . |
||
− | digits n |
||
+ | fromList . |
||
− | {- 123->[3,2,1] |
||
+ | concat . |
||
− | -} |
||
+ | L.map (L.filter ispalindrome . sumsFrom) $ [1 .. limit] |
||
− | |n<10=[n] |
||
+ | </haskell> |
||
− | |otherwise= y:digits x |
||
− | where |
||
− | (x,y)=divMod n 10 |
||
+ | == [http://projecteuler.net/index.php?section=problems&id=126 Problem 126] == |
||
− | palind n=foldl dmm 0 (digits n) |
||
+ | Exploring the number of cubes required to cover every visible face on a cuboid. |
||
− | -- 123 ->321 |
||
− | dmm=(\x y->x*10+y) |
||
+ | Solution: |
||
− | makepalind n=(n*d+p):[c+b*d|b<-[0..9]] |
||
+ | <haskell> |
||
− | where |
||
+ | import Data.Array.ST |
||
− | a=(+1)$floor$logBase 10$fromInteger n |
||
+ | import Control.Monad (when) |
||
− | d=10^a |
||
+ | import Control.Monad.ST |
||
− | p=palind n |
||
− | c=n*10*d+p |
||
+ | limit = 20000 |
||
− | twomakep n=(n*d+p) |
||
+ | layer x y z n = 4*(x+y+z+n-2)*(n-1) + 2*x*y + 2*x*z + 2*y*z |
||
− | where |
||
− | a=(+1)$floor$logBase 10$fromInteger n |
||
− | d=10^a |
||
− | p=palind n |
||
+ | solutions :: STUArray s Int Int -> Int -> ST s () |
||
− | p125=sum[b|a<-[1..999], b<-makepalind a,not$null$ funa b] |
||
+ | solutions a n = |
||
− | p125a=sum[b|a<-[1000..9999], let b=twomakep a,not$null$ funa b] |
||
+ | when (layer 1 1 1 n <= limit) $ |
||
− | p125b=sum[a|a<-[1..9], not$null$ funa a] |
||
+ | do solutions a (n+1) |
||
+ | solutions' a 1 n |
||
+ | solutions' :: STUArray s Int Int -> Int -> Int -> ST s () |
||
− | findmap=fromList[(a,2*fill_map a)|a<-[0..737]] |
||
+ | solutions' a x n = |
||
− | fill_map x |
||
− | + | when (layer x x x n <= limit) $ |
|
− | + | do solutions' a (x+1) n |
|
+ | solutions'' a x x n |
||
− | where |
||
− | fastsum y=div (y*(y+1)*(2*y+1)) 6 |
||
− | fastsumodd y=let n=div (y+1) 2 in div (n*(4*n*n-1)) 3 |
||
+ | solutions'' :: STUArray s Int Int -> Int -> Int -> Int -> ST s () |
||
− | funa x=[(a,x)|a<-takeWhile (\a->a*a*a<4*x) [2..],funb a x] |
||
+ | solutions'' a x y n = |
||
− | funb x n |
||
− | + | when (layer x y y n <= limit) $ |
|
+ | do solutions'' a x (y+1) n |
||
− | |otherwise=d4==0 && odd d3 && d3>=(x+1)^2 && isSq d3 |
||
+ | solutions''' a x y y n |
||
− | where |
||
− | x1=fromInteger x |
||
− | (d1,d2)=divMod ((n-findmap! x1)) (x) |
||
− | (d3,d4)=divMod ((4*n-findmap!x1)) (x) |
||
− | isSq x=(floor$sqrt$toFloat x)^2==x |
||
− | problem_125 = (p125+p125a+p125b) |
||
− | </haskell> |
||
+ | solutions''' :: STUArray s Int Int -> Int -> Int -> Int -> Int -> ST s () |
||
− | == [http://projecteuler.net/index.php?section=view&id=126 Problem 126] == |
||
+ | solutions''' a x y z n = |
||
− | Exploring the number of cubes required to cover every visible face on a cuboid. |
||
+ | when (layer x y z n <= limit) $ |
||
+ | do readArray a (layer x y z n) >>= return.(+1) >>= writeArray a (layer x y z n) |
||
+ | solutions''' a x y (z+1) n |
||
+ | findSolution :: STUArray s Int Int -> Int -> ST s (Maybe Int) |
||
− | Solution: |
||
+ | findSolution a n |
||
− | <haskell> |
||
+ | | n == limit = return Nothing |
||
− | problem_126 = undefined |
||
+ | | otherwise = do |
||
+ | v <- readArray a n |
||
+ | if v == 1000 |
||
+ | then return (Just n) |
||
+ | else findSolution a (n+1) |
||
+ | |||
+ | main :: IO () |
||
+ | main = print foo |
||
+ | where foo = runST $ |
||
+ | do cn <- newArray (0,limit+1) 0 :: ST s (STUArray s Int Int) |
||
+ | solutions cn 1 |
||
+ | findSolution cn 154 |
||
</haskell> |
</haskell> |
||
− | == [http://projecteuler.net/index.php?section= |
+ | == [http://projecteuler.net/index.php?section=problems&id=127 Problem 127] == |
Investigating the number of abc-hits below a given limit. |
Investigating the number of abc-hits below a given limit. |
||
Line 183: | Line 180: | ||
rads = listArray (1,n) $ map rad [1..n] |
rads = listArray (1,n) $ map rad [1..n] |
||
invrads = sort $ map (\(a,b) -> (b, a)) $ assocs rads |
invrads = sort $ map (\(a,b) -> (b, a)) $ assocs rads |
||
− | primeFactors :: Integer -> [Integer] |
||
− | primeFactors n = factor n primes |
||
− | where |
||
− | factor _ [] = [] |
||
− | factor m (p:ps) | p*p > m = [m] |
||
− | | m `mod` p == 0 = p : factor (m `div` p) (p:ps) |
||
− | | otherwise = factor m ps |
||
− | merge xs@(x:xt) ys@(y:yt) = case compare x y of |
||
− | LT -> x : (merge xt ys) |
||
− | EQ -> x : (merge xt yt) |
||
− | GT -> y : (merge xs yt) |
||
− | |||
− | diff xs@(x:xt) ys@(y:yt) = case compare x y of |
||
− | LT -> x : (diff xt ys) |
||
− | EQ -> diff xt yt |
||
− | GT -> diff xs yt |
||
− | |||
− | primes, nonprimes :: [Integer] |
||
− | primes = [2,3,5] ++ (diff [7,9..] nonprimes) |
||
− | nonprimes = foldr1 f . map g $ tail primes |
||
− | where f (x:xt) ys = x : (merge xt ys) |
||
− | g p = [ n*p | n <- [p,p+2..]] |
||
problem_127 = main |
problem_127 = main |
||
</haskell> |
</haskell> |
||
− | == [http://projecteuler.net/index.php?section= |
+ | == [http://projecteuler.net/index.php?section=problems&id=128 Problem 128] == |
Which tiles in the hexagonal arrangement have prime differences with neighbours? |
Which tiles in the hexagonal arrangement have prime differences with neighbours? |
||
Solution: |
Solution: |
||
<haskell> |
<haskell> |
||
+ | p128= |
||
− | problem_128 = undefined |
||
+ | concat[m|a<-[0..70000],let m=middle a++right a,not$null m] |
||
+ | where |
||
+ | middle n |
||
+ | |all isPrime [11+6*n,13+6*n,29+12*n]=[2+3*(n+1)*(n+2)] |
||
+ | |otherwise=[] |
||
+ | right n |
||
+ | |all isPrime [11+6*n,17+6*n,17+12*n]=[1+3*(n+2)*(n+3)] |
||
+ | |otherwise=[] |
||
+ | problem_128=do |
||
+ | print(p128!!1997) |
||
+ | isPrime x |
||
+ | |x<100=isPrime' x |
||
+ | |otherwise=all (millerRabinPrimality x )[2,7,61] |
||
</haskell> |
</haskell> |
||
− | == [http://projecteuler.net/index.php?section= |
+ | == [http://projecteuler.net/index.php?section=problems&id=129 Problem 129] == |
Investigating minimal repunits that divide by n. |
Investigating minimal repunits that divide by n. |
||
Line 222: | Line 210: | ||
<haskell> |
<haskell> |
||
import Data.List |
import Data.List |
||
− | mulMod :: Integral a => a -> a -> a -> a |
||
− | mulMod a b c= (b * c) `rem` a |
||
− | squareMod :: Integral a => a -> a -> a |
||
− | squareMod a b = (b * b) `rem` a |
||
− | pow' :: (Num a, Integral b) => (a -> a -> a) -> (a -> a) -> a -> b -> a |
||
− | pow' _ _ _ 0 = 1 |
||
− | pow' mul sq x' n' = f x' n' 1 |
||
− | where |
||
− | f x n y |
||
− | | n == 1 = x `mul` y |
||
− | | r == 0 = f x2 q y |
||
− | | otherwise = f x2 q (x `mul` y) |
||
− | where |
||
− | (q,r) = quotRem n 2 |
||
− | x2 = sq x |
||
− | powMod :: Integral a => a -> a -> a -> a |
||
− | powMod m = pow' (mulMod m) (squareMod m) |
||
− | |||
− | merge xs@(x:xt) ys@(y:yt) = case compare x y of |
||
− | LT -> x : (merge xt ys) |
||
− | EQ -> x : (merge xt yt) |
||
− | GT -> y : (merge xs yt) |
||
− | |||
− | diff xs@(x:xt) ys@(y:yt) = case compare x y of |
||
− | LT -> x : (diff xt ys) |
||
− | EQ -> diff xt yt |
||
− | GT -> diff xs yt |
||
− | |||
− | primes, nonprimes :: [Integer] |
||
− | primes = [2,3,5] ++ (diff [7,9..] nonprimes) |
||
− | nonprimes = foldr1 f . map g $ tail primes |
||
− | where f (x:xt) ys = x : (merge xt ys) |
||
− | g p = [ n*p | n <- [p,p+2..]] |
||
− | primeFactors :: Integer -> [Integer] |
||
− | primeFactors n = factor n primes |
||
− | where |
||
− | factor _ [] = [] |
||
− | factor m (p:ps) | p*p > m = [m] |
||
− | | m `mod` p == 0 = p : factor (m `div` p) (p:ps) |
||
− | | otherwise = factor m ps |
||
− | |||
− | fstfac x = [(head a ,length a)|a<-group$primeFactors x] |
||
− | fac [(x,y)]=[x^a|a<-[0..y]] |
||
− | fac (x:xs)=[a*b|a<-fac [x],b<-fac xs] |
||
factors x=fac$fstfac x |
factors x=fac$fstfac x |
||
+ | funp (p,1)= |
||
− | funp (p,1)=head[a|a<-sort$factors (p-1),powMod p 10 a==1] |
||
+ | head[a| |
||
+ | a<-sort$factors (p-1), |
||
+ | powMod p 10 a==1 |
||
+ | ] |
||
funp (p,s)=p^(s-1)*funp (p,1) |
funp (p,s)=p^(s-1)*funp (p,1) |
||
funn []=1 |
funn []=1 |
||
funn (x:xs) =lcm (funp x) (funn xs) |
funn (x:xs) =lcm (funp x) (funn xs) |
||
+ | p129 q= |
||
− | p129 q=head[a|a<-[q..],gcd a 10==1,let s=funn$fstfac$(*9) a,s>q,s>a] |
||
+ | head[a| |
||
+ | a<-[q..], |
||
+ | gcd a 10==1, |
||
+ | let s=funn$fstfac$(*9) a, |
||
+ | s>q, |
||
+ | s>a |
||
+ | ] |
||
problem_129 = p129 (10^6) |
problem_129 = p129 (10^6) |
||
</haskell> |
</haskell> |
||
− | == [http://projecteuler.net/index.php?section= |
+ | == [http://projecteuler.net/index.php?section=problems&id=130 Problem 130] == |
Finding composite values, n, for which n−1 is divisible by the length of the smallest repunits that divide it. |
Finding composite values, n, for which n−1 is divisible by the length of the smallest repunits that divide it. |
||
Line 281: | Line 236: | ||
<haskell> |
<haskell> |
||
--factors powMod in p129 |
--factors powMod in p129 |
||
− | fun x |
+ | fun x |
+ | |(not$null a)=head a |
||
|otherwise=0 |
|otherwise=0 |
||
where |
where |
Latest revision as of 18:29, 21 February 2010
Problem 121
Investigate the game of chance involving coloured discs.
Solution:
import Data.List
problem_121 = possibleGames `div` winningGames
where
possibleGames = product [1..16]
winningGames =
(1+) $ sum $ map product $ chooseUpTo 7 [1..15]
chooseUpTo 0 _ = []
chooseUpTo (n+1) x =
[y:z |
(y:ys) <- tails x,
z <- []: chooseUpTo n ys
]
Problem 122
Finding the most efficient exponentiation method.
Solution using a depth first search, pretty fast :
import Data.List
import Data.Array.Diff
import Control.Monad
depthAddChain 12 branch mins = mins
depthAddChain d branch mins = foldl' step mins $ nub $ filter (> head branch)
$ liftM2 (+) branch branch
where
step da e | e > 200 = da
| otherwise =
case compare (da ! e) d of
GT -> depthAddChain (d+1) (e:branch) $ da // [(e,d)]
EQ -> depthAddChain (d+1) (e:branch) da
LT -> da
baseBranch = [2,1]
baseMins :: DiffUArray Int Int
baseMins = listArray (1,200) $ 0:1: repeat maxBound
problem_122 = sum . elems $ depthAddChain 2 baseBranch baseMins
Problem 123
Determining the remainder when (pn − 1)n + (pn + 1)n is divided by pn2.
Solution:
problem_123 =
fst . head . dropWhile (\(n,p) -> (2 + 2*n*p) < 10^10) $
zip [1..] primes
Problem 124
Determining the kth element of the sorted radical function.
Solution:
import Data.List
import Data.Ord (comparing)
compress = map head . group
rad = product . compress . primeFactors
radfax = (1,1) : zip [2..] (map rad [2..])
sortRadfax n = sortBy (comparing snd) $ take n radfax
problem_124=fst$sortRadfax 100000!!9999
Problem 125
Finding square sums that are palindromic.
Solution:
import Data.List as L
import Data.Set as S
hi = 100000000
ispalindrome n = (show n) == reverse (show n)
-- the "drop 2" ensures all sums use at least two terms
-- by ignoring the 0- and 1-term "sums"
sumsFrom i =
takeWhile (<hi) .
drop 2 .
scanl (\s n -> s + n^2) 0 $ [i..]
limit =
truncate . sqrt . fromIntegral $ (hi `div` 2)
problem_125 =
fold (+) 0 .
fromList .
concat .
L.map (L.filter ispalindrome . sumsFrom) $ [1 .. limit]
Problem 126
Exploring the number of cubes required to cover every visible face on a cuboid.
Solution:
import Data.Array.ST
import Control.Monad (when)
import Control.Monad.ST
limit = 20000
layer x y z n = 4*(x+y+z+n-2)*(n-1) + 2*x*y + 2*x*z + 2*y*z
solutions :: STUArray s Int Int -> Int -> ST s ()
solutions a n =
when (layer 1 1 1 n <= limit) $
do solutions a (n+1)
solutions' a 1 n
solutions' :: STUArray s Int Int -> Int -> Int -> ST s ()
solutions' a x n =
when (layer x x x n <= limit) $
do solutions' a (x+1) n
solutions'' a x x n
solutions'' :: STUArray s Int Int -> Int -> Int -> Int -> ST s ()
solutions'' a x y n =
when (layer x y y n <= limit) $
do solutions'' a x (y+1) n
solutions''' a x y y n
solutions''' :: STUArray s Int Int -> Int -> Int -> Int -> Int -> ST s ()
solutions''' a x y z n =
when (layer x y z n <= limit) $
do readArray a (layer x y z n) >>= return.(+1) >>= writeArray a (layer x y z n)
solutions''' a x y (z+1) n
findSolution :: STUArray s Int Int -> Int -> ST s (Maybe Int)
findSolution a n
| n == limit = return Nothing
| otherwise = do
v <- readArray a n
if v == 1000
then return (Just n)
else findSolution a (n+1)
main :: IO ()
main = print foo
where foo = runST $
do cn <- newArray (0,limit+1) 0 :: ST s (STUArray s Int Int)
solutions cn 1
findSolution cn 154
Problem 127
Investigating the number of abc-hits below a given limit.
Solution:
import Data.List
import Data.Array.IArray
import Data.Array.Unboxed
main = appendFile "p127.log" $show$ solve 99999
rad x = fromIntegral $ product $ map fst $ primePowerFactors $ fromIntegral x
primePowerFactors x = [(head a ,length a)|a<-group$primeFactors x]
solve :: Int -> Int
solve n = sum [ c | (rc,c) <- invrads
, 2 * rc < c
, (ra, a) <- takeWhile (\(a,_)->(c > 2*rc*a)) invrads
, a < c `div` 2
, gcd ra rc == 1
, ra * rads ! (c - a) < c `div` rc]
where
rads :: UArray Int Int
rads = listArray (1,n) $ map rad [1..n]
invrads = sort $ map (\(a,b) -> (b, a)) $ assocs rads
problem_127 = main
Problem 128
Which tiles in the hexagonal arrangement have prime differences with neighbours?
Solution:
p128=
concat[m|a<-[0..70000],let m=middle a++right a,not$null m]
where
middle n
|all isPrime [11+6*n,13+6*n,29+12*n]=[2+3*(n+1)*(n+2)]
|otherwise=[]
right n
|all isPrime [11+6*n,17+6*n,17+12*n]=[1+3*(n+2)*(n+3)]
|otherwise=[]
problem_128=do
print(p128!!1997)
isPrime x
|x<100=isPrime' x
|otherwise=all (millerRabinPrimality x )[2,7,61]
Problem 129
Investigating minimal repunits that divide by n.
Solution:
import Data.List
factors x=fac$fstfac x
funp (p,1)=
head[a|
a<-sort$factors (p-1),
powMod p 10 a==1
]
funp (p,s)=p^(s-1)*funp (p,1)
funn []=1
funn (x:xs) =lcm (funp x) (funn xs)
p129 q=
head[a|
a<-[q..],
gcd a 10==1,
let s=funn$fstfac$(*9) a,
s>q,
s>a
]
problem_129 = p129 (10^6)
Problem 130
Finding composite values, n, for which n−1 is divisible by the length of the smallest repunits that divide it.
Solution:
--factors powMod in p129
fun x
|(not$null a)=head a
|otherwise=0
where
a=take 1 [n|n<-sort$factors (x-1),(powMod x 10 n)==1]
problem_130 =sum$take 25[a|a<-[1..],
not$isPrime a,
let b=fun a,
b/=0,
mod (a-1) b==0,
mod a 3 /=0]