Circular prime numbers - haskell

I am trying to convert the following function which test the number if it's prime to another one that test if the integer is a circular prime.
eg. 1193 is a circular prime, since 1931, 9311 and 3119 all are also prime.
So i need to rotate the digits of the integer and test if the number is prime or not. any ideas?
note: I am new to Haskell Programming
isPrime :: Integer -> Bool
isPrime 1 = False
isPrime 2 = True
isPrime n
| (length [x | x <- [2 .. n-1], n `mod` x == 0]) > 0 = False
| otherwise = True
isCircPrime :: Integer -> Bool

You can improve the efficiency and elegance of your isPrime function easily by implementing it as:
isPrime :: Integral i => i -> Bool
isPrime 1 = False
isPrime n = all ((/=) 0 . mod n) (takeWhile (\x -> x*x <= n) [2..])
In order to rotate numbers, we can make use of two helper functions here: one to convert a number to a list of digits, and one to convert a list of digits to a number, we do this in reverse, since that is more convenient to implement, but will not matter:
num2dig :: Integral i => i -> [i]
num2dig n | n < 10 = [n]
| otherwise = r : num2dig q
where (q, r) = quotRem n 10
dig2num :: (Foldable t, Num a) => t a -> a
dig2num = foldr ((. (10 *)) . (+)) 0
Now we can make a simple function to generate, for a list of items, all rotations:
import Control.Applicative(liftA2)
import Data.List(inits, tails)
rots :: [a] -> [[a]]
rots = drop 1 . liftA2 (zipWith (++)) tails inits
So we can use this to construct all rotated numbers:
rotnum :: Integral i => i -> [i]
rotnum = map dig2num . rots . num2dig
For example for 1425, the rotated numbers are:
Prelude Control.Applicative Data.List> rotnum 1425
[5142,2514,4251,1425]
I leave using isPrime on these numbers as an exercise.

Referencing your question here, you can achieve what you want by adding a single new function:
check :: Integer -> Bool
check n = and [isPrime (stringToInt cs) | cs <- circle (intToString n)]
This is to add an easier to understand solution from where you already were in your specific code, as I can see you were asking for that specifically. Usage:
*Main> check 1931
True
*Main> check 1019
False
Mind you, I have made some type-changes. I assume you want each function to be type-specific, due to their names. Full code, taken from your example:
circle :: String -> [String]
circle xs = take (length xs) (iterate (\(y:ys) -> ys ++ [y]) xs)
stringToInt :: String -> Integer
stringToInt x = read (x) :: Integer
intToString :: Integer -> String
intToString x = show x
isPrime :: Integer -> Bool
isPrime 1 = False
isPrime 2 = True
isPrime n
| (length [x | x <- [2 .. n-1], n `mod` x == 0]) > 0 = False
| otherwise = True
check :: Integer -> Bool
check n = and [isPrime (stringToInt cs) | cs <- circle (intToString n)]

Related

Counting "perfect squares" in a list in Haskell

