ML muliplication - sml

Using SML, I have to create a recursive function to do the following
fun mult ([a,b,c]) - multiply a*b c times
example: mult ([2,3,5]) -> [2, 6, 18, 54, 162, 486]
Update: I have the following
fun mult (a, b) = a*b;
fun multin ([a, b, c]) = if c=0 then nil
else mult(a, b) :: multin ([mult(a,b), b, c-1]);
multin ([2, 3, 5]);
results in: val it = [6,18,54,162,486] : int list
I need the first element to be 2 in this case. If I make the base case if c=0 then [a], then it just repeats whatever the last element was; in this case it was repeating 486.

You don't need a helper unless you require the function to be tail recursive.
The first thing to observe is that if c is zero, the answer is [a]. That's the base case of your recursion. Otherwise, you need to construct a list that is a consed onto the rest of the answer, which you can obtain with a recursive call.
That should be enough of a hint to get started.

why don't you count up since the list is going up? something like
fun mult ([a,b,k],c) = a*b^k::mult([a,b,k+1],c)
mult([a,b,0],c)
Not sure what the operator for power is ^ but you get the idea.
Then terminate your loop when k increments reaches c.

Related

Finding two max in list

How do I find two max value in a list and sum up, not using rec, only can use List.fold_left or right and List.map?
I used filter, but it's not allowed, anyways I can replace the filter?
let max a b =
if b = 0 then a
else if a > b then a
else b;;
let maxl2 lst =
match lst with
| [] -> 0
| h::t ->
let acc = h in
List.fold_left max acc lst +
List.fold_left
max acc
(List.filter (fun x -> (x mod List.fold_left max acc lst) != 0) lst);;
List.fold_left is very powerful and can be used to implement List.filter, List.map, List.rev and so on. So it's not much of a restriction. I would assume the purpose of the exercise is for you to learn about the folds and what they can do.
If your solution with List.filter actually works, you should be able to replace List.filter by one you wrote yourself using List.fold_left. The basic idea of a fold is that it builds up a result (of any type you choose) by looking at one element of the list at a time. For filter, you would add the current element to the result if it passes the test.
However I have to wonder whether your solution will work even with List.filter. I don't see why you're using mod. It doesn't make a lot of sense. You seem to need an equality test (= in OCaml). You can't use mod as an equality test. For example 28 mod 7 = 0 but 28 <> 7.
Also your idea of filtering out the largest value doesn't seem like it would work if the two largest values were equal.
My advice is to use List.fold_left to maintain the two largest values you've seen so far. Then add them up at the end.
To build on what Jeffrey has said, List.fold_left looks at one element in a list at a time and an accumulator. Let's consider a list [1; 3; 7; 0; 6; 2]. An accumulator that makes sense is a tuple with the first element being the largest and the second element representing the second largest. We can initially populate these with the first two elements.
The first two elements of this list are [1; 3]. Finding the max of that we can turn this into the tuple (3, 1). The remainder of the list is [7; 0; 6; 2].
First we consider 7. It's bigger than 3, so we change the accumulator to (7, 3). Next we consider 0. This is smaller than both elements of the accumulator, so we make no changes. Next: 6. This is bigger than 3 but smaller than 7, so we updated the accumulator to (7, 6). Next: 2 which is smaller than both, so no change. The resulting accumulator is (7, 6).
Actually writing the code for this is your job.
Often, functions called by fold use an accumulator that is simple enough to be stored as an anonymous tuple. But this can become hard to understand when you are dealing with complex behaviors: you have to consider different corner cases, like what is the initial accumulator value? what is the regular behavior of the function, ie. when the accumulator has encountered enough values? what happens before that?
For example here you have to keep track of two maximal values (the general case), but your code has a build-up phase where there is only one element being visited in the list, and starts with initially no known max value. This kind of intermediate states is IMO the hardest part of using fold (the more pleasant cases are when the accumulator and list elements are of the same type).
I'd recommend making it very clear what type the accumulator is, and write as many helper functions as possible to clear things up.
To that effect, let's define the accumulator type as follows, with all different cases treated explicitly:
type max_of_acc =
| SortedPair of int * int (* invariant: fst <= snd *)
| Single of int
| Empty
Note that this isn't the only way to do it, you could keep a list of maximum values, initially empty, always sorted, and of size at most N, for some N (and then you would solve a more general case, ie. a list of N highest values). But as an exercise, it helps to cover the different cases as above.
For example, at some point you will need to compute the sum of the max values.
let sum_max_of m = match m with
| Empty -> 0
| Single v -> v
| SortedPair (u,v) -> u+v;;
I would also define the following helper function:
let sorted_pair u v = if u <= v then SortedPair (u,v) else SortedPair (v, u)
Finally, your function would look like this:
let fold_max_of acc w = match acc with
| Empty -> ...
| Single v -> ...
| SortedPair (u, v) -> ...
And could be used in the following way:
# List.fold_left fold_max_of Empty [1;2;3;5;4];;
- : max_of = SortedPair (4, 5)

How can I multiply each element of a list by the first element, then the second element, and so on, making a list for each set of products?

