Haskell Integer Odd Digits Checker - function

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.

Related

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.

OCaml : recursive function dealing with parity between list elements and an int

This function should take two arguments a list and an int. if an element of the list and the number “a” parity is equal then they’d have to be summed, else the two numbers should be subtracted.
The calculation should be done in this order :
At the beginning, the residual value r is the value of a,
Each element e of lst (taken in the order given by the list) affects the residual value: if e and r are of the same parity (both odd or both even) then the new r’ is equal to the sum of r + e, if not then it should be equal to the subtraction of r - e,
The last r is the result expected.
To put this into an example:
par [4;7;3;6] 5
should return -1, it would work as follows :
5 and 4 have a different parity so we subtract -> 5 - 4 = 1
1 and 7 are both odd, so we add them together -> 1 + 7 = 8
8 and 3 have a different parity -> 8 - 3 = 5
Finally, 5 and 6 have different parity -> 5 - 6 = -1
I have thought of something like this below :
let rec par lst a =
match lst with
| [] -> 0
| h::t -> if (h mod 2 == 0 && a mod 2 == 0) || (h mod 2 == 1 && a mod 2 == 1) then a + h
| h::t -> if (h mod 2 == 0 && a mod 2 == 1) || (h mod 2 == 1 && a mod 2 == 0) then a - h :: par t a ;;
EDIT1 : Here is the error I get from the compiler :
Line 4, characters 83-88: Error: This expression has type int but an
expression was expected of type unit because it is in the result of a
conditional with no else branch
The idea is to build this function using no more than the following predefined functions List.hd, List.tl et List.length.
What is disturbing in my proposition above and how to remediate it? Anyone can help me resolve this, please?
EDIT 2:
I was able to do what is needed with if...then... else syntax (not the best I know for OCaml) but I personally have more difficulties sometimes understanding the pattern matching. Anyhow here's what I got :
let rec par lst a = (* Sorry it might hurt some sensible eyes *)
if List.length lst = 0 then a
else
let r = if (List.hd lst + a) mod 2 == 0 then (a + (List.hd lst))
else (a - (List.hd lst)) in
par (List.tl lst) r ;;
val par : int list -> int -> int = <fun>
Suggestions and help to put it into a pattern-matching syntax are welcomed.
Your code doesn't compile. Did you try compiling it? Did you read the errors and warnings produced by the compiler? Could you please add them to your question?
A few comments about your code:
| h::t -> if ... then ... should be | h::t when ... -> ...;
(h mod 2 == 0 && a mod 2 == 0) || (h mod 2 == 1 && a mod 2 == 1) can be simplified to (h - a) mod 2 == 0;
The compiler likes to know that the matching was exhaustive; in particular, you don't need to repeat the test in the third line of the matching (the third line will only be read if the test was false in the second line);
You are missing the recursive call in the second line of the matching;
In the third line of the matching, you are returning a list rather than a number (the compiler should have explicitly told you about that type mismatch!! did you not read the compiler error message?);
In the first line of the matching, in case the list is empty, you return 0. Are you sure that 0 is the value you want to return, when you've reached the end of the list? What about the residual value that you have calculated?
Once you have fixed this version of your code as a recursive function, I recommend trying to write a code solving the same problem using List.fold_left, rather than List.hd and List.tl as you are suggesting.
When I first wrote my answer, I included a fixed version of your code, but I think I'd be doing you a disservice by handing out the solution rather than letting you figure it out.

Count number of odd digits in Integer Haskell

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.

OCaml : Raise an error inside a match with structure

In OCaml, I have a list of strings that contains names of towns (Something like "1-New York; 2-London; 3-Paris"). I need to ask the user to type a number (if they want London they have to type 2).
I want to raise an exception message saying that the town is not valid, if the person types for example "4", in the example.
I tried this, but it doesn't work :
let chosenTown = match int_of_string (input_line stdin) with
| x > (length listOfTowns) -> raise (Err "Not a valid town")
What's the good way to code "if the chosen number is bigger than the length of the list then raise the error" ??
Pattern can't contain arbitrary expressions. It can be a constant, a constructor name, record field inside curly braces, list, array, etc.
But patterns can be guarded, e.g.
match int_of_string (input_line stding) with
| x when x >= length listOfTowns ->
invalid_arg "the number is too large"
| x -> List.nth listOfTowns x
To complete the answer, patter matching relies on unification and does not expect assertion (it is not the equivalent of a switch in C or so).
The idea is that you provide different "shapes" (patterns) that your term (the thing you match on) could have.
For a list for instance:
match l with
| e :: e' :: r -> (*...*)
| e :: r -> (*...*)
| [] -> (*...*)
It also had a binding effect, if you pass on, say, [1] (a very small list indeed), it won't match e :: e' :: r, but will match e :: r and then e = 1 and r = [].
As ivg said, you can add conditions, as booleans this time, thanks to the keyword when.
However, when manipulating lists like this, I would go for a recursive function:
let rec find_town n l =
match l with
| t :: _ when n = 1 -> t
| _ :: r -> find_town (n-1) r
| [] -> raise (Err "Not a valid town")
This is basically writing again List.nth but changing the exception that it raises.

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]