Count number of odd digits in Integer Haskell - function

I'm trying to make program which counts the number of odd digits in integer using Haskell. I have ran into problem with checking longer integers. My program looks like this at the moment:
oddDigits:: Integer -> Int
x = 0
oddDigits i
| i `elem` [1,3,5,7,9] = x + 1
| otherwise = x + 0
If my integer is for example 22334455 my program should return value 4, because there are 4 odd digits in that integer. How can I check all numbers in that integer? Currently it only checks first digit and returns 1 or 0. I'm still pretty new to haskell.

You can first convert the integer 22334455 to a list "22334455". Then find all the elements satisfying the requirement.
import Data.List(intersect)
oddDigits = length . (`intersect` "13579") . show

In order to solve such problems, you typically split this up into smaller problems. A typical pipeline would be:
split the number in a list of digits;
filter the digits that are odd; and
count the length of the resulting list.
You thus can here implement/use helper functions. For example we can generate a list of digits with:
digits' :: Integral i => i -> [i]
digits' 0 = []
digits' n = r : digits' q
where (q, r) = quotRem n 10
Here the digits will be produced in reverse order, but since that does not influences the number of digits, that is not a problem. I leave the other helper functions as an exercise.

Here's an efficient way to do that:
oddDigits :: Integer -> Int
oddDigits = go 0
where
go :: Int -> Integer -> Int
go s 0 = s
go s n = s `seq` go (s + fromInteger r `mod` 2) q
where (q, r) = n `quotRem` 10
This is tail-recursive, doesn't accumulate thunks, and doesn't build unnecessary lists or other structures that will need to be garbage collected. It also handles negative numbers correctly.

Related

Implement Gaussian sum function in OCaml with lambda expression

I have to write a function sum that takes as first argument a value n. The second argument is a function f so that sum calculates the Gaussian sum.
In a second step, I have to implement thesum_gauss (int->int) using sum and a lambda expression.
This is my idea for the function sum:
let rec sum (n:int) (f:int->int) : int =
if n < 1 then 0
else sum (n-1) f + f n
And this is sum_gauss which throws an error:
let sum_gauss = sum ((i:int) -> fun (i:int) : int -> i)
The error is:
Line 1, characters 30-32:
Error: Syntax error: ')' expected
Line 1, characters 22-23:
This '(' might be unmatched
I don't understand why this error is raised because every left bracket is matched by a right bracket.
Rewriting with type inference cleaning things up:
let rec sum n f =
if n < 1 then 0
else sum (n-1) f + f n
If you wish to add all number from 1 to n. you need to pass the number and the function to sum_gauss as separate arguments.
let sum_gauss n = sum n (fun x -> x)
Of course, fun x -> x is really just Fun.id.
let sum_gauss n = sum n Fun.id
If you feel like being extra clever and you're already using the Fun module you can use Fun.flip to pass Fun.id as the second argument of sum and elide n from the definition entirely. The fact that sum is not polymorphic avoids weak typing issues with partial application.
let gauss_sum = Fun.(flip sum id)

How to find maximum of function outputs with multipe inputs in one function?

I want a function maxfunct, with input f (a function) and input n (int), that computes all outputs of function f with inputs 0 to n, and checks for the max value of the output.
I am quite new to haskell, what I tried is something like that:
maxfunct f n
| n < 0 = 0
| otherwise = maximum [k | k <- [\(f, x)-> f x], x<- [0..n]]
Idea is that I store every output of f in a list, and check for the maximum in this list.
How can I achieve that?
You're close. First, let's note the type of the function we're trying to write. Starting with the type, in addition to helping you get a better feel for the function, also lets the compiler give us better error messages. It looks like you're expecting a function and an integer. The result of the function should be compatible with maximum (i.e. should satisfy Ord) and also needs to have a reasonable "zero" value (so we'll just say it needs Num, for simplicity's sake; in reality, we might consider using Bounded or Monoid or something, depending on your needs, but Num will suffice for now).
So here's what I propose as the type signature.
maxfunct :: (Num a, Ord a) => (Int -> a) -> Int -> a
Technically, we could generalize a bit more and make the Int a type argument as well (requires Num, Enum, and Ord), but that's probably overkill. Now, let's look at your implementation.
maxfunct f n
| n < 0 = 0
| otherwise = maximum [k | k <- [\(f, x)-> f x], x<- [0..n]]
Not bad. The first case is definitely good. But I think you may have gotten a bit confused in the list comprehension syntax. What we want to say is: take every value from 0 to n, apply f to it, and then maximize.
maxfunct :: (Num a, Ord a) => (Int -> a) -> Int -> a
maxfunct f n
| n < 0 = 0
| otherwise = maximum [f x | x <- [0..n]]
and there you have it. For what it's worth, you can also do this with map pretty easily.
maxfunct :: (Num a, Ord a) => (Int -> a) -> Int -> a
maxfunct f n
| n < 0 = 0
| otherwise = maximum $ map f [0..n]
It's just a matter of which you find more easily readable. I'm a map / filter guy myself, but lots of folks prefer list comprehensions, so to each his own.

