list & an integer n. The function should add the n-th element of the list, and return the remaining list .for example
insertnth ([5,6,7],2,9);
output : [5,9,6,7]
n is the 2.
9 is which I add the second line
Seriously, lutzlover. You need to go read a text book or some introduction to SML. For example see the SML/NJ Literature page.
Basically you have two ways of solving this problem. Given a function insertnth(xs, pos, n), then the ugly non-functional way is to split the list at position pos, and then return left # n :: right where left and right are the left and right part of the split. Or the more functional way, with a recursive function that goes through the list xs element by element, decrementing the pos variable each time, and then when you reach position 1, then return n appended to the remaining list, to stop the recursion.
Related
I'm new to Prolog, trying to sum up only the first elements of each list.
takeFirst([[1,2,3],[4,5,6],[7,8,9]],R). --> R=1+4+7=12
It keeps outputting false and I don't understand what I'm missing here.
takeFirst([HF|_],[],HF):-!.
takeFirst([H|L1],R):- H=[_|_], L1=[_|_],!,takeFirst(H,L1,NN), R is NN.
takeFirst([HF|_],[K|L2],HF):- takeFirst(K,L2,NN), HF is HF+NN.
does anyone see what is wrong here?
Well your code is rather chaotic: you define a takeFirst/3 first (that probably should be the base case?). Next you define two recursive cases, but you somehow pass the head the list in the recursive call, etc.
Actually the problem is easy to solve. You first better redirect your takeFirst/2 to a takeFirst/3` with an accumulator:
takeFirst(L,R) :-
takeFirst(L,0,R).
Next we consider a base case: we reached the end of the list:
takeFirst([],R,R).
In this case we reached the end, and so the value of the accumulator, the variable we pass that keeps track of the sum thus far, is returned as the result.
In the recursive case, we are given a list [H|T] and we are interested in the head of the head HH so [[HH|_]|T]. In that case we add HH to the accumulator and do a recursive call with T:
takeFirst([[HH|_]|T],Ra,R) :-
Rb is Ra+HH,
takeFirst(T,Rb,R).
So putting it together we get:
takeFirst(L,R) :-
takeFirst(L,0,R).
takeFirst([],R,R).
takeFirst([[HH|_]|T],Ra,R) :-
Rb is Ra+HH,
takeFirst(T,Rb,R).
Something that was not very clear in your question is what should be done if there is an empty list in your list, like [[1,2,3],[],[7,8,9]]. The above predicate will fail: it expects that all lists have at least one element. In case you simply want to ignore these lists, you can alter your code into:
takeFirst2(L,R) :-
takeFirst2(L,0,R).
takeFirst2([],R,R).
takeFirst2([[]|T],Ra,R) :-
takeFirst2(T,Ra,R).
takeFirst2([[HH|_]|T],Ra,R) :-
Rb is Ra+HH,
takeFirst2(T,Rb,R).
So we add a case where the list follows the pattern [[]|T], in which case we simply perform a recursive call with the tail T.
Based on the given above predicates, constructing a list of heads is not hard as well:
heads([],[])
heads([[HH|_]|TA],[HH|TB]) :-
heads(TA,TB).
I have to write a recursive function that takes a list of three elements, and returns another list created using those three elements. For example I might have a list like [a,b,c], and a function needs to multiple a by b c times. So [2,3,5] would create a list like [2,6,18,54,162,486]
I understand the hd, tl, #, and :: list operators, but I don't understand the logic of building the list.
If I multiply hd([2,3,5])* hd(tl([2,3,5)) I'll get six. But where do I attach that? I would need new logic on every call to go deeper in the list multiplying the last element by 3.
The point is, your recursive function should return the list, and the call which satisfies the stopping requirement should return empty list (or some starting list).
In this case, the function appends (a * b) to the start of list of the next values. The decreasing c provides a counter, while intermediate result (a * b) serves as a base for calculations further down the line. So here the list grows backwards, from the greatest values at the tail to the smallest at the head.
The first element of a list is called a head, and the rest of a list is its tail. But what is the term for a sublist that consists of first N elements of a list? And what is the name for the rest of the list after N'th element?
Actually, in a rather large subset of linked list implementations, the tail is actually the last element rather than the list sans the head :-)
Since there appears to be little consensus (after two years) as to what you should call the initial subset, you can name it whatever you like as long as it's clear, for example:
initial subset of size N;
first N elements;
initial-N.
I would actually call the rest of the list just the remainder, since you'll almost always be using it in the context of what you're discussing.
So, for example, the head has a remainder of all but the head, and the initial subset of size N has a remainder of the list minus those N elements.
I am having a difficult time understand recursion in prolog. I can read examples and sometimes understand, but I mostly have a difficult time implementing them. For example, could someone code me how to find the summation all the elements in a list, and go through it? and tips on how to approach a question like this? Thanks!
A general "good" explanation is not possible, because a good explanation needs to link to the previous knoledgment of the person. I'm going, by example, assume you are able to made a "proof by induction".
Step1: Let start by the initial fact, "the sum of a set with a single element is the element itself". In prolog:
sum([A],A).
Step2: if the sum of a set Q is SQ, the sum of this set adding one element H is H+SQ. In prolog:
sum([H|Q],R) :- sum(Q,SQ), R is H+SQ.
thats all, you have the problem solved. But...
In general, we try to start by the most basic set, the empty one, so replace "step 1" that becames now: the sum of the elements of an empty set is 0:
sum([],0).
Finally, prolog is more efficiente if the rules are tail recursive (if the execution environment is not able to optimice by itself). That means a little change:
sum([],R,R).
sum([H|Q],SQ,R) :- T is SQ+H, sum(Q,T,R).
these rules can be understood as: Assume (assert) that sum of Q is SQ. In this case, sum of set Q plus an element H is SQ+H. The first one means, when there are no more elements in the pending set, the result is directly the acumulated sum.
Thinking recursively can be hard. See my answer to the question "Prolog programming - path way to a solution" for links to good resources on how to think recursively.
For instance, most recursive problems can be broken down into a few (1 or 2) special cases, and then, the general case. In your case — computing the sum of a list of numbers — one might look at it has having 1 or two special cases. First, you have to make a decision: What is the sum of an empty list? One might argue either that the sum of an empty list is zero, or that an empty list has no sum. Either is, arguable, a perfectly valid point-of-view.
In either event, the special cases are
[]. The empty list. The sum of the empty list is either 0, or nothing (in which case your predicate should fail.)
[100]. A list of length one. The sum of a list of length 1 is obviously that value of the first and only entry.
And the more general case:
[100,101,102]. The sum of a list of length greater than 1 can be computed by taking the value of the first item in the list and computing the sum of the remainder. Note that
The solution is defined in terms of itself, and
The problem is made smaller (by removing the 1st item from the list).
Eventually, the problem will degenerate into one of the special cases, right?
Given all that, let us suppose that we've decided that the sum of the empty list is to be 0. That means our 2nd special case (a single element list) goes away, leaving us with a solution that can be described as
The sum of an empty list is 0.
The sum of a non-empty list is computed by
removing the 1st item from the list,
computing the sum of the remaining items,
adding the value of the 1st item to the sum of the remainder.
And since prolog is a declarative language, our solution is going to be pretty much identical to the description of the solution:
sum_of_list( [] , 0 ) .
sum_of_list( [N|Ns] , S ) :-
sum_of_list(Ns,T) ,
S is T+N
.
The c
I've defined a custom list type as part f a homework exercise.
type 'a myType =
| Item of ('a * 'a myType)
| Empty;;
I've already done 'length' and now I need a 'append' function.
My length function:
let length l =
let rec _length n = function
| Empty -> n
| Item(_, next) -> _length (n + 1) next
in _length 0 l;;
But I really don't know how to make the append function.
let append list1 list2 = (* TODO *)
I can't use the list module so I can't use either :: or #.
I guess my comments are getting too lengthy to count as mere comments. I don't really want to answer, I just want to give hints. Otherwise it defeats the purpose.
To repeat my hints:
a. The second parameter will appear unchanged in your result, so you can just
spend your time worrying about the first parameter.
b. You first need to know how to append something to an empty list. I.e., you need
to know what to do when the first parameter is Empty.
c. You next need to know how to break down the non-empty case into a smaller append
problem.
If you don't know how to create an item, then you might start by writing a function that takes (say) an integer and a list of integers and returns a new list with the integer at the front. Here is a function that takes an integer and returns a list containing just that one integer:
let list1 k =
Item (k, Empty)
One way to think of this is that every time Item appears in your code, you're creating a new item. Item is called a constructor because it constructs an item.
I hope this helps.
Your structure is a list, so you should start by defining a value nil that is the empty list, and a function cons head tail, that appends the head element in front of the list tail.
Another advice: sometimes, it helps a lot to start by taking a simple example, and trying to do it manually, i.e. decomposing what you want to do in simple operations that you do yourself. Then, you can generalize and write the code...