I am new to Haskell and I am struggling to get this concept to work.
I have to use a list of integers as a parameter and count the number of perfect squares (1,4,9,etc) in the list and output that value. So for example, if I entered myfunction[1,5,9] the output would be 2.
So far I have only got one function to work:
myfunction list = map per list
where per y = floor(sqrt (y) * sqrt (y))
Takes the square root of the element multiplied by the square root of the element. My mindset with the above is that I could set the above result equal to the original element. And if they are equal to each other, that would mean they are perfect squares. And then I would increment a value.
My issue is that my book doesn't give me any ideas for how to increment a variable or how to incorporate more than 1 function at a time. And as a result, I've been aimlessly working on this over the course of 3 days.
Thank you in advance for any help, advice, or resources!
fixing your version
first completed your version could look like this:
myfunction list = length $ filter per list
where
per y = floor(sqrt y * sqrt y) == y
this would even type-check but it would not work (try it)
that's because there is a small little problem - let's make it obvious by giving some types:
myfunction :: [Int] -> Int
myfunction list = length $ filter per list
where
per :: Int -> Bool
per y = floor(sqrt y * sqrt y) == y
you get an error:
No instance for (Floating Int) arising from a use of ‘sqrt’
it is trying to say to you that it does not know how to use sqrt for an Int - an easy fix is using fromIntegral and let it convert the Int into something that can:
myfunction :: [Int] -> Int
myfunction list = length $ filter per list
where
per :: Int -> Bool
per y = floor(sqrt (fromIntegral y) * sqrt (fromIntegral y)) == y
this kind of works (wrong answer) but gives an warning - we could get rid of with
myfunction :: [Int] -> Int
myfunction list = length $ filter per list
where
per :: Int -> Bool
per y = floor(sqrt (fromIntegral y :: Double) * sqrt (fromIntegral y)) == y
were we tell Haskell what type to use for the conversion (the warning would tell you that you default to this anyway).
So there is the wrong answer still.
#jpmarinier already told why - the way you test/sqr is sadly not cutting it (at least as I thought you wanted) - here is a fix:
myfunction :: [Int] -> Int
myfunction list = length $ filter per list
where
per :: Int -> Bool
per y = let y' = (fromIntegral y :: Double) in sqrt y' ** 2 == y'
where we first convert y to a Double value y' and test this.
Another option is using a integer-sqr as #jpmarinier mentioned:
myfunction :: [Int] -> Int
myfunction list = length $ filter per list
where
per :: Int -> Bool
per y = squareRoot y * squareRoot y == y
squareRoot :: Int -> Int
squareRoot = floor . sqrt . (fromIntegral :: Int -> Double)
that should finally work.
without floor and sqr:
ok this is maybe a bit to grok for you but here is how you can do this by sieving out the values.
Let's start by creating a (ascending) list of all perfect squares - I don't know which type you want those numbers to be so let's stay generic as well:
-- need later
import Data.List (sort)
perfectSquares :: Enum a => Num a => [a]
perfectSquares = [ n*n | n <- [1..] ]
no let's make a function counting elements from two lists - if the lists are sorted this can be done recursively by walking alongside the lists - I don't know if your input lists are always sorted so let's sort it before:
countOccurances :: (Enum a, Num a, Ord a) => [a] -> [a] -> a
countOccurances from list =
countAlong from $ sort list
where
countAlong [] _ = 0
countAlong _ [] = 0
countAlong allXs#(x:xs) allYs#(y:ys)
| x < y = countAlong xs allYs
| x > y = countAlong allXs ys
| otherwise = 1 + countAlong allXs ys
having both we can combine them for the answer:
import Data.List (sort)
countPerfectSquares :: (Enum a, Num a, Ord a) => [a] -> a
countPerfectSquares = countOccurances perfectSquares
countOccurances :: (Enum a, Num a, Ord a) => [a] -> [a] -> a
countOccurances from list =
countAlong from $ sort list
where
countAlong [] _ = 0
countAlong _ [] = 0
countAlong allXs#(x:xs) allYs#(y:ys)
| x < y = countAlong xs allYs
| x > y = countAlong allXs ys
| otherwise = 1 + countAlong allXs ys
perfectSquares :: Enum a => Num a => [a]
perfectSquares = [ n*n | n <- [1..] ]
Example:
> countPerfectSquares [1,5,9] :: Int
2

Breaking out of If-Then when a certain requirement is met in Haskell

