I need to make a function that given natural number n, calculates the product
of the numbers below n that are not divisible by
2 or by 3 im confused on how to use nested functions in order to solve this problem (also new to sml ) here is my code so far
fun countdown(x : int) =
if x=0
then []
else x :: countdown(x-1)
fun check(countdown : int list) =
if null countdown
then 0
else
It is not clear from the question itself (part of an exercise in some class?) how we are supposed to use nested functions since there are ways to write the function without nesting, for example like
fun p1 n =
if n = 1 then 1 else
let val m = n - 1
in (if m mod 2 = 0 orelse m mod 3 = 0 then 1 else m) * p1 m
end
and there are also many ways to write it with nested functions, like
fun p2 n =
if n = 1 then 1 else
let val m = n - 1
fun check m = (m mod 2 = 0 orelse m mod 3 = 0)
in (if check m then 1 else m) * p2 m
end
or
fun p3 n =
let fun check m = (m mod 2 = 0 orelse m mod 3 = 0)
fun loop m =
if m = n then 1 else
(if check m then 1 else m) * loop (m + 1)
in loop 1
end
or like the previous answer by #coder, just to give a few examples. Of these, p3 is somewhat special in that the inner function loop has a "free variable" n, which refers to a parameter of the outer p3.
Using the standard library, a function that produces the numbers [1; n-1],
fun below n = List.tabulate (n-1, fn i => i+1);
a function that removes numbers divisible by 2 or 3,
val filter23 = List.filter (fn i => i mod 2 <> 0 andalso i mod 3 <> 0)
a function that calculates the product of its input,
val product = List.foldl op* 1
and sticking them all together,
val f = product o filter23 o below
This generates a list, filters it and collapses it. This wastes more memory than necessary. It would be more efficient to do what #FPstudent and #coder do and generate the numbers and immediately either make them a part of the end product, or throw them away if they're divisible by 2 or 3. Two things you could do in addition to this is,
Make the function tail-recursive, so it uses less stack space.
Generalise the iteration / folding into a common pattern.
For example,
fun folditer f e i j =
if i < j
then folditer f (f (i, e)) (i+1) j
else e
fun accept i = i mod 2 <> 0 andalso i mod 3 <> 0
val f = folditer (fn (i, acc) => if accept i then i*acc else acc) 1 1
This is similar to Python's xrange.
Related
I am trying to create a recursive function that divides two integers n and m and then displays the result and the remainder of the division.
Basicly I created two separate functions which do exactly what I want:
let rec div1 (n: int, m: int): int =
if n<m then n else div1(n-m, m)
printfn "Remainder: %i" (div1(5,5))
let rec div2 (n: int, m: int): int =
if n<m then 0 else 1+div2(n-m, m)
printfn "Result: %i" (div2(5,5))
The thing is, I want to do them both at once, I mean in one function like let rec div12 (n: int) (m : int): int * int = , not in two separate.
I am not sure how exactly this would work on F#.
A function may return more than just a number. For example, a function may return a tuple of two numbers:
let f x = (x, x+5)
f 5
> (5, 10)
Further, you can destructure return value of such a function in a similar way:
let (x, y) = f 5
x
> 5
y
> 10
Now we can use this to have our div+mod function return two results - remainder and quotient:
let rec divMod n m =
if n < m
then
(n, 0)
else
let (remainder, quotient) = divMod (n-m) m
(remainder, quotient + 1)
Note how this function simply combines results of your div1 and div2 in a tuple, then destructures them after the recursive call.
divMod 5 5
> (0, 1)
divMod 5 3
> (2, 1)
divMod 7 3
> (1, 2)
Also note that I'm using curried parameters divMod n m instead of tupled parameters as you do div1 (n, m). Ultimately this is a matter of taste, but as a pro tip, I'd like to point out that curried parameters turn out to be much more useful in practice.
I'm very new to Haskell and am trying to write a simple function that will take an array of integers as input, then return either the product of all the elements or the average, depending on whether the array is of odd or even length, respectively.
I understand how to set a base case for recursion, and how to set up boolean guards for different cases, but I don't understand how to do these in concert.
arrayFunc :: [Integer] -> Integer
arrayFunc [] = 1
arrayFunc array
| (length array) % 2 == 1 = arrayFunc (x:xs) = x * arrayFunc xs
| (length array) % 2 == 0 = ((arrayFunc (x:xs) = x + arrayFunc xs) - 1) `div` length xs
Currently I'm getting an error
"parse error on input '='
Perhaps you need a 'let' in a 'do' block?"
But I don't understand how I would use a let here.
The reason you have guards is because you are trying to determine the length of the list before you actually look at the values in the list.
Rather than make multiple passes (one to compute the length, another to compute the sum or product), just compute all of the values you might need, as you walk the list, and then at the end make the decision and return the appropriate value:
arrayFunc = go (0, 1, 0, True)
where go (s, p, len, parity) [] =
if parity then (if len /= 0 then s `div` len else 0)
else p
go (s, p, len, parity) (x:xs) =
go (s + x, p * x, len + 1, not parity) xs
There are various things you can do to reduce memory usage, and the recursion is just reimplementing a fold, but this gives you an idea of how to compute the answer in one pass.
Define an auxiliary inner function like that:
arrayFunc :: [Integer] -> Integer
arrayFunc [] = 1
arrayFunc array
| (length array) % 2 == 1 = go1 array
| (length array) % 2 == 0 = go2 array
where
go1 (x:xs) = x * go1 xs
go2 (x:xs) = ((x + go2 xs) - 1) `div` length xs
This deals only with the syntactical issues in your question. In particular, [Integer] is not an array -- it is a list of integers.
But of course the name of a variable doesn't influence a code's correctness.
Without focus on recursion this should be an acceptable solution:
arrayFunc :: (Integral a) => [a] -> a
arrayFunc ls
| n == 0 = 1
| even n = (sum ls) `div` (fromIntegral n)
| otherwise = product ls
where
n = length xs
I wrote a function that finds power. But I want to program to find minus 1 of power function. How can I do that ? For example power 3 4 = 80, power 2 3 = 7
Here is the code
let rec power m n =
if n = 0 then 1
else m * power m (n-1) ;;
Well, you'll have to subtract 1 after calculating the power then:
let powerMinus1 m n = (power m n) - 1;;
Or if you need it self-contained you can use an inner function:
let powerMinus1 m n =
let rec power n =
...
in (power n) - 1;;
I'm trying to put the last element of a list in the front of the list while keeping the rest of the elements in the same order N times. I can do it once with this function, but I want to add another parameter to the function so that the function in called N times.
Code:
fun multcshift(L, n) =
if null L then nil
else multcshift(hd(rev L)::(rev(tl(rev L))));
Thanks
To make the parameter n work, you need recursion. You need a base case at which point the function should no longer call itself, and a recursive case where it does. For this function, a good base case would be n = 0, meaning "shift the last letter in front 0 times", i.e., return L without modification.
fun multcshift(L, n) =
if n = 0
then L
else multcshift( hd(rev L)::rev(tl(rev L)) , n - 1 )
The running time of this function is terrible: For every n, reverse the list three times!
You could save at least one of those list reversals by not calling rev L twice. E.g.
fun multcshift (L, 0) = L
| multcshift (L, n) =
let val revL = rev L
in multcshift ( hd revL :: rev (tl revL) , n - 1 ) end
Those hd revL and rev (tl revL) seem like useful library functions. The process of applying a function to its own output n times seems like a good library function, too.
(* Return all the elements of a non-empty list except the last one. *)
fun init [] = raise Empty
| init ([_]) = []
| init (x::xs) = x::init xs
(* Return the last element of a non-empty list. *)
val last = List.last
(* Shift the last element of a non-empty list to the front of the list *)
fun cshift L = last L :: init L
(* Compose f with itself n times *)
fun iterate f 0 = (fn x => x)
| iterate f 1 = f
| iterate f n = f o iterate f (n-1)
fun multcshift (L, n) = iterate cshift n L
But the running time is just as terrible: For every n, call last and init once each. They're both O(|L|) just as rev.
You could overcome that complexity by carrying out multiple shifts at once. If you know you'll shift one element n times, you might as well shift n elements. Shifting n elements is equivalent to removing |L| - n elements from the front of the list and appending them at the back.
But what if you're asked to shift n elements where n > |L|? Then len - n is negative and both List.drop and List.take will fail. You could fix that by concluding that any full shift of |L| elements has no effect on the result and suffice with n (mod |L|). And what if n < 0?
fun multcshift ([], _) = raise Empty
| multcshift (L, 0) = L
| multcshift (L, n) =
let val len = List.length L
in List.drop (L, len - n mod len) #
List.take (L, len - n mod len) end
There are quite a few corner cases worth testing:
val test_zero = (multcshift ([1,2,3], 0) = [1,2,3])
val test_empty = (multcshift ([], 5); false) handle Empty => true | _ => false
val test_zero_empty = (multcshift ([], 0); false) handle Empty => true | _ => false
val test_negative = (multcshift ([1,2,3,4], ~1) = [2,3,4,1])
val test_nonempty = (multcshift ([1,2,3,4], 3) = [2,3,4,1])
val test_identity = (multcshift ([1,2,3,4], 4) = [1,2,3,4])
val test_large_n = (multcshift [1,2,3,4], 5) = [4,1,2,3])
val test_larger_n = (multcshift [1,2,3,4], 10) = [3,4,1,2])
I am new to Haskell and have an assignment. I have to write a
Int->Int->[u]->[u]
Function that is given input two Ints i and j and a list and returns the elements that are in possitions greater than i and smaller than j. What I have thought so far is:
fromTo :: Int->Int->[u]->[u]
fromTo i j (h:t)
|i == 1 && j == length(h:t)
= (h:t)
|i /= 1
fromTo (i-1) j t
|j /= length(h:t)
fromTo i j init(h:t)
However I get a syntax error for the second |. Also im unsure if my train of thought is correct here.
(init returns the list without its last element)
EDIT: Corrected
|i /= 1
fromTo (i-1) j (h:t)
to
|i /= 1
fromTo (i-1) j t
Fixed indentation, parenthesization, and missing =s. This reformation compiles, and works for ordinals and finite non-empty lists:
fromTo :: Int -> Int -> [u] -> [u]
fromTo i j (h : t)
| i == 1 && j == length (h : t) = h : t
| i /= 1 = fromTo (i - 1) j t
| j /= length (h : t) = fromTo i j (init (h : t))
I think you're looking for something like this pointfree, naturally indexing span:
take :: Int -> [a] -> [a]
take _ [] = []
take 0 _ = []
take n (x : xs) = x : take (n - 1) xs
drop :: Int -> [a] -> [a]
drop _ [] = []
drop 0 xs = xs
drop n (_ : xs) = drop (n - 1) xs
span :: Int -> Int -> [a] -> [a]
span i j = drop i . take (j + 1)
which
span 0 3 [0 .. 10] == [0,1,2,3]
Or, to fit the specification:
between :: Int -> Int -> [a] -> [a]
between i j = drop (i + 1) . take j
which
between 0 3 [0 .. 10] == [1,2]
You're missing = between the | guard clause and the body. The Haskell compiler thinks the whole thing is the guard, and gets confused when it runs into the next | guard because it expects a body first. This will compile (although it is still buggy):
fromTo :: Int -> Int -> [u] -> [u]
fromTo i j (h:t)
| i == 1 && j == length (h:t) =
(h:t)
| i /= 1 =
fromTo (i-1) j t
| j /= length (h:t) =
fromTo i j (init (h:t))
but I would say there are better ways of writing this function. For example, in principle a function like this should work on infinite lists, but your use of length makes that impossible.
Here is complete solution that use recursion:
fromTo :: Int -> Int -> [u] -> [u]
fromTo i j xs = go i j xs []
where go i j (x:xs) rs
| i < 0 || j < 0 = []
| i > length (x:xs) || j > length (x:xs) = []
| i /= 0 = go (i - 1) j t
| j /= 1 = goo i (j -1) (rs ++ [x])
| otherwise = rs
Notes:
go is standard Haskell idiom for recursive function that need extra parameters compared to main level function.
First clause make sure that negative indexes result in empty list. Second does the same for any index that exceed size of a list. Lists must be finite. Third "forgets" head of the array i times. Fourth will accumulate "next" (j - 1) heads into rs. Fifth clause will be triggered when all indexes are "spent" and rs contain result.
You could make it work on infinite lists. Drop second clause. Return rs if xs is empty before "exhausting" indexes. Then function will take "up to" (j-1) elements from i.