Haskell Integer Odd Digits Checker

I seem to be stuck on a question and have no idea how to approach it or what Im doing wrong with my current code.
I have to write a function called oddDigits which takes a single integer argument and returns a boolean result. It should return True if and only if the argument is a positive integer with an odd number of digits. If the argument is zero or negative, the function should stop with an error message.
Also, cant convert the argument into a string. Have to use recursion.
I have a feeling each digit could be stored in a list recursively and then the length of the list could determine the answer.
So far, I have this:
oddDigits :: Integer -> Bool
lst = []
oddDigits x
| (x < 0) || (x == 0) = error
| x `mod` 10 ++ lst ++ oddDigits(x `div` 10)
| length(lst) `mod` 2 /= 0 = True
| otherwise = False
Sorry if the code looks horrible. I am new to Haskell and still learning. What exactly am I doing wrong and how could I correct it?
First off, this seems a pretty weird thing to check. Perhaps what you're doing wrong is to ever consider this problem...
But if you persist you want to know the property of an integer having an odd number of digits... oh well. There's a lot that could be improved. For starters, (x < 0) || (x == 0) doesn't need the parentheses – < and == (infix 4) bind more tightly than ||. If you're not sure about this, you can always ask GHCi:
Prelude> :i ==
class Eq a where
(==) :: a -> a -> Bool
...
-- Defined in ‘GHC.Classes’
infix 4 ==
Prelude> :i ||
(||) :: Bool -> Bool -> Bool -- Defined in ‘GHC.Classes’
infixr 2 ||
But here you don't need || anyway because there's a dedicated operator for less-than-or-equal. Hence you can just write
oddDigits x
| x <= 0 = error "bla bla"
| ...
Then, you can “convert” the number to a string. Converting to string is generally a really frowned-upon thing to do because it throws all structure, typechecking etc. out of the window; however “number of digits” basically is a property of a string (the decimal expansion), rather than a number itself, so this is not entirely unsensible for this specific task. This would work:
oddDigits x
| x <= 0 = error "blearg"
| length (show x)`mod`2 /= 0 = True
| otherwise = False
however it's a bit redundancy department redundant. You're checking if something is True, then give True as the result... why not just put it in one clause:
oddDigits x
| x <= 0 = error "blearg"
| otherwise = length (show x)`mod`2 /= 0
That's perhaps in fact the best implementation.
For any proper, sensible task, I would not recommend going the string route. Recursion is better. Here's what it could look like:
oddDigits 1 = True
oddDigits x
| x <= 0 = error "blearg"
| otherwise = not . oddDigits $ x`div`10
There's nothing wrong with your general approach of converting to a list of digits, then finding the length of the list. Really where you went wrong is trying to cram everything into one function. As you found out first hand, it makes it very difficult to debug. Functional programming works best with very small functions.
If you separate out the responsibility of converting an integer to a list of digits, using a digs function like the one from this answer, the rest of your algorithm simplifies to:
oddDigits x | x <= 0 = error
oddDigits x = odd . length $ digs x
leftaroundabout's eventual answer is very nice, however it fails for numbers like 2,3 and 23. Here's a fix.
oddDigits x
| x <= 0 = error "blearg"
| x < 10 = True
| otherwise = not . oddDigits $ x`div`10
Its much more elegant than my initial answer, below. I'm including it to introduce a common functional paradigm, a worker/wrapper transformation of the problem. Here the wrapper gives the interface and passes off the work to another function. Notice that the negativity check only needs to be done once now.
oddDigits :: Integer -> Bool
oddDigits x
| x <= 0 = False
| otherwise = oddDigits' True x
oddDigits' :: Bool -> Integer -> Bool
oddDigits' t x
| x < 10 = t
| otherwise = oddDigits' (not t) $ x `div` 10
oddDigits' carries a piece of internal data with it, the initial Bool. My first first thought was to have that Bool be a digit accumulator, counting the number of digits. In that case, an "unwrapper" needs to be supplied, in this case the standard "odd" function:
oddDigits x
| x <= 0 = False
| otherwise = odd . oddDigits'' 1 $ x
where oddDigits'' :: Integer -> Integer -> Integer.

OCaml function with variable number of arguments

I'm exploring "advanced" uses of OCaml functions and I'm wondering how I can write a function with variable number of arguments.
For example, a function like:
let sum x1,x2,x3,.....,xn = x1+x2,+x3....+xn
With a bit of type hackery, sure:
let sum f = f 0
let arg x acc g = g (acc + x)
let z a = a
And the (ab)usage:
# sum z;;
- : int = 0
# sum (arg 1) z;;
- : int = 1
# sum (arg 1) (arg 2) (arg 3) z;;
- : int = 6
Neat, huh? But don't use this - it's a hack.
For an explanation, see this page (in terms of SML, but the idea is the same).
OCaml is strongly typed, and many techniques used in other (untyped) languages are inapplicable. In my opinion (after 50 years of programming) this is a very good thing, not a problem.
The clearest way to handle a variable number of arguments of the same type is to pass a list:
# let sum l = List.fold_left (+) 0 l;;
val sum : int list -> int = <fun>
# sum [1;2;3;4;5;6];;
- : int = 21

Haskell function about even and odd numbers

I'm new to Haskell, started learning a couple of days ago and I have a question on a function I'm trying to make.
I want to make a function that verifies if x is a factor of n (ex: 375 has these factors: 1, 3, 5, 15, 25, 75, 125 and 375), then removes the 1 and then the number itself and finally verifies if the number of odd numbers in that list is equal to the number of even numbers!
I thought of making a functions like so to calculate the first part:
factor n = [x | x <- [1..n], n `mod`x == 0]
But if I put this on the prompt it will say Not in scope 'n'. The idea was to input a number like 375 so it would calculate the list. What I'm I doing wrong? I've seen functions being put in the prompt like this, in books.
Then to take the elements I spoke of I was thinking of doing tail and then init to the list. You think it's a good idea?
And finally I thought of making an if statement to verify the last part. For example, in Java, we'd make something like:
(x % 2 == 0)? even++ : odd++; // (I'm a beginner to Java as well)
and then if even = odd then it would say that all conditions were verified (we had a quantity of even numbers equal to the odd numbers)
But in Haskell, as variables are immutable, how would I do the something++ thing?
Thanks for any help you can give :)
This small function does everything that you are trying to achieve:
f n = length evenFactors == length oddFactors
where evenFactors = [x | x <- [2, 4..(n-1)], n `mod` x == 0]
oddFactors = [x | x <- [3, 5..(n-1)], n `mod` x == 0]
If the "command line" is ghci, then you need to
let factor n = [x | x <- [2..(n-1)], n `mod` x == 0]
In this particular case you don't need to range [1..n] only to drop 1 and n - range from 2 to (n-1) instead.
The you can simply use partition to split the list of divisors using a boolean predicate:
import Data.List
partition odd $ factor 10
In order to learn how to write a function like partition, study recursion.
For example:
partition p = foldr f ([],[]) where
f x ~(ys,ns) | p x = (x:ys,ns)
f x ~(ys,ns) = (ys, x:ns)
(Here we need to pattern-match the tuples lazily using "~", to ensure the pattern is not evaluated before the tuple on the right is constructed).
Simple counting can be achieved even simpler:
let y = factor 375
(length $ filter odd y) == (length y - (length $ filter odd y))
Create a file source.hs, then from ghci command line call :l source to load the functions defined in source.hs.
To solve your problem this may be a solution following your steps:
-- computers the factors of n, gets the tail (strips 1)
-- the filter functions removes n from the list
factor n = filter (/= n) (tail [x | x <- [1..n], n `mod` x == 0])
-- checks if the number of odd and even factors is equal
oe n = let factors = factor n in
length (filter odd factors) == length (filter even factors)
Calling oe 10 returns True, oe 15 returns False
(x % 2 == 0)? even++ : odd++;
We have at Data.List a partition :: (a -> Bool) -> [a] -> ([a], [a]) function
So we can divide odds like
> let (odds,evens) = partition odd [1..]
> take 10 odds
[1,3,5,7,9,11,13,15,17,19]
> take 10 evens
[2,4,6,8,10,12,14,16,18,20]
Here is a minimal fix for your factor attempt using comprehensions:
factor nn = [x | n <- [1..nn], x <- [1..n], n `mod`x == 0]