Difference between revisions of "Euler problems/121 to 130"
Marypoppins (talk | contribs) |
CaleGibbard (talk | contribs) (rv: vandalism) |
||
Line 1: | Line 1: | ||
− | + | == [http://projecteuler.net/index.php?section=problems&id=121 Problem 121] == | |
+ | Investigate the game of chance involving coloured discs. | ||
+ | |||
+ | Solution: | ||
+ | <haskell> | ||
+ | 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 | ||
+ | ] | ||
+ | </haskell> | ||
+ | |||
+ | == [http://projecteuler.net/index.php?section=problems&id=122 Problem 122] == | ||
+ | Finding the most efficient exponentiation method. | ||
+ | |||
+ | Solution using a depth first search, pretty fast : | ||
+ | <haskell> | ||
+ | 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 | ||
+ | </haskell> | ||
+ | |||
+ | == [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. | ||
+ | |||
+ | Solution: | ||
+ | <haskell> | ||
+ | problem_123 = | ||
+ | fst . head . dropWhile (\(n,p) -> (2 + 2*n*p) < 10^10) $ | ||
+ | zip [1..] primes | ||
+ | </haskell> | ||
+ | |||
+ | == [http://projecteuler.net/index.php?section=problems&id=124 Problem 124] == | ||
+ | Determining the kth element of the sorted radical function. | ||
+ | |||
+ | Solution: | ||
+ | <haskell> | ||
+ | import Data.List | ||
+ | compress [] = [] | ||
+ | compress (x:[]) = [x] | ||
+ | compress (x:y:xs) | x == y = compress (y:xs) | ||
+ | | otherwise = x : compress (y:xs) | ||
+ | |||
+ | rad = product . compress . primeFactors | ||
+ | |||
+ | radfax = (1,1) : zip [2..] (map rad [2..]) | ||
+ | |||
+ | sortRadfax n = sortBy (\ (_,x) (_,y) -> compare x y) $ take n radfax | ||
+ | problem_124=fst$sortRadfax 100000!!9999 | ||
+ | </haskell> | ||
+ | |||
+ | == [http://projecteuler.net/index.php?section=problems&id=125 Problem 125] == | ||
+ | Finding square sums that are palindromic. | ||
+ | |||
+ | Solution: | ||
+ | <haskell> | ||
+ | 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] | ||
+ | </haskell> | ||
+ | |||
+ | == [http://projecteuler.net/index.php?section=problems&id=126 Problem 126] == | ||
+ | Exploring the number of cubes required to cover every visible face on a cuboid. | ||
+ | |||
+ | Solution: | ||
+ | <haskell> | ||
+ | problem_126 = undefined | ||
+ | </haskell> | ||
+ | |||
+ | == [http://projecteuler.net/index.php?section=problems&id=127 Problem 127] == | ||
+ | Investigating the number of abc-hits below a given limit. | ||
+ | |||
+ | Solution: | ||
+ | <haskell> | ||
+ | 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 | ||
+ | </haskell> | ||
+ | |||
+ | == [http://projecteuler.net/index.php?section=problems&id=128 Problem 128] == | ||
+ | Which tiles in the hexagonal arrangement have prime differences with neighbours? | ||
+ | |||
+ | Solution: | ||
+ | <haskell> | ||
+ | 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] | ||
+ | </haskell> | ||
+ | |||
+ | == [http://projecteuler.net/index.php?section=problems&id=129 Problem 129] == | ||
+ | Investigating minimal repunits that divide by n. | ||
+ | |||
+ | Solution: | ||
+ | <haskell> | ||
+ | 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) | ||
+ | </haskell> | ||
+ | |||
+ | == [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. | ||
+ | |||
+ | Solution: | ||
+ | <haskell> | ||
+ | --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] | ||
+ | </haskell> |
Revision as of 04:59, 30 January 2008
Contents
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
compress [] = []
compress (x:[]) = [x]
compress (x:y:xs) | x == y = compress (y:xs)
| otherwise = x : compress (y:xs)
rad = product . compress . primeFactors
radfax = (1,1) : zip [2..] (map rad [2..])
sortRadfax n = sortBy (\ (_,x) (_,y) -> compare x y) $ 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:
problem_126 = undefined
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]