Last active
August 29, 2015 14:14
-
-
Save zaneli/fe2d126baf87a4654496 to your computer and use it in GitHub Desktop.
「HaskellでProject Euler(Problem 58~60)」ブログ用
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import Data.List (find, unfoldr) | |
import Zaneli.Euler (isPrime) | |
main = let Just (_, l) = search spiralDiagonals in print l | |
spiralDiagonals :: [(Integer, [Integer])] | |
spiralDiagonals = zip [3,5..] $ unfoldr spiralDiagonals' (1, 0) | |
where | |
spiralDiagonals' (n, step) = Just (ns, (m, step')) | |
where | |
m = n + step' * 4 | |
ns = [n+step',n+step'*2..m] | |
step' = step + 2 | |
search :: Num a => [(a, [Integer])] -> Maybe ((Int, Int), a) | |
search nss = find (\((n, d), l) -> n*100 `div` d < 10) $ tail $ scanl f ((0, 1), 0) nss | |
where | |
f ((n, d), _) (l, ns) = ((n', d'), l) | |
where | |
n' = n + (length $ filter isPrime ns) | |
d' = d + (length ns) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import Data.Bits (xor) | |
import Data.List (find, findIndex, unfoldr) | |
main = do | |
cipher <- readFile "cipher.txt" | |
let cs = concatMap (splitOn ',') $ lines cipher | |
let Just plain = find (contains " the ") $ map (decrypt cs) $ keys 3 | |
print $ sum $ map fromEnum plain | |
keys :: Int -> [String] | |
keys n = let xs = ['a'..'z'] in perm xs (map (\x -> [x]) xs) n | |
where | |
perm xs yss@(ys:_) n | length ys >= n = yss | |
perm xs yss n = perm xs (concatMap (\ys -> map (\x -> x:ys) xs) yss) n | |
decrypt :: Enum a => [String] -> [a] -> String | |
decrypt enc key = map (\(e, k) -> toEnum $ (read e) `xor` (fromEnum k)) $ zip enc $ cycle key | |
splitOn :: Eq a => a -> [a] -> [[a]] | |
splitOn d xs = unfoldr splitOn' xs | |
where | |
splitOn' [] = Nothing | |
splitOn' xs | |
| Just index <- findIndex (==d) xs = let (x, rest) = splitAt index xs in | |
Just (x, tail rest) | |
| otherwise = Just (xs, []) | |
contains :: Eq a => [a] -> [a] -> Bool | |
contains xs ys = let m = length xs in | |
any (\n -> xs == (take m $ drop n ys)) [0..length ys-m] |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import Data.Bits (xor) | |
import Data.List (find, isInfixOf, unfoldr) | |
main = do | |
cipher <- readFile "cipher.txt" | |
let cs = concatMap (splitOn ',') $ lines cipher | |
let Just plain = find (isInfixOf " the ") $ map (decrypt cs) $ keys 3 | |
print $ sum $ map fromEnum plain | |
keys :: Int -> [String] | |
keys n = let xs = ['a'..'z'] in perm xs [""] n | |
where | |
perm xs yss 0 = yss | |
perm xs yss n = perm xs [x:ys | ys <- yss, x <- xs] $ n-1 | |
decrypt :: Enum a => [String] -> [a] -> String | |
decrypt enc key = zipWith (\e k -> toEnum $ (read e) `xor` (fromEnum k)) enc $ cycle key | |
splitOn :: Eq a => a -> [a] -> [[a]] | |
splitOn d xs = unfoldr splitOn' xs | |
where | |
splitOn' [] = Nothing | |
splitOn' xs = let (ys, zs) = break (==d) xs in Just (ys, drop 1 zs) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import Data.Bits (xor) | |
import Data.Char (chr, isPrint, isSpace, ord) | |
import Data.List (find, isInfixOf, unfoldr) | |
main = do | |
cipher <- readFile "cipher.txt" | |
let cs = map read $ concatMap (splitOn ',') $ lines cipher | |
let Just plain = find (anyInfixOf [" the ", "The "]) $ filter (all isValid) $ map (decrypt cs) $ keys 3 | |
print $ sum $ map ord plain | |
where | |
anyInfixOf xs x = any (flip isInfixOf x) xs | |
isValid x = any ($ x) [isPrint, isSpace] | |
keys :: Int -> [[Int]] | |
keys n = sequence $ replicate n [ord 'a'..ord 'z'] | |
decrypt :: [Int] -> [Int] -> String | |
decrypt enc key = zipWith (\e k -> chr $ e `xor` k) enc $ cycle key | |
splitOn :: Eq a => a -> [a] -> [[a]] | |
splitOn d xs = unfoldr splitOn' xs | |
where | |
splitOn' [] = Nothing | |
splitOn' xs = let (ys, zs) = break (==d) xs in Just (ys, drop 1 zs) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import Zaneli.Euler (isPrime) | |
limit = 5 | |
main = print $ primes search | |
search :: (Num a, Ord a, Show a) => a -> [a] -> Maybe a | |
search n ps | xs@(_:_) <- concatPrimes ps' (limit-1) = Just $ n + (minimum $ map sum xs) | |
| otherwise = Nothing | |
where ps' = filterConcatPrimes n ps | |
concatPrimes :: (Eq a, Num a, Show b) => [b] -> a -> [[b]] | |
concatPrimes _ 0 = [[]] | |
concatPrimes [] _ = [] | |
concatPrimes (x:xs) n = map (x:) (concatPrimes xs' (n-1)) ++ concatPrimes xs n | |
where xs' = filterConcatPrimes x xs | |
filterConcatPrimes :: (Show a, Show b) => a -> [b] -> [b] | |
filterConcatPrimes n = filter $ isConcatPrime n | |
where | |
isConcatPrime x y = (isPrime $ concatenating x y) && (isPrime $ concatenating y x) | |
concatenating x y = read $ (show x) ++ (show y) | |
-- Zaneli.Euler.primes とほぼ同様の処理を行っているが、mが素数の場合のみret関数を呼びたいため別途定義。 | |
primes :: Integral a => (a -> [a] -> Maybe b) -> b | |
primes ret = primes' 3 [2] [] | |
where | |
primes' m list list' | |
| not $ isPrime list' = primes' (m + 2) list list' | |
| Just r <- ret m list = r | |
| otherwise = primes' (m + 2) (m:list) (list' ++ [m]) | |
where | |
isPrime = all (\x -> m `mod` x /= 0) . takeWhile (\x -> x ^ 2 <= m) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment