From 02d4adc3aa84086240cd2c2a927888035282f312 Mon Sep 17 00:00:00 2001 From: Daniele Fucini Date: Wed, 20 Nov 2024 19:39:00 +0100 Subject: [PATCH] Add Haskell solutions for Problems 26 and 27 --- Haskell/p026.hs | 38 ++++++++++++++++++++++++++++++++++++++ Haskell/p027.hs | 37 +++++++++++++++++++++++++++++++++++++ 2 files changed, 75 insertions(+) create mode 100644 Haskell/p026.hs create mode 100644 Haskell/p027.hs diff --git a/Haskell/p026.hs b/Haskell/p026.hs new file mode 100644 index 0000000..4e34674 --- /dev/null +++ b/Haskell/p026.hs @@ -0,0 +1,38 @@ +-- A unit fraction contains 1 in the numerator. The decimal representation of the unit fractions with denominators 2 to 10 are given: +-- +-- 1/2 = 0.5 +-- 1/3 = 0.(3) +-- 1/4 = 0.25 +-- 1/5 = 0.2 +-- 1/6 = 0.1(6) +-- 1/7 = 0.(142857) +-- 1/8 = 0.125 +-- 1/9 = 0.(1) +-- 1/10 = 0.1 +-- +-- Where 0.1(6) means 0.166666..., and has a 1-digit recurring cycle. It can be seen that 1/7 has a 6-digit recurring cycle. +-- +-- Find the value of d < 1000 for which 1/d contains the longest recurring cycle in its decimal fraction part. + +removeFactor :: (Integral a) => a -> a -> a +removeFactor f n + | n `mod` f /= 0 = n + | otherwise = removeFactor f (n `div` f) + +findCycleLengthRecursive :: (Integral a) => a -> a -> a -> a +findCycleLengthRecursive n j k + | n == 1 = 0 + | k `mod` n == 0 = j + | otherwise = findCycleLengthRecursive n (j+1) (k * 10 + 9) + +findCycleLength :: (Integral a) => a -> a +findCycleLength n = findCycleLengthRecursive ((removeFactor 2 . removeFactor 5) n) 1 9 + +maxRepeatingCycle :: (Integral a) => a -> a -> a +maxRepeatingCycle a b = snd . maximum $ zip xs [1..] + where xs = map findCycleLength [a..b] + +main = do + let result = maxRepeatingCycle 1 999 + putStrLn $ "Project Euler, Problem 26\n" + ++ "Answer: " ++ show result diff --git a/Haskell/p027.hs b/Haskell/p027.hs new file mode 100644 index 0000000..b6ce20c --- /dev/null +++ b/Haskell/p027.hs @@ -0,0 +1,37 @@ +-- Euler discovered the remarkable quadratic formula: +-- +-- n^2+n+41 +-- +-- It turns out that the formula will produce 40 primes for the consecutive integer values 0≤n≤39. However, when n=40,402+40+41=40(40+1)+41 is +-- divisible by 41, and certainly when n=41,412+41+41 is clearly divisible by 41. +-- +-- The incredible formula n^2−79n+1601 was discovered, which produces 80 primes for the consecutive values 0≤n≤79. +-- The product of the coefficients, −79 and 1601, is −126479. +-- +-- Considering quadratics of the form: +-- +-- n^2+an+b, where |a|<1000 and |b|≤1000 +-- +-- where |n| is the modulus/absolute value of n +-- e.g. |11|=11 and |−4|=4 +-- +-- Find the product of the coefficients, a and b, for the quadratic expression that produces the maximum number of primes for consecutive values of n, +-- starting with n=0. + +import Data.List (maximumBy) +import Data.Function (on) +import ProjectEuler (isPrime) + +findLengthPrimeSequence :: Int -> Int -> Int +findLengthPrimeSequence a b = length $ takeWhile isPrime [ n*n + a*n + b | n <- [0..] ] + +findCoefficients = let as = [-999..999] + bs = filter isPrime [2..1000] + cs = [ (a, b) | a <- as, b <- bs ] + in fst $ maximumBy (compare `on` snd) [ (c, l) | c <- cs, let l = uncurry findLengthPrimeSequence c ] + +main = do + let coefficients = findCoefficients + result = uncurry (*) coefficients + putStrLn $ "Project Euler, Problem 27\n" + ++ "Answer: " ++ show result