Euler problems/51 to 60

From HaskellWiki
Jump to navigation Jump to search
The printable version is no longer supported and may have rendering errors. Please update your browser bookmarks and please use the default browser print function instead.

Problem 51

Find the smallest prime which, by changing the same part of the number, can form eight different primes.

Solution:

problem_51 = undefined

Problem 52

Find the smallest positive integer, x, such that 2x, 3x, 4x, 5x, and 6x, contain the same digits in some order.

Solution:

problem_52 = head [n | n <- [1..],
                   digits (2*n) == digits (3*n),
                   digits (3*n) == digits (4*n),
                   digits (4*n) == digits (5*n),
                   digits (5*n) == digits (6*n)]
    where digits = sort . show

Problem 53

How many values of C(n,r), for 1 ≤ n ≤ 100, exceed one-million?

Solution:

problem_53 = length [n | n <- [1..100], r <- [1..n], n `choose` r > 10^6]
    where n `choose` r
           | r > n || r < 0 = 0
           | otherwise      = foldl (\z j -> z*(n-j+1) `div` j) n [2..r]

Problem 54

How many hands did player one win in the poker games?

Solution:

probably not the most straight forward way to do it.

import Data.List (sort, sortBy, tails, lookup, groupBy)
import Data.Maybe (fromJust)

data Hand = HighCard | OnePair | TwoPairs | ThreeOfKind | Straight | Flush | FullHouse | FourOfKind | StraightFlush
    deriving (Show, Read, Enum, Eq, Ord)

values :: [(Char, Int)]
values = zip ['2','3','4','5','6','7','8','9','T','J','Q','K','A'] [1..]

value :: String -> Int
value (c:cs) = fromJust $ lookup c values

suites :: [[Char]]
suites = map sort $ take 9 $ map (take 5) $ tails cards

cards :: [Char]
cards = ['2','3','4','5','6','7','8','9','T','J','Q','K','A']

flush :: [String] -> Bool
flush = a . extractSuit
    where
        a (x:y:xs) = x == y && a (y:xs)
        a _ = True
        extractSuit = map s
            where
                s (_:y:ys) = y

straight :: [String] -> Bool
straight = a . extractValues 
    where
        a xs = any (==(sort xs)) suites
        extractValues = map v
            where
                v (x:xs) = x

groupByKind :: [String] -> [[String]]
groupByKind = sortBy l . groupBy g . sortBy s
    where
        s (a) (b) = compare (value b) (value a)
        g (a:_) (b:_) = a == b
        l a b = compare (length b) (length a)

guessHand :: [String] -> Hand
guessHand cards
    | straight cards && flush cards = StraightFlush
    | length g1 == 4 = FourOfKind
    | length g1 == 3 && length g2 == 2 = FullHouse
    | flush cards = Flush
    | straight cards = Straight
    | length g1 == 3 = ThreeOfKind
    | length g1 == 2 && length g2 == 2 = TwoPairs
    | length g1 == 2 = OnePair
    | otherwise = HighCard
    where
        g = groupByKind cards
        g1 = head g
        g2 = head $ tail g

playerOneScore :: ([String], [String]) -> Int
playerOneScore (p1, p2)
    | a == b    = compare p1 p2
    | a > b     = 1
    | otherwise = 0
    where
        a = guessHand p1
        b = guessHand p2
        compare p1 p2 = if ((map value $ concat $ groupByKind p1) > (map value $ concat $ groupByKind p2)) then 1 else 0

problem_54 :: String -> Int
problem_54 = sum . map (\x -> playerOneScore $ splitAt 5 $ words x) . lines

Problem 55

How many Lychrel numbers are there below ten-thousand?

Solution:

problem_55 = length $ filter isLychrel [1..9999]
    where isLychrel n = all notPalindrome (take 50 (tail (iterate revadd n)))
          notPalindrome s = (show s) /= reverse (show s)
          revadd n = n + rev n
              where rev n = read (reverse (show n))

Problem 56

Considering natural numbers of the form, ab, finding the maximum digital sum.

Solution:

problem_56 = maximum [dsum (a^b) | a <- [1..99], b <-[1..99]]
    where dsum 0 = 0
          dsum n = let ( d, m ) = n `divMod` 10 in m + ( dsum d )

Problem 57

Investigate the expansion of the continued fraction for the square root of two.

Solution:

problem_57 = length $ filter topHeavy $ take 1000 convergents 
    where topHeavy r = numDigits (numerator r) > numDigits (denominator r)
          numDigits = length . show
          convergents = iterate next (3%2)
          next r = 1 + 1/(1+r)

Problem 58

Investigate the number of primes that lie on the diagonals of the spiral grid.

Solution:

base :: (Integral a) => [a]
base = base' 2
    where
        base' n = n:n:n:n:(base' $ n + 2)

pascal = scanl (+) 1 base

ratios :: [Integer] -> [Double]
ratios (x:xs) = 1.0 : ratios' 0 1 xs
    where
        ratios' n d (w:x:y:z:xs) = ((fromInteger num)/(fromInteger den)) : (ratios' num den xs)
            where
                num = (p w + p x + p y + p z + n)
                den = (d + 4)
                p n = case isPrime n of
                        True -> 1
                        False -> 0

problem_58 = fst $ head $ dropWhile (\(_,a) -> a > 0.1) $ zip [1,3..] (ratios pascal)

Problem 59

Using a brute force attack, can you decrypt the cipher using XOR encryption?

Solution:

problem_59 = undefined

Problem 60

Find a set of five primes for which any two primes concatenate to produce another prime.

Solution:

problem_60 = undefined