How can I create non-repeating palindromic numbers? - haskell

So I'm trying to do something and it's almost there I think but I can't solve the last part of it. I have to make a code where someone gives a number (let's make it 22) an I need to find all the palindromic numbers there is when I multiply two numbers smaller than 22:
Find all the palindromic numbers of a*b but a < n && b < n. but they can't repeat themselves.
I got this
calc :: Int -> [Int]
calc n = [a*b|a<-[1..n-1], b<-[a..n-1], a*b>10, reverse(show(a*b))==show(a*b)]
If we do calc 22 the result should be
[11,22,33,44,55,66,77,88,99,171,121,252,272,323]
but I'm getting
[11,22,33,44,55,66,77,88,99,171,121,252,252,272,323]
because 14x18 = 12x21 = 252.
Where did I go wrong?

Well, you have to make sure that every number is unique. There exist multiple representations for all numbers with at least three prime factors (x * y * z = (x * y) * z = x * (y * z)). So one way we could tacke this would be prime factor analysis and reasoning about them. But that's probably an overkill.
Instead, we can use a function that makes sure that every number in our sorted list is unique:
unique :: Eq a => [a] -> [a]
unique (x:y:xs) = if x == y then unique (y:xs) else x : unique (y:xs)
unique xs = xs
(Alternatively, use unique = map head . group)
Now you can use sort from Data.List and you end up with your actual calUniuqe:
calcUnique :: Int -> [Int]
calcUnique = unique . sort . calc
However, we can make calc a lot easier to read if we move the palindrome check into its own function:
isPalindrome :: Int -> Bool
isPalindrome n = n > 10 && reverse n' == n'
where n' = show n
calc :: Int -> [Int]
calc n = [a * b | a <- [1..n-1], b <- [a..n-1], isPalindrome (a * b)]

Related

Prime Factorization in Haskell to return a list of tuples giving the number and the power

I have been trying to learn haskell by trying to do some simple problems.
The Problem
Currently, I am trying to implement a function primeFactorization :: Integer -> [(Integer, Integer)] such that the output is a list of tuples containing the prime factor and the power it is raise to in the number.
Example Output
> primeFactorization 120
[(2,3), (3,1), (5,1)] since 120 = 2^3 * 3^1 * 5^1
My (Partial) Solution
primeFactorization :: Integer -> [Integer]
primeFactorization n =
let
factors :: Integer -> [Integer]
factors n = [x | x <- [2..n-1], n `mod` x == 0]
isPrime :: Integer -> Bool
isPrime n
| n `elem` [0, 1] = False
| n == 2 = True
| n > 2 = null [ x | x <- [2..(ceiling . sqrt . fromIntegral) n], n `mod` x == 0]
| otherwise = False
in
filter isPrime $ (factors n)
This is a working implementation to get the prime factors of a number. However as seen it only outputs the prime factors. I am not sure on how to store the number of times in haskell. Also, considering it is un-idiomatic to iterate in haskell I don't know how I would implement the solution. In python, I would do:
def pf(number):
factors=[]
d=2
while(number>1):
while(number%d==0):
factors.append(d)
number=number/d
d+=1
return factors
So, the question: How to implement the powers of the prime factors?
NOTE:
I already saw: Prime factorization of a factorial however that does not answer my question.
This is NOT a homework problem, I am learning independently.
You can always replace imperative-language loops (as long as they don't meddle with any global state) with recursion. That may not be the most elegant approach, but in this case it seems perfectly appropriate to imitate your inner Python loop with a recursive function:
dividerPower :: Integer -> Integer -> Int
dividerPower n d
| n`rem`d == 0 = 1 + dividerPower (n`quot`d) d
| otherwise = 0
(This counts “backwards” compared to the Python loop. You could also make it tail-recursive with a helper function and count forwards over an accumulator variable, but that's more awkward and I don't think there's a memory/performance benefit that would justify it in this case.)
You can either use that together with your Haskell code (for each of the factors you've already found, check how often it occurs), or extend it so the whole thing works like the Python solution (which is actually a lot more efficient, because it avoids for every number checking whether it's prime). For that you just need to give back the final n in the result. Let's use a where block for handling the pattern matching, and also make the rem and:
dividePower :: Integer -> Integer -> (Integer, Int)
dividePower n d
| r == 0 = (nfin, p'+1)
| otherwise = (n, 0)
where (n', r) = n `quotRem` d
(nfin, p') = dividePower n' d
Then the equivalent to your Python code is
pf :: Integer -> Integer -> [(Integer, Int)]
pf = go 2
where go d n
| n>1 = (d, p) : go (d+1) n'
| otherwise = []
where (n', p) = dividePower n d
This actually gives you, like in Python, the list including also non-dividers (with power 0). To avoid that, change the list-building to
| n>1 = (if p>0 then ((d,p):) else id) $ go (d+1) n'

How to break a number into a list of digits? [duplicate]

Given an arbitrary number, how can I process each digit of the number individually?
Edit
I've added a basic example of the kind of thing Foo might do.
For example, in C# I might do something like this:
static void Main(string[] args)
{
int number = 1234567890;
string numberAsString = number.ToString();
foreach(char x in numberAsString)
{
string y = x.ToString();
int z = int.Parse(y);
Foo(z);
}
}
void Foo(int n)
{
Console.WriteLine(n*n);
}
Have you heard of div and mod?
You'll probably want to reverse the list of numbers if you want to treat the most significant digit first. Converting the number into a string is an impaired way of doing things.
135 `div` 10 = 13
135 `mod` 10 = 5
Generalize into a function:
digs :: Integral x => x -> [x]
digs 0 = []
digs x = digs (x `div` 10) ++ [x `mod` 10]
Or in reverse:
digs :: Integral x => x -> [x]
digs 0 = []
digs x = x `mod` 10 : digs (x `div` 10)
This treats 0 as having no digits. A simple wrapper function can deal with that special case if you want to.
Note that this solution does not work for negative numbers (the input x must be integral, i.e. a whole number).
digits :: Integer -> [Int]
digits = map (read . (:[])) . show
or you can return it into []:
digits :: Integer -> [Int]
digits = map (read . return) . show
or, with Data.Char.digitToInt:
digits :: Integer -> [Int]
digits = map digitToInt . show
the same as Daniel's really, but point free and uses Int, because a digit shouldn't really exceed maxBound :: Int.
Using the same technique used in your post, you can do:
digits :: Integer -> [Int]
digits n = map (\x -> read [x] :: Int) (show n)
See it in action:
Prelude> digits 123
[1,2,3]
Does that help?
You could also just reuse digits from Hackage.
Textbook unfold
import qualified Data.List as L
digits = reverse . L.unfoldr (\x -> if x == 0 then Nothing else Just (mod x 10, div x 10))
You can use
digits = map (`mod` 10) . reverse . takeWhile (> 0) . iterate (`div` 10)
or for reverse order
rev_digits = map (`mod` 10) . takeWhile (> 0) . iterate (`div` 10)
The iterate part generates an infinite list dividing the argument in every step by 10, so 12345 becomes [12345,1234,123,12,1,0,0..]. The takeWhile part takes only the interesting non-null part of the list. Then we reverse (if we want to) and take the last digit of each number of the list.
I used point-free style here, so you can imagine an invisible argument n on both sides of the "equation". However, if you want to write it that way, you have to substitute the top level . by $:
digits n = map(`mod` 10) $ reverse $ takeWhile (> 0) $ iterate (`div`10) n
Via list comprehension:
import Data.Char
digits :: Integer -> [Integer]
digits n = [toInteger (digitToInt x) | x <- show n]
output:
> digits 1234567890
[1,2,3,4,5,6,7,8,9,0]
I was lazy to write my custom function so I googled it and tbh I was surprised that none of the answers on this website provided a really good solution – high performance and type safe. So here it is, maybe somebody would like to use it. Basically:
It is type safe - it returns a type checked non-empty list of Word8 digits (all the above solutions return a list of numbers, but it cannot happen that we get [] right?)
This one is performance optimized with tail call optimization, fast concatenation and no need to do any reversing of the final values.
It uses special assignment syntax which in connection to -XStrict allows Haskell to fully do strictness analysis and optimize the inner loop.
Enjoy:
{-# LANGUAGE Strict #-}
digits :: Integral a => a -> NonEmpty Word8
digits = go [] where
go s x = loop (head :| s) tail where
head = fromIntegral (x `mod` 10)
tail = x `div` 10
loop s#(r :| rs) = \case
0 -> s
x -> go (r : rs) x
Here's an improvement on an answer above. This avoids the extra 0 at the beginning ( Examples: [0,1,0] for 10, [0,1] for 1 ). Use pattern matching to handle cases where x < 10 differently:
toDigits :: Integer -> [Integer] -- 12 -> [1,2], 0 -> [0], 10 -> [1,0]
toDigits x
| x < 10 = [x]
| otherwise = toDigits (div x 10) ++ [mod x 10]
I would have put this in a reply to that answer, but I don't have the needed reputation points :(
Applicative. Pointfree. Origami. Neat.
Enjoy:
import Data.List
import Data.Tuple
import Data.Bool
import Control.Applicative
digits = unfoldr $ liftA2 (bool Nothing) (Just . swap . (`divMod` 10)) (> 0)
I've been following next steps(based on this comment):
Convert the integer to a string.
Iterate over the string
character-by-character.
Convert each character back to an integer,
while appending it to the end of a list.
toDigits :: Integer -> [Integer]
toDigits a = [(read([m])::Integer) | m<-show(a)]
main = print(toDigits(1234))
For returning a list of [Integer]
import Data.Char
toDigits :: Integer -> [Integer]
toDigits n = map (\x -> toInteger (digitToInt x)) (show n)
The accepted answer is great but fails in cases of negative numbers since mod (-1) 10 evaluates to 9. If you would like this to handle negative numbers properly... which may not be the case the following code will allow for it.
digs :: Int -> [Int]
digs 0 = []
digs x
| x < 0 = digs ((-1) * x)
| x > 0 = digs (div x 10) ++ [mod x 10]
The accepted answer is correct except that it will output an empty list when input is 0, however I believe the output should be [0] when input is zero.
And I don't think it deal with the case when the input is negative. Below is my implementation, which solves the above two problems.
toDigits :: Integer -> [Integer]
toDigits n
| n >=0 && n < 10 = [n]
| n >= 10 = toDigits (n`div`10) ++ [n`mod`10]
| otherwise = error "make sure your input is greater than 0"
I would like to improve upon the answer of Dave Clarke in this page. It boils down to using div and mod on a number and adding their results to a list, only this time it won't appear reversed, nor resort to ++ (which is slower concatenation).
toDigits :: Integer -> [Integer]
toDigits n
| n <= 0 = []
| otherwise = numToDigits (n `mod` 10) (n `div` 10) []
where
numToDigits a 0 l = (a:l)
numToDigits a b l = numToDigits (b `mod` 10) (b `div` 10) (a:l)
This program was a solution to a problem in the CIS 194 course at UPenn that is available right here. You divide the number to find its result as an integer and the remainder as another. You pass them to a function whose third argument is an empty list. The remainder will be added to the list in case the result of division is 0. The function will be called again in case it's another number. The remainders will add in order until the end.
Note: this is for numbers, which means that zeros to the left won't count, and it will allow you to have their digits for further manipulation.
digits = reverse . unfoldr go
where go = uncurry (*>) . (&&&) (guard . (>0)) (Just . swap . (`quotRem` 10))
I tried to keep using tail recursion
toDigits :: Integer -> [Integer]
toDigits x = reverse $ toDigitsRev x
toDigitsRev :: Integer -> [Integer]
toDigitsRev x
| x <= 0 = []
| otherwise = x `rem` 10 : toDigitsRev (x `quot` 10)

Split a tuple into n parts

I am trying to create a function that receives a range of doubles (Double, Double) and an n (Int), where I divide this interval into n equal parts. I know that if it was a list, I did a Split in the list, but being in tuples and getting Doubles, I'm not sure what to do.
Thank you for any help
This is similar to #mschmidt's answer, but I think a list comprehension is probably clearest:
intervals :: Int -> (Double,Double) -> [(Double,Double)]
intervals n (a,b) =
let n' = fromIntegral n
d = (b - a) / n'
in [(a + i*d, a + (i+1)*d) | i <- [0..n'-1]]
giving:
> intervals 4 (1,10)
[(1.0,3.25),(3.25,5.5),(5.5,7.75),(7.75,10.0)]
>
If the duplicate calculation of the endpoint offends you, you could write:
intervals' :: Int -> (Double,Double) -> [(Double,Double)]
intervals' n (a,b) =
let n' = fromIntegral n
d = (b - a) / n'
x = [a + i*d | i <- [0..n']]
in zip x (tail x)
Note that zip x (tail x) is a pretty standard way to get tuples of consecutive pairs of a list:
> let x = [1,2,3,4] in zip x (tail x)
[(1,2),(2,3),(3,4)]
>
A rough sketch, probably not the most elegant solution:
Take the two input doubles (I call them l and u) and compute the width of the input range/interval.
You want to compute n output ranges of equal width w. Compute this w by dividing the input width by n.
Build a list of length n containing the values l+0*w, l+1*w, l+2*w, ...
Build the list of output tuples by combining the first two items in the list into a tuple. Drop one element of the list. Continue until only one element remains.
Try to catch all possible errors

Check if Int `mod` every element of a list == 0

I'm writing a (Literate) Haskell code that bruteforces the lcm (least common multiple) of a list of Ints.
I already thought about a strategy, but I'm not that good with Haskell syntax and don't know a lot of functions.
This is the function so far:
> bruteforceLCM :: [Int] -> Int -> Int
> bruteforceLCM xs n = if EVERYELEMENTOFTHELIST `mod` n == 0
> then n
> else (bruteforceLCM xs (n+1))
Where xs is the list of all Ints and n is the current Int that gets checked for being the lcm.
The first call would be bruteforceLCM xs 2, because n=0 would be not divisible and n=1 would always return true, these cases are solved with pattern matching earlier.
What would I have to replace "EVERYELEMENTOFTHELIST" with to achieve my goal?
Greeting, Joe
EDIT: Here is the whole code now, thanks to dfeuer!
> bruteforceKGV :: [Int] -> Int -> Int
> bruteforceKGV xs n = if all p xs then n else (bruteforceKGV xs (n+1))
> where p x = n `mod` x == 0
Can you write down a function f :: Int -> Bool that checks if an Int is 0 modulo n? I'll leave this first step to you.
So now you have a function f :: Int -> Bool and a list of Ints, and you want to see if f x is True for every x in the list. We ask Hoogle, and it tells us about all. You'll use f as the first argument of all to do what you want.
You're starting out with
bruteforceLCM :: [Int] -> Int -> Int
bruteforceLCM xs n = if EVERYELEMENTOFTHELIST `mod` n == 0
then n
else (bruteforceLCM xs (n+1))
When you say EVERYELEMENTOFTHELIST `mod` n == 0, what you really mean is "For each element, x, of xs, x `mod` n == 0".
Let's write a predicate expressing what that says about an element of the list:
p x = x `mod` n == 0
Now we can use all, which takes our predicate and tells us if it's true for all elements of the list.
But now we might want to clean things up a bit at a higher level. Because Haskell is lazy, we don't need to be so explicit about the recursion. We can do something like this instead:
bfLCM xs = fromJust $ find SOMETHING [2..]
Unfortunately, running this leads to a lot of infinite loops, because your math actually turns out to be a little bit wrong. Can you figure out where your mistake is?

How can I produce a fixed length of numbers that sum up a given number in Haskell

I'm new to haskell world and wanted to know, given any positive integer and number of digits between 1-9 how can I find the combination of numbers that sum into the positive integer using the provided number of digits in Haskell. For example,
4 using two digits can be represented as a list of [[2,2],[3,1]] using three digits as a list of [[1,1,2]],
5 using two digits can be represented as a list of [[2,3],[4,1]] using three digits as a list of [[1,1,3],[2,2,1]]
Assuming that you want to avoid a brute-force approach, this can be regarded as a typical dynamic-programming problem:
import Data.Array
partitions :: Int -> Int -> [[Int]]
partitions m n = table ! (m, n, 9)
where
table = listArray ((1, 1, 1), (m, n, 9)) l
l = [f i j k | i <- [1 .. m], j <- [1 .. n], k <- [1 .. 9]]
f i 1 k = if i > k `min` 9 then [] else [[i]]
f i j k = [d : ds | d <- [1 .. k `min` pred i], ds <- table ! (i - d, j - 1, d)]
The idea is to construct a three-dimensional lazy array table in which a cell with index (i, j, k) contains all partitions ds of the positive integer i into lists of j digits drawn from [1 .. k] such that sum ds == i.
For example:
> partitions 4 2
[[2,2],[3,1]]
> partitions 4 3
[[2,1,1]]
> partitions 5 2
[[3,2],[4,1]]
> partitions 5 3
[[2,2,1],[3,1,1]]
If you really don't want to think about the problem, and you really should because dynamic programming is good brain food, then you can ask the computer to be smart on your behalf. For example, you could use a tool called an SMT solver to which the sbv package gives you easy access.
Encoding Partitioning in SBV
A great advantage of solvers is you merely need to express the problem and not the solution. In this case lets declare some number of integers (identified by len) which are values 1..9 that sum to a known result (sumVal):
intPartitions :: Int -> Int -> IO AllSatResult
intPartitions sumVal len = allSat $ do
xs <- mapM exists [show i | i <- [1..len]] :: Symbolic [SWord32]
mapM (constrain . (.< 10)) xs
mapM (constrain . (.> 0)) xs
return $ sum xs .== fromIntegral sumVal
Calling this function is rather simple we just have to import the right libraries and print out what are called the satisfying "models" for our problem:
import Data.SBV
import Data.List (nub,sort)
main = do
res <- intPartitions 5 3
print (nub (map sort (extractModels res :: [[Word32]])))
Notice I sorted and eliminated duplicate solutions because you didn't seem to care that [1,1,3], [3,1,1] etc were all solutions - you just want one permutation of the resulting assignments.
For these hard-coded values we have a result of:
[[1,1,3],[1,2,2]]
Well a simple brute force does the trick:
import Data.List
import Control.Monad
sums :: Int -> Int -> [[Int]]
sums number count = nub . map sort . filter ((==number) . sum) $ replicateM count [1..number+1-count]
Note that this is very inefficient. The usage of nub . map sort only shortens the result by removing doubled elements.
This is usually solved by using dynamic programming to avoid recomputing common sub-problems. But this is not the most important problem here: you need to start by coming up with the recursive algorithm! You will have plenty of time to think about producing an efficient solution once you've solved that problem. Hence this answer in two steps. The whole gist without comments is available here.
I start off by giving names to types because I'd get confused with all the Ints floating around and I consider types to be documentation. You might be more clever than I am and not need all this extra stuff.
type Target = Int
type Digits = Int
type MaxInt = Int
Now, the bruteforce solution: We're given the number of Digits left to partition a number, the Target number and the MaxInt we may use in this partition.
partitionMaxBrute :: Digits -> Target -> MaxInt -> [[Int]]
partitionMaxBrute d t m
If we have no digits left and the target is zero, we're happy!
| d == 0 && t == 0 = [[]]
If the product of Digits by MaxInt is smaller than Target or if the MaxInt itself is smaller than zero, there is no way we may succeed accumulating Digits non-zero numbers! :(
| d * m < t || m <= 0 = []
If MaxInt is bigger than our Target then we better decrease MaxInt if we want to have a solution. It does not make sense to decrease it to anything bigger than Target + 1 - Digits.
| t < m = partitionMaxBrute d t (t + 1 - d)
Finally, we may either lower MaxInt (we are not using that number) or substract MaxInt from Target and keep going (we are using MaxInt at least once):
| otherwise = partitionMaxBrute d t (m - 1)
++ fmap (m :) (partitionMaxBrute (d - 1) (t - m) m)
Given that solution, we can get our brute force partition: it's the one where the MaxInt we start with is Target + 1 - Digits which makes sense given that we are expecting a list of Digits non-zero numbers.
partitionBrute :: Digits -> Target -> [[Int]]
partitionBrute d t = partitionMaxBrute d t (t + 1 - d)
Now comes the time of memoization: dynamic programming is taking advantage of the fact that the smaller problems we solve are discovered through a lot of different paths and we do not need to recompute the answer over and over again. Easy caching is made possible by the memoize package. We simply write the same function with its recursive calls abstracted:
partitionMax :: (Digits -> Target -> MaxInt -> [[Int]]) ->
Digits -> Target -> MaxInt -> [[Int]]
partitionMax rec d t m
| d == 0 && t == 0 = [[]]
| d * m < t || m <= 0 = []
| t < m = rec d t (t + 1 - d)
| otherwise = rec d t (m - 1)
++ fmap (m :) (rec (d - 1) (t - m) m)
And make sure that we cache the values:
partition :: Digits -> Target -> [[Int]]
partition d t = memoPM d t (t + 1 - d)
where memoPM = memoize3 $ partitionMax memoPM
You can produce all partitions directly:
type Count = Int
type Max = Int
type Target = Int
partitions :: Count -> Max -> Target -> [[Int]]
partitions 0 m 0 = [[]]
partitions k m n = do
let m' = min m (n - k + 1)
d <- takeWhile (\d -> n <= k * d) [m', m' - 1 .. 1]
map (d:) $ partitions (k - 1) d (n - d)
It's easy to check, that there are no redundant cases. We just need to replace do with redundant $ do, where redundant is
redundant [] = [[]]
redundant xs = xs
If partitions (k - 1) d (n - d) returned [], then redundant would make [[]] from it, and then map (d:) $ partitions (k - 1) d (n - d) would be equal to [d]. But output doesn't change with the redundant function, so all partitions are generated directly.
The code is pretty simple and fast, since you want to produce partitions, rather than count them.

Resources