I am currently trying to create a list of lists in OCaml using a single list, where each new list contains the set of products resulting from multiplication of each list element by the first, second, third, and so on, list element. I should also say now that I'm only allowed to use ´List.hd´, ´List.tl´, and ´List.nth´.
An example would be:
[-1, 1, -1, 1] -> [1, -1, 1, -1]
[-1, 1, -1, 1]
[1, -1, 1, -1]
[-1, 1, -1, 1]
I've created a function that does this perfectly fine, but my issue is that it only does so for the very first time, as every additional time it destroys the head of the list and does it for the new smaller list. I need help making it so the list isn't getting destroyed as I do this.
Here is my code that implements the multiplication and appends the result as a list in the list of lists:
let rec hopTrainAstate = function (astate) ->
if((astate == []))
then []
else multiplyAll(List.hd astate, astate)::hopTrainAstate(List.tl astate);;
Here is my code for the multiplication:
let rec multiplyAll = function (head, alist) ->
if((alist == []))
then []
else (head *. List.hd alist)::multiplyAll(head, List.tl alist);;
Here is the result of using the function with the example above:
[
As you can see, the multiplication is working just fine, but it's working on a list that keeps removing the head. I am pretty new to OCaml so maybe this isn't as hard as I think it is, but I haven't been able to find anything online that has helped. I really appreciate any help!
Your main function is working with smaller and smaller lists, so this is more or less the expected result.
It would probably help if your main function had a second parameter that represents the whole list. That's what you need to be passing to your multiplication function.
If you don't want your main function to have an extra parameter (which is reasonable) then you could write a helper function. In fact, a helper function inside the main function could easily access the initial list directly.
If you're just starting with OCaml, you might not know what a helper function is. It's a function that's used inside the main function to help with the computation. For example if I want to find the maximum element of a list of non-negative ints, I could write this:
let find_maximum l =
let rec imax max_so_far il =
match il with
| [] -> max_so_far
| hd :: tl ->
if hd > max_so_far then imax hd tl
else imax max_so_far tl
in
imax (-1) l
It's fairly common to have a recursive helper function inside a non-recursive main function. This allows the recursive function to have extra parameters.
Note that in this example the helper function imax could access the original list under the name l if it was interested in this value.

SML: How to take the tl of a list x number of times?

I'm working on an assignment, and the problem I'm running into is that I am unsure how to take the tl of a list x number of times within a function. x is given when the function is ran, but anytime before then I don't know.
There is already a built-in function for this: List.drop (xs, n) drops n elements from xs. Since "taking the tail" is equivalent to dropping one element, dropping n elements is equivalent to "taking the tail" n times.
- List.drop ([1,1,2,3,5,8,13,21], 5);
> val it = [8, 13, 21] : int list
I got it. I had to write a Helper function that took the tl of my list however many times I needed it to.
Thanks!

Writing Prolog Code which returns list of integer sums from a given number

I'm trying to write a Prolog predicate that can decomposes a given non-negative integer into every possible sum, using a DCG.
For example:
?- s(3, L, []).
L = [3] ? ;
L = [2,1] ? ;
L = [1,2] ? ;
L = [1,1,1] ? ;
false.
I started by writing a predicate which takes a number N and returns L = [1,2,3,...,N]:
mkList(N, L) :-
m(0, N, L).
m(X, X, []).
m(Y, L, [H|T]) :-
H is Y+1,
m(H, L, T).
However, I'm not sure how I can proceed.
s(Input) -->
{ mkList(Input, InputList) },
{ member(X, InputList) },
[X].
This is what I was going to use, it starts out my running through the list one by one. However, I'm not sure where I should include a rule to find the difference between X and Input.
the base case is easy:
all_sum(N) --> [N].
now, we can call recursively if we provide a M between 1 and N, and take the rest R (beware it must be > 0)
all_sum(N) --> {...},[M],all_sum(R).
please fill the dots using the hints above.
You will get
?- phrase(all_sum(3),L).
L = [3] ;
L = [1, 2] ;
L = [1, 1, 1] ;
L = [2, 1] ;
false.
The best way to proceed is to think like Prolog, that is, recursively. Yes, you've got recursion. It may even be right, but I'm not following it.
Thinking like this should work:
mkList(Number,List) :-
pick a number between 1 and number. It'll be your first addend.
subtract it from number to get the remainder.
make a recursive call to handle the remainder.
patch together List based on the first addend and the list from the recursive call.
Obviously we need to stop when Number is less than 1.
This doesn't use a DCG, but for the life of me I can't see how a DCG is relevant here.

How to parse a list and form a number in Prolog?

I would like to know if someone could help me with a problem in prolog. I have to define two predicates but before that, I need to find out a way how to parse a list and form a number. For example [1,2,3] => 123. I tried different ways to do this but nothing works good. My code looks like this, I know it is not good but I can't find another way.
num([H|T],I,RI,RES):-
H2 is H * I,
R1 is RI + H2,
I2 is I/10,
RES2 is RES + R1,
num(T,I2,R1,RES2).
Your hunch is correct that this can be much simpler. Recursively, you want to think of the digits [A, B, C] representing number as, (((A * 10) + B) * 10) + C.
To start, you want to think about what kind of predicate you desire. That would simply be, num(Digits, Number). which yields Number given Digits. You'll need an accumulator for intermediate results using the above formula concept, so your num/2 needs to call a num/3 that will include an accumulator argument that you carry along:
num(Digits, Num) :-
num(Digits, 0, Num). % Accumulator initially 0
If the input list is empty, the result is the accumulator:
num([], A, A). % Result is accumulator when there are no digits
Then your recursive case:
num([D|T], A, R) :-
NewA is (D * 10) + A, % New accumulator is (current digit * 10) + old accumlator
... % Need recursive call
I'll leave the ... for you to fill in as an exercise. :)