I am given the assignment of coding a hailstone sequence in Haskell. I must be given an integer and create a list of integers ending with the last number 1, eg.
-- > hailstone 4
-- [4,2,1]
-- > hailstone 6
-- [6,3,10,5,16,8,4,2,1]
-- > hailstone 7
-- [7,22,11,34,17,52,26,13,40,20,10,5,16,8,4,2,1]
My answer should have just one 1 at the end, however I do not know how to break out of the loop once reaching 1.
hailstone :: Integer -> [Integer]
hailstone = takeWhile (>=1) . (iterate collatz)
where collatz n = if n == 1
then 1
else if even n
then n `div` 2
else 3*n+1
I end up with infinite 1's at the end of this. How can I fix this?
You can use a function like takeUntil :: (a -> Bool) -> [a] -> [a] from the utility-ht package [hackage]. This function will:
Take all elements until one matches. The matching element is returned, too. This is the key difference to takeWhile (not . p). It holds takeUntil p xs == fst (breakAfter p xs).
So we can use that to include the 1:
import Data.List.HT(takeUntil)
hailstone :: Integer -> [Integer]
hailstone = takeUntil (== 1) . iterate collatz
where collatz 1 = 1
collatz n | even n = div n 2
| otherwise = 3 * n + 1
or we can implment takeUntil ourself:
takeUntil :: (a -> Bool) -> [a] -> [a]
takeUntil p = go
where go [] = []
go (x:xs) | p x = [x]
| otherwise = x : go xs
or with a fold:
takeUntil :: (a -> Bool) -> [a] -> [a]
takeUntil p = foldr (\x y -> x : if p x then [] else y) []
For negative numbers, the collatz can get stuck in an infinite loop:
Prelude> hailstone (-7)
[-7,-20,-10,-5,-14,-7,-20,-10,-5,-14,-7,-20,-10,-5,-14,-7,-20,-10,-5,-14,
We thus might want to change the condition for all numbers less than or equal to 1:
hailstone :: Integer -> [Integer]
hailstone = takeUntil (<= 1) . iterate collatz
where collatz 1 = 1
collatz n | even n = div n 2
| otherwise = 3 * n + 1
All this use of takeUntil, iterate, breaking out has a very imperative feel for me (do something with the numbers until you reach 1 - and then how the hell do I stop? what is the Haskell equivalent of a break statement.....?)
There is nothing wrong with that, and it wil work eventually, but when using Haskell, is often better to think a bit more declaratively: the tail of a hailstone sequence (other than [1]) is another (shorter) hailstone sequence, so hailstone n = n : hailstone (f n) for some f
Thus:
hailstone n
| n == 1 = [1]
| even n = n : hailstone (n `div` 2)
| otherwise = n : hailstone (3*n + 1)
The sole classic library function that seems to offer some hope is unfoldr. It uses the Maybe monad, and returning Nothing is what stops the recursion.
unfoldr :: (b -> Maybe (a, b)) -> b -> [a]
You have to pick the proper function argument:
import Data.List
hailstone :: Integer -> [Integer]
hailstone n =
let next nn = if (even nn) then (div nn 2) else (3*nn+1)
unfn nn = if (nn==1) then Nothing else let nx = next nn in Just (nx,nx)
in
n : (unfoldr unfn n)
main = do
putStrLn $ "hailstone 7 is: " ++ show (hailstone 7)
That way, the stopping criterion is clearly separated from the successor function.

How do I filter numbers which end in other numbers in Haskell?

For instance, I want to extract from a list the numbers that end in 67: 1637767, 9967, 523467...
Compare them modulo 100:
let result = filter ((== 67) . (`mod` 100)) numbers
The other answers will work if all you want is to match a 2-digit number. Here is a more generalized solution:
import Data.List (isSuffixOf)
extractSuff :: Int -> [Int] -> [Int]
extractSuff n xs = filter (\x -> isSuffixOf (show n) (show x)) xs
EDIT:
Upon Guvante's suggestion, I'm adding another solution which doesn't stringify numbers.
extractSuff' :: Int -> [Int] -> [Int]
extractSuff' n xs = filter (\x -> n == (x `mod` (10 ^ (numDigits n)))) xs
where numDigits n
| abs n < 10 = 1
| otherwise = 1 + numDigits (n `div` 10)

Haskell optimization program

Have the task
I need to implement the function Change, which will take the value and split it into the possible combinations from list of coins(random list)
Example:
coins = [2,3,7]
GHCi> change 7
[[2,2,3],[2,3,2],[3,2,2],[7]]
That's what I did:
coins :: Num a => [a]
coins = [2, 3, 7]
change :: (Ord a, Num a) => a -> [[a]]
change n = uniqEl (filter (\x -> sum x == n) take ()(subsequences (replic' n coins coins)))
replic' n x y | n == 1 = y
| otherwise = replic' (n-1) x (y ++ x)
uniqEl :: Eq a => [a] -> [a]
uniqEl [] = []
uniqEl (x:xs) = if (x `elem` xs) then uniqEl xs else x : (uniqEl xs)
But this code is very slow. Help to make this program more quickly. As part of the job it is said that this task is easily done with the help of generators lists and recursion. Thank you in advance for your help.
import Data.List
change :: [Int] -> Int -> [[Int]]
change _ 0 = []
change coins n = do
x <- [c | c <- coins, c <= n]
if x == n
then return [x]
else do
xs <- change coins (n - x)
-- if (null xs)
-- then return [x]
-- else if x < (head xs)
-- then []
-- else return (x:xs)
return (x:xs)
change' :: Int -> [[Int]]
change' = change [2,3,7]
test7 = change' 7
test6 = change' 6
test5 = change' 5
test4 = change' 4
You're doing a lot of filtering, eleming and so on, and placing a lot of constraints on the data types.
Think of this more as a dynamic problem, that you constantly need to figure out how many ways there are to return change for a total amount.
Once you have found the amount of possibilities for a specific coin, you can remove it from the list.
Here is my proposed solution wrapped up in one function.
In the list comprehension, note that I assign values to the remaining variable, and that these values range from [0,total], with jumps every x, where x is the denomination.
For example, if you had to calculate how many times $0.25 goes into a $2 total, that list comprehension ends up doing:
[countChange 2, countChange 1.75,countChange 1.5, countChange 1.25,...], but also these next iterations of countChange don't include the 0.25 coin - because we just "tested" that.
-- Amount to return -> List of Coin denominations available
countChange :: Integer -> [Integer] -> Integer
countChange _ [] = 0 -- No coins at all, so no change can be given
countChange 0 _ = 1 -- Only one way to return 0 change
countChange total (x:xs) = sum [countChange (total-remaining) xs | remaining <- [0,x..total]]
Use MemoCombinators. This is fast ! Pls. try change 100
import Data.List
import qualified Data.MemoCombinators as Memo
coins :: [Int]
coins = [2,3,7]
change :: Int -> [[Int]]
change = Memo.integral change'
change' 0 = []
change' n = do
x <- [c | c <- coins, c <= n]
if x == n
then return [x]
else do
xs <- change (n - x)
-- if (null xs)
-- then return [x]
-- else if x < (head xs)
-- then []
-- else return (x:xs)
return (x:xs)

Haskell sublists

I have to make a function that finds specific sublists.
function :: Integer -> Integer -> [[Integer]]
function n m = …
If m is smaller then n the program exits.
If the (mod (sum [1..n]) m) /= 0 then again error.
Otherwise the program should find sublists.
And the primary list is generated from [1..n]
For example, if the numbers are n = 6 and m = 7. List is [1,2,3,4,5,6] The answer is [[6,1],[5,2],[4,3]].
function 6 7
>>> [[6,1],[5,2],[4,3]]
Order is not necessary. So on I have made these steps. Any help would be useful.Also example codes would be useful. If anyone can solve this problem, I would appreciate it. Code with solution would be very useful for me.
function :: Integer -> Integer -> [[Integer]]
function n m
|m < n = error "m is smaller than n"
|(mod (sum [1..n]) m) /= 0 = error "list sum doesn't devide with m"
|otherwise = …
I would go and create all lists with sum property, for example using list comprehension. And then filtering by the uniqueness property, by something like:
taking list difference of the first sublist and the generatorlist and checking if the next sublist is contained in the generator,
then deleting a sublist if it is not subset of the altered generator
or doing the same procedure as in 1.
you can end the procedure if the sum of the altered generators is less than m
note that the result is depending on how you have sorted all sublists - so the solution is not a unique longest list of sublists, but just one of many results possible with sum and "uniqueness" property.
Edit: Some Code - not perfect maximum solution
just something to start and think about i only collect easy two element lists and otherwise take one maximal list.
The next improvements would be to make a function collecting not only easy but all two element lists and then generalize this to get sublists of a given length, maybe you want to have a look a bit at elementary combinatorics.
module Sublists where
import Data.List ((\\))
subLists :: Int -> Int -> [[Int]]
subLists n = subLists' ([],[1..n])
subLists' :: ([[Int]],[Int]) -> Int -> [[Int]]
subLists' aa m = fst (mLSubLists (tLSubLists aa m) m)
_subLists :: ([Int] -> Int -> [Int]) -> ([[Int]],[Int]) -> Int -> ([[Int]],[Int])
_subLists _ yx#(_,[ ]) _ = yx
_subLists _ yx#(_,[_]) _ = yx
_subLists f yx#(yy,xx) m | sum xx < m = yx
| otherwise = if tt == []
then yx
else _subLists f (tt:yy,xx\\tt) m
where tt = f xx m
tLSubLists :: ([[Int]],[Int]) -> Int -> ([[Int]],[Int])
tLSubLists = _subLists twoList
mLSubLists :: ([[Int]],[Int]) -> Int -> ([[Int]],[Int])
mLSubLists = _subLists manyList
twoList :: [Int] -> Int -> [Int]
twoList [ ] _ = []
twoList [_] _ = []
twoList xx#(x:xs) m | (x + l) < m = []
| x == l = []
| (x + l) `rem` m == 0 = [x,l]
| otherwise = twoList ii m
where l = last xs
ii = init xx
manyList :: [Int] -> Int -> [Int]
manyList xx m | s < m = []
| s == m = xx
| s `rem` m == 0 = xx
| otherwise = manyList xs m
where s = sum xx
xs = tail xx
and some test cases:
import Sublists
import Test.HUnit
import Data.List ((\\))
main = testAll
testAll = runTestTT $ TestList tests
tests :: [Test]
tests = [
"n=6 m=7" ~: "subLists" ~: [[3,4],[2,5],[1,6]]
~=? subLists 6 7,
"n=6 m=7" ~: "twoList" ~: [1,6]
~=? twoList [1..6] 7,
"n=6 m=7" ~: "twoList" ~: [2,5]
~=? twoList ([1..6]\\[1,6]) 7,
"n=6 m=7" ~: "twoList" ~: [3,4]
~=? twoList (([1..6]\\[1,6])\\[2,5]) 7,
"n=6 m=7" ~: "manyList" ~: [2,3,4,5]
~=? manyList [1..5] 7,
"dummy" ~: "dummy" ~: "result"
~=? (\_ -> "result") "function"
]
The function subsequences in Data.List might be helpful, e.g.
subsequences "abc" == ["","a","b","ab","c","ac","bc","abc"]
Then you "just" need to filter out all sub-lists that don't match your criterias.

Resources