I need to find all the twin primes up to an inputted number. After my trying it out this is the closest i can get:
primeTwins :: Integer -> [Integer]
primeTwins x = [y | x <- [2..x], y <- [x-2, x+2]]
If x is 20 prime Twins returns: [0,4,1,5,3,7,5,9,9,13,11,15,15,19,17,21]
So this returns primes +2 and primes -2 and with duplicates, However i need just twin primes (A twin prime is a prime number that is either 2 less or 2 more than another prime number) with no duplication. Ive been searching but cant find a way to sort lists. Im very new to haskell, So any help would be appreciated!
First of all, it'd be nice to have an infinite list of primes:
primes :: [Integer]
primes = 2:3:filter
(\n -> not $ any
(\p -> n `mod` p == 0)
(takeWhile (\p -> p * p <= n) primes))
[5,7..]
This is similar to the Sieve of Eratosthenes, checking only prime factors up to the square root of the number. For reference, take 20 primes is [2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71], so it works properly. Now, we want to filter out just the twin primes into another infinite list:
infTwinPrimes :: [Integer]
-- we need to manually enter 3 5 7 since 5 is a part of two pairs
infTwinPrimes = 3:5:7:(
-- we convert the tuple into a list
( >>= \(a, b) -> [a, b])
$ filter (\(a, b) -> b - a == 2)
-- we drop 4 to compensate for manually entering 3, 5, 7
$ drop 4
-- we zip primes with its tail in order to
-- get every element in a tuple with the next element
$ zip primes (tail primes)
)
If you're confused, it might help to think about how zip primes (tail primes) is [(2,3),(3,5),(5,7),(7,11),(11,13),(13,17),(17,19),...], and how [(1, 2), (3, 4)] >>= \(a, b) -> [a, b] is [1, 2, 3, 4]. Now, our twin primes function is as easy as a takeWhile:
twinPrimes :: Integer -> [Integer]
twinPrimes n = takeWhile (<= n) infTwinPrimes
And we can verify that it works
λ> twinPrimes 20
[3,5,7,11,13,17,19]
Which does indeed contain every twin prime up to 20.
Related
--for number divisible by 15 we can get it easily
take 10 [x | x <- [1..] , x `mod` 15 == 0 ]
--but for all how do I use the all option
take 10 [x | x <- [1..] , x `mod` [2..15] == 0 ]
take 10 [x | x <- [1..] , all x `mod` [2..15] == 0 ]
I want to understand how to use all in this particular case.
I have read Haskell documentation but I am new to this language coming from Python so I am unable to figure the logic.
First you can have a function to check if a number is mod by all [2..15].
modByNumbers x ns = all (\n -> x `mod` n == 0) ns
Then you can use it like the mod function:
take 10 [x | x <- [1..] , x `modByNumbers` [2..15] ]
Alternatively, using math, we know that the smallest number divible by all numbers less than n is the product of all of the prime numbers x less than n raised to the floor of the result of logBase x n.
A basic isPrime function:
isPrime n = length [ x | x <- [2..n], n `mod` x == 0] == 1
Using that to get all of the primes less than 15:
p = [fromIntegral x :: Float | x <- [2..15], isPrime x]
-- [2.0,3.0,5.0,7.0,11.0,13.0]
Now we can get the exponents:
e = [fromIntegral (floor $ logBase x 15) :: Float | x <- p']
-- [3.0,2.0,1.0,1.0,1.0,1.0]
If we zip these together.
z = zipWith (**) p e
-- [8.0,9.0,5.0,7.0,11.0,13.0]
And then find the product of these we get the smallest number divisible by all numbers between 2 and 15.
smallest = product z
-- 360360.0
And now to get the rest we just need to multiply that by the numbers from 1 to 15.
map round $ take 10 [smallest * x | x <- [1..15]]
-- [360360,720720,1081080,1441440,1801800,2162160,2522520,2882880,3243240,3603600]
This has the advantage of running substantially faster.
Decompose the problem.
You already know how to take the first 10 elements of a list, so set that aside and forget about it. There are infinitely many numbers divisible by all of [2,15], your remaining task is to list them all.
There are infinitely many natural numbers (unconstrained), and you already know how to list them all ([1..]), so your remaining task is to transform that list into the "sub-list" who's elements are divisible by all of [2,15].
You already know how to transform a list into the "sub-list" satisfying some constraint (predicate :: X -> Bool). You're using a list comprehension in your posted code, but I think the rest of this is going to be easier if you use filter instead. Either way, your remaining task is to represent "is divisible by all of [2,15]" as a predicate..
You already know how to check if a number x is divisible by another number y. Now for something new: you want to abstract that as a predicate on x, and you want to parameterize that predicate by y. I'm sure you could get this part on your own if asked:
divisibleBy :: Int -> (Int -> Bool)
divisibleBy y x = 0 == (x `mod` y)
You already know how to represent [2,15] as [2..15]; we can turn that into a list of predicates using fmap divisibleBy. (Or map, worry about that difference tomorrow.) Your remaining task is to turn a list of predicates into a predicate.
You have a couple of options, but you already found all :: (a -> Bool) -> [a] -> Bool, so I'll suggest all ($ x). (note)
Once you've put all these pieces together into something that works, you'll probably be able to boil it back down into something that looks a little bit like what you first wrote.
I recently started learning Haskell. To train a bit I wanted to try generating the list of prime numbers via self reference using the following code:
main = do
print (smaller_than_sqrt 4 2)
print (smaller_than_sqrt_list 5 [2..])
print ("5")
print (is_prime 5 [2..])
print ("7")
print (is_prime 7 [2..])
print ("9")
print (is_prime 9 [2..])
print ("test")
print (take 5 primes) -- Hangs
-- Integer square root
isqrt :: Int -> Int
isqrt = ceiling . sqrt . fromIntegral
-- Checks if x is smaller than sqrt(p)
smaller_than_sqrt :: Int -> Int -> Bool
smaller_than_sqrt p x = x <= isqrt p
-- Checks if x doesn't divide p
not_divides :: Int -> Int -> Bool
not_divides p x = p `mod` x /= 0
-- Takes in a number and an ordered list of numbers and only keeps the one smaller than sqrt(p)
smaller_than_sqrt_list :: Int -> [Int] -> [Int]
smaller_than_sqrt_list p xs = takeWhile (smaller_than_sqrt p) xs
-- Checks if p is prime by looking at the provided list of numbers and checking that none divides p
is_prime :: Int -> [Int] -> Bool
is_prime p xs = all (not_divides p) (smaller_than_sqrt_list p xs)
-- Works fine: primes = 2 : [ p | p <- [3..], is_prime p [2..]]
-- Doesn't work:
primes = 2 : 3 : [ p | p <- [5..], is_prime p primes]
But for some reason referencing primes inside of primes hangs when running runhaskell and is detected as a loop error when running the compiled binary with ghc.
However I don't really understand why.
Clearly, the first two elements of primes are 2 and 3. What comes after that? The next element of primes is the first element of
[p | p <- [5..], is_prime p primes]
What's that? It could be 5, if is_prime 5 primes, or it could be some larger number. To find out which, we need to evaluate
smaller_than_sqrt_list 5 primes
Which requires
takeWhile (<= isqrt 5) primes
Which requires
takeWhile (<= 3) primes
Well, that's easy enough, it starts with 2:3:..., right? Okay, but what's the next element? We need to look at the third element of primes and see whether it's less or equal to 3. But the third element of primes is what we were trying to calculate to begin with!
The problem is that smaller_than_sqrt 5 3 is still True. To compute whether 5 is a prime, the is_prime 5 primes expands to all (not_divides 5) (takeWhile (smaller_than_sqrt 5) primes), and takeWhile will attempt to iterate primes until the predicate no longer holds. It does hold for the first element (2), it still does hold for the second element (3), will it hold for the next element - wait what's the next element? We're still computing which one that is!
It should be sufficient to use floor instead of ceiling in isqrt, or simpler just
smaller_than_sqrt p x = x * x <= p
I need to find all the subsets of squares that is equal to given square number.Ex:
f (11^2) --> f (121) --> [1,2,4,10],[2,6,9] all there sum of individual squares is equal to 121.
First I tried to find all the possible combinations of sums that is equal sum of given number.Code that I have tried
squares x = map (\x -> x * x ) [1..x]
--Using Subsequences,to create [subsequences][1] of the list
f n = filter (\x -> sum x == n) (subsequences.map (\y -> y *y) $ [1..(sqrt n)])
But Sequences of a big number produces huge list Ex: f (50^2) takes long time.Is there is any other approach to proceed efficiently?
Let's say we want to pick from the 50 lowest square values in descending order, starting with this list: [2500, 2401, ... , 16, 9, 4, 1] and targeting a sum of 2500.
The problem with your subsequences-based algorithm is that it is going to generate and test all value subsequences. But it is for example pointless to test subsequences starting with [49*49, 48*48], because 49*49 + 48*48 = 4705 > 2500.
The subsequences-based algorithm does not maintain a running sum, also known as an accumulator. Considering the subsequences as a virtual tree, an accumulator allows you to eliminate whole branches of the tree at once, rather than having to check all possible leaves of the tree.
It is possible to write a recursive algorithm which maintains an accumulator for the partial sum. First, we need an auxiliary function:
import Data.List (tails, subsequences)
getPairs :: [a] -> [(a,[a])]
getPairs xs = map (\(x:xs) -> (x,xs)) $ filter (not . null) $ tails xs
Usage:
$ ghci
GHCi, version 8.8.4: https://www.haskell.org/ghc/ :? for help
...
λ>
λ> printAsLines xs = mapM_ (putStrLn . show) xs
λ>
λ> printAsLines $ getPairs $ reverse $ map (^2) [1..8]
(64, [49,36,25,16,9,4,1])
(49, [36,25,16,9,4,1])
(36, [25,16,9,4,1])
(25, [16,9,4,1])
(16, [9,4,1])
(9, [4,1])
(4, [1])
(1, [])
λ>
λ>
(Note: edited for readability)
Above, the left element of each pair is the element to be added to the running sum, while the right element is the list of remaining values that can still be considered for addition.
We can thus provide a general recursive algorithm for partial sums:
getSummations :: Int -> [Int] -> [[Int]]
getSummations s xs = go [] 0 xs
where
-- go prefix runningSum restOfValues
go prefix acc ys
| (acc > s) = [] -- all rejected
| (acc == s) = [prefix] -- cannot add further values
| otherwise =
let pairs = getPairs ys
in concat $ map (\(k,zs) -> go (k:prefix) (acc+k) zs) pairs
-- or: concatMap (\(k,zs) -> go (k:prefix) (acc+k) zs) pairs
Here, prefix is the list of values already included in the summation, and s is the target sum.
Note that the pruning of “dead branches” is done by the following lines:
| (acc > s) = [] -- all rejected
| (acc == s) = [prefix] -- cannot add further values
Next, we can specialize the mechanism for our square values:
getSquareSummations :: Int -> [[Int]]
getSquareSummations n = getSummations (n*n) (reverse $ map (^2) [1..n])
For comparison purposes, the subsequences-based algorithm can be written like this:
naiveGetSquareSummations :: Int -> [[Int]]
naiveGetSquareSummations n = let xss = subsequences $ map (^2) [1..n]
in filter (\xs -> sum xs == n*n) xss
Using GHC v8.8.4 with -O2, the expression getSquareSummations 50 returns the list of 91021 possible subsequences summing to 2500, in less than one second. This is with a vintage 2014 Intel x86-64 CPU, Intel(R) Core(TM) i5-4440 # 3.10GHz.
I am currently working on trying to find the number of primes between a range in haskell. The program prints out the range of primes correctly. E.g countPrimesUntil 2 10 will print out [2, 3, 5, 7]. I am looking for the number 4 because that's how many primes is between 2 and 10. How do I incorporate countPrimes correctly?
import Data.List
countPrimesUntil :: Integral a=> a -> a -> [a]
countPrimesUntil a b = takeWhile (<= b) $ dropWhile (< a) $ sieve [2..]
while sieve (n:ns) = n:sieve [m | m <- ns, m `mod` n /= 0]
countPrimes n = length([x | x <- [2..n], countPrimesUntil x])
countPrimesUntil is misnamed; it doesn't count anything. Rather, it produces a list of primes between a and b, inclusive.
All you need to do is apply length to the result of countPrimesUntil, when given arguments 2 and n.
countPrimes n = length (countPrimesUntil 2 n)
-- countPrimes = length . countPrimesUntil 2
In that case the countPrimes calls countPrimesUntil 2 n, and determines it length, so:
countPrimes n = length (countPrimesUntil 2 n)
Hi I am new in Haskell and I came across an interesting problem but I was not really sure on how I would go about solving it. I am about to show you only two parts of the question as an example.
The question is that we are to input a number between 13 to 15 digits.
then from that number we remove the last number. such as 19283828382133 should out put the exact same number just without the final 3, 1928382838213.
Then every odd digit(not number) from these numbers will be doubled. So you will get 2,9,4,8,6 etc
This is my code so far. As you can see from the code I have been able to complete these two parts individually(working) but I am not sure how I would add them together.
lastdigit :: Integer -> Integer -- This Function removes the last number
lastdigit x = x`div`10
doubleOdd (x:xs) = (2*x):(doubleEven xs) -- This function doubles every odd digit not number.
doubleOdd [] = []
doubleEven (x:xs) = x:(doubleOdd xs)
doubleEven [] = []
So to further explain the program I am trying to build will first go through the step of taking in the number between 13 to 15 digits. Then it will first remove the last number then automatically go to the next step of doubling each odd digit(not number). Thanks
First, you need a way to break some large number into digits.
digits :: Integral x => x -> [x]
digits 0 = []
digits x = digits (x `div` 10) ++ [x `mod` 10]
Which gives you...
Prelude> digits 12345
[1,2,3,4,5]
You can then drop the last digit with init
Prelude> (init . digits) 12345
[1,2,3,4]
The a helper function to map over odd elements in a list.
mapOdd _ [] = []
mapOdd f (x:[]) = [f x]
mapOdd f (x:y:rest) = f x : y : mapOdd f rest
Giving you...
Prelude> mapOdd (+10) [1..10]
[11,2,13,4,15,6,17,8,19,10]
And a function to get back to a large number...
undigits = sum . zipWith (*) [10^n | n <- [0..]] . reverse
Resulting in...
Prelude> undigits [1, 2, 3, 4]
1234
And putting it all together
Prelude> undigits . mapOdd (*2) . init . digits $ 12345
2264
In functional languages particularly, always try to solve a problem by composing solutions to smaller problems :)
The missing component is a way to break down an integer into its digits, and build it back up from there. That's easy:
digits:: Int -> [Int]
digits = map (`mod` 10) . takeWhile (/= 0) . iterate (`div` 10)
undigits :: [Int] -> Int
undigits = foldr f 0 where f i r = 10 * r + i
Then it looks like you need to post-process those digits in two different ways, but only if they match a predicate. Let's build a combinator for that:
when :: (a -> Bool) -> (a -> a) -> a -> a
when p f a = if p a then f a else a
The first case appears when you want to double digits in odd position (from left to right). Again trivial, with the minor inconvenience that digits breaks down a number by increasing power of ten. Let's prefix each number by its position:
prefix :: [Int] -> [(Int, Int)]
prefix is = let n = length is in zip [n, n-1..1] is
doubleOdd can now be expressed as
doubleodd :: [Int] -> [Int]
doubleodd = map (snd . when (odd . fst) (id *** double)) . prefix
You mentioned in a comment that when the double number overflows, its digits must be added together. This is the second case I was referring to and is again simplicity itself:
double :: Int -> Int
double = when (>= 10) (sum . digits) . (* 2)
Here is your final program:
program = undigits . doubleodd . tail . digits
... assuming the "between 13 and 15 digits" part is verified separately.
I hope this helps and realize it could be cleaned up a lot. List indices start with 0 which is also an even number and the first element of a list. The list comprehension processes 0,2,4 ... the 1st,2nd and 3rd items.
let f n = [mod n 10] ++ f (div n 10)
let r = [if even i then d*2 else d|(i,d)<-zip [0..] (init.reverse.take 14.f$19283828382133)]
sum [b*(10^a)|(a,b) <- zip [12,11..0] r]
2948684868416
If you want it to handle any length number, the easiest way here is length $ show 19283828382133 but I do have a function somewhere that does that. Use the length as a value in 3 places, once at full value in thetake function in the composition.