How to remove the next to last element from the list in Erlang - erlang

I have a task: "Add second and fifth elements of list to the end of the list and remove the penultimate element". I need to do this without using the module lists, just using recursion.
I have code which finds an element by index, which solves the problem of finding the second and fifth element (also not an ideal solution for me, because it's the same lists:nth function).
-module(task).
-export([remove_and_add/1]).
remove_and_add(List) ->
remove_penultimate(List) ++ [nth(2, List)] ++ [nth(5, List)].
nth(1, [H|_]) ->
H;
nth(N, [_|T]) ->
nth(N - 1, T).
But I don't understand how to remove the penultimate element without a length (how to implement remove_penultimate function).

Whenever you use ++, you can pretty much assume you are doing it inefficiently:
remove_penultimate(List) ++ [nth(2, List)] ++ [nth(5, List)].
If you can't use the lists module, then the first function every beginner needs to write is a reverse(List) function. Beside being one of the most useful functions, that will teach you the trick of how to add an "accumulator" variable to a function's parameter variables to store whatever data you want in it. Here is an example:
go(List) ->
go(List, []).
go([H|T], Acc) -> %% Acc starts off as a blank list, which can be used to store data
%% maybe do something here
go(T, [H|Acc]); %% storing data in the Acc list
go([], Acc) -> Acc.
You can add as many variables as you need to a function's parameters using the trick above, for instance:
go(List) ->
go(List, 1, none, none, []).
go([H|T], N, X, Y, Acc) -> ...
Examine this function:
show_previous(List) ->
show_previous(List, none).
show_previous([], Prev) -> %% A variable called Prev has been added to the function's parameters, and it starts off with the value none.
io:format("current: end of list, previous: ~w~n", [Prev]);
show_previous([Last], Prev) -> %% This clause only matches a list with one element.
io:format("current: ~w, penultimate: ~w~n", [Last, Prev]),
show_previous([H|T], Prev) ->
io:format("current: ~w, prev: ~w~n", [H, Prev]),
show_previous(T, H).
Note that in erlang, a function with the same name but with a different number of parameter variables (known as the "arity" of a function) is a completely different function, so show_previous/1 and show_previous/2 are completely different functions.
Here's another example of what you can do:
show([]) ->
io:format("!No more elements!~n");
show([X, Y]) -> %% only matches a list with two elements
io:format("penultimate: ~w, last: ~w~n", [X, Y]),
show([Y]);
show([H|T]) ->
io:format("current: ~w~n", [H]),
show(T). %% By whittling the list down one element at a time,
%% the list will eventually become a 2 element list
But I don't understand how to remove the penultimate element without a length.
You could always get the length by recursing over all the elements and counting them. It would be good practice to write your own length function. It's very simple. Remember though, it's more efficient to recurse over a list as few times as possible, and you should be able to solve your original problem by recursing over the list once, then reversing the list (which requires recursing over the list again).
Another possible approach to removing the penultimate element is to reverse the list, then ask yourself, "How do I remove the second element of a list?"
I came up with a solution that traverses the original list once, and when it comes to the end of the list, it reverses the Acc list and returns it. It takes this list:
[1, 2, 3, 4, 5, 6, 7]
and returns this list:
[1,3,4,7,2,5]
I would describe that operation as removing the penultimate element in the list and moving the 2nd and 5th elements to the end of the list. Copying the 2nd and 5th elements and adding the copies to the end of the list would be solved in a similar fashion.

Related

Erlang: serial implementation of accumulator

I am trying to create a method that takes an associative and commutative operator, as well a list of values, and then returns the answer by applying an operator to the values in the list.
The following two examples represent what the input/output are supposed to look like.
Example 1
Input: sum(fun(A,B) -> A+B end, [2,6,7,10,12]).
Output: 37
Example 2
Input: sum(fun (A,B) -> A++B end , ["C", "D", "E"]).
Output: "CDE"
This is the code I am working with so far.
-module(tester).
-compile(export_all).
sum(Func, Data, Acc) ->
lists:foldr(Func, Acc, Data).
This code produces the correct result, however, there are two problems I am trying to figure out how to approach answering.
(1) In order for this code to work, it requires an empty list to be included at the end of the command line statements. In other words, if I enter the input above (as in the examples), it will err out, because I did not write it in the following way:
12> tester:sum(fun(X, Acc) -> X+Acc end, [2,6,7,10,12], 0).
How would I implement this without an empty list as in the examples above and get the same result?
(2) Also, how would the code be implemented without the list function, or in an even more serial way?
How would I implement this without an empty list as in the examples above and get the same result?
Assuming the list always has one element (you can't really do it without this assumption), you can extract the first element from the list and pass that as the initial accumulator. You'll need to switch to foldl to do this efficiently. (With foldr you'll essentially need to make a copy of the list to drop the last element.)
sum(Func, [X | Xs]) ->
lists:foldl(fun (A, B) -> Func(B, A) end, X, Xs).
1> a:sum(fun(A,B) -> A+B end, [2,6,7,10,12]).
37
2> a:sum(fun (A,B) -> A++B end , ["C", "D", "E"]).
"CDE"
Also, how would the code be implemented without the list function, or in an even more serial way?
Here's a simple implementation using recursion and pattern matching:
sum2(Func, [X | Xs]) ->
sum2(Func, Xs, X).
sum2(Func, [], Acc) ->
Acc;
sum2(Func, [X | Xs], Acc) ->
sum2(Func, Xs, Func(Acc, X)).
We define two versions of the function. The first one extracts the head and uses that as the initial accumulator. The second one, with arity 3, does essentially what the fold functions in lists do.
After working on this for a while, this was my solution. I've left some comments about the general idea of what I did, but there's a lot more to be said.
-module(erlang2).
-compile(export_all).
-export([reduce/2]).
reduce(Func, List) ->
reduce(root, Func, List).
%When done send results to Parent
reduce(Parent, _, [A]) ->
%send to parent
Parent ! { self(), A};
%I tried this at first to take care of one el in list, but it didn't work
%length ([]) ->
% Parent ! {self(), A};
%get contents of list, apply function and store in Parent
reduce(Parent, Func, List) ->
{ Left, Right } = lists:split(trunc(length(List)/2), List),
Me = self(),
%io:format("Splitting in two~n"),
Pl = spawn(fun() -> reduce(Me, Func, Left) end),
Pr = spawn(fun() -> reduce(Me, Func, Right) end),
%merge results in parent and call Func on final left and right halves
combine(Parent, Func,[Pl, Pr]).
%merge pl and pl and combine in parent
combine(Parent, Func, [Pl, Pr]) ->
%wait for processes to complete (using receive) and then send to Parent
receive
{ Pl, Sorted } -> combine(Parent, Func, Pr, Sorted);
{ Pr, Sorted } -> combine(Parent, Func, Pl, Sorted)
end.
combine(Parent, Func, P, List) ->
%wait and store in results and then call ! to send
receive
{ P, Sorted } ->
Results = Func(Sorted, List),
case Parent of
root ->
Results;
%send results to parent
_ -> Parent ! {self(), Results}
end
end.

Flatten List Erlang Need Clarification

flatten(X) -> flatten(X,[]).
flatten([],Acc) -> Acc;
flatten([[]|T],Acc) -> flatten(T, Acc);
flatten([[_|_]=H|T],Acc) -> flatten(T, flatten(H,Acc));
flatten([H|T],Acc) -> flatten(T,Acc++[H]) .
This is from an Post made before not my code.
Can some one explain what is happening here:
flatten([[_|_]=H|T],Acc)
[[_|_]=H|T] is the part I don't get.
(Also This is on another page but I can't comment on it because of rep.)
[[_|_]=H|T] matches a non-empty list whose first element is also a non-empty list.
Let's split it up:
[ H|T] %% match the Head and Tail of a list
[_|_] %% match the head and tail of the inner list, ignoring the values
= %% assign the matched inner list to the variable H
This is a common pattern in Erlang. A list either has zero elements, and thus matches [], or it has at least one element, in which case you can extract the first element and the rest of the list with [H|T]. (That match can also be written as [H] ++ T.)

Make pairs out of a list in erlang

I'm trying to do a process on items in a sorted set in erlang, I call ZRANGE KEY 0 -1 WITHSCORES with eredis, the problem is it returns something like [<<"item1">>, <<"100">>, <<"item2">>, <<"200">>]. How can I run a function f on these items efficiently so that these calls occur: f(<<"item1">>, <<"100">>), f(<<"item2">>, <<"200">>)?
I solved it with something like this
f([X,Y|T]) -> [do_the_job(X,Y)|f(T)];
f([]) -> [].
then calling:
f(List).
Is there a more efficient way for doing so?
An optimized way is using tail-recursion. You can pass your list into do/1 function and it generates an empty list for storing the result of applying f/2 function on each two head items of the given list and then return the results:
do(List) ->
do(List, []).
do([X,Y | Tail], Acc) ->
do(Tail, [f(X, Y) | Acc]);
do([], Acc) ->
lists:reverse(Acc).
f(X, Y) ->
{X, Y}.
A note from Erlang documentation about tail-recursive efficiency:
In most cases, a recursive function uses more words on the stack for each recursion than the number of words a tail-recursive would allocate on the heap. As more memory is used, the garbage collector is invoked more frequently, and it has more work traversing the stack.

Copy one list to another list

I am stuck at some basic recursion since this language is completely new for me, I want to copy integers from one list to another.
This is what I have:
cpy_list(L) -> cpy_list(L, []).
cpy_list([], Acc) -> Acc;
could somebody show me how a working solution can look like?
You need one more clause for thecpy_list/2
cpy_list(L) -> cpy_list(L, []). % Starting condition
cpy_list([H|T], Acc) -> cpy_list(T, Acc ++ [H]); % take the first element and add to Acc
cpy_list([], Acc) -> Acc.
Of course, it is not an ideal solution because it is not efficient. See note here: http://www.erlang.org/doc/efficiency_guide/listHandling.html
And since variables are immutable in erlang, I doubt there is any point in copying a list.
In Erlang, assigning a variable into a new one is "copying" the content from the on to the other. (no pointers!)
So you don't need a special function for it.
TheList = [1,2,3,4,5].
CpyList = TheList.
cpy_list(L) -> cpy_list(L, []).
cpy_list([], Acc) -> lists:reverse(Acc);
cpy_list([H|T], Acc) ->
cpy_list(T, [H|Acc]).
Here is the code, you can use Tail-recursive
In Erlang since all data is immutiable there is no point in copying a list. Anything you do to manipulate the list will produce an altered copy of the original list. If you did want to copy a list it would be as simple as running:
List = [1,2,3],
NewList = lists:map(fun(X) -> X end, List).
Because lists:map/2 will always returns a new list this will work! You could just have easily have performed your alterations on the original list with map/2 and it would have returned a completely new list.
Once can also use a list comprehension:
ListCopy = [Entry || Entry <- ListOriginal]

right rotate a List in Erlang

I am getting myself familiar to Sequential Erlang (and the functional programming thinking) now. So I want to implement the following two functionality without the help of BIF. One is left_rotate (which I have come up with the solution) and the other is right_rotate (which I am asking here)
-export(leftrotate/1, rightrotate/1).
%%(1) left rotate a lits
leftrotate(List, 0) ->
List;
leftrotate([Head | Tail], Times) ->
List = append(Tail, Head),
leftrotate(List, Times -1).
append([], Elem)->
[Elem];
append([H|T], Elem) ->
[H | append(T, Elem)].
%%right rotate a list, how?
%%
I don't want to use BIF in this exercise. How can I achieve the right rotation?
A related question and slightly more important question. How can I know one of my implementation is efficient or not (i.e., avoid unnecessary recursion if I implement the same thing with the help of a BIF, and etc.)
I think BIF is built to provide some functions to improve efficiency that functional programming is not good at (or if we do them in a 'functional way', the performance is not optimal).
The efficiency problem you mention has nothing to do with excessive recursion (function calls are cheap), and everything to do with walking and rebuilding the list. Every time you add something to the end of a list you have to walk and copy the entire list, as is obvious from your implementation of append. So, to rotate a list N steps requires us to copy the entire list out N times. We can use lists:split (as seen in one of the other answers) to do the entire rotate in one step, but what if we don't know in advance how many steps we need to rotate?
A list really isn't the ideal data structure for this task. Lets say that instead we use a pair of lists, one for the head and one for the tail, then we can rotate easily by moving elements from one list to the other.
So, carefully avoiding calling anything from the standard library, we have:
rotate_right(List, N) ->
to_list(n_times(N, fun rotate_right/1, from_list(List))).
rotate_left(List, N) ->
to_list(n_times(N, fun rotate_left/1, from_list(List))).
from_list(Lst) ->
{Lst, []}.
to_list({Left, Right}) ->
Left ++ reverse(Right).
n_times(0, _, X) -> X;
n_times(N, F, X) -> n_times(N - 1, F, F(X)).
rotate_right({[], []}) ->
{[], []};
rotate_right({[H|T], Right}) ->
{T, [H|Right]};
rotate_right({[], Right}) ->
rotate_right({reverse(Right), []}).
rotate_left({[], []}) ->
{[], []};
rotate_left({Left, [H|T]}) ->
{[H|Left], T};
rotate_left({Left, []}) ->
rotate_left({[], reverse(Left)}).
reverse(Lst) ->
reverse(Lst, []).
reverse([], Acc) ->
Acc;
reverse([H|T], Acc) ->
reverse(T, [H|Acc]).
The module queue provides a data structure something like this. I've written this without reference to that though, so theirs is probably more clever.
First, your implementation is a bit buggy (try it with the empty list...)
Second, I would suggest you something like:
-module(foo).
-export([left/2, right/2]).
left(List, Times) ->
left(List, Times, []).
left([], Times, Acc) when Times > 0 ->
left(reverse(Acc), Times, []);
left(List, 0, Acc) ->
List ++ reverse(Acc);
left([H|T], Times, Acc) ->
left(T, Times-1, [H|Acc]).
right(List, Times) ->
reverse(foo:left(reverse(List), Times)).
reverse(List) ->
reverse(List, []).
reverse([], Acc) ->
Acc;
reverse([H|T], Acc) ->
reverse(T, [H|Acc]).
Third, for benchmarking your functions, you can do something like:
test(Params) ->
{Time1, _} = timer:tc(?MODULE, function1, Params),
{Time2, _} = timer:tc(?MODULE, function2, Params),
{{solution1, Time1}, {solution2, Time2}}.
I didn't test the code, so look at it critically, just get the idea.
Moreover, you might want to implement your own "reverse" function. It will be trivial by using tail recursion. Why not to try?
If you're trying to think in functional terms then perhaps consider implementing right rotate in terms of your left rotate:
rightrotate( List, 0 ) ->
List;
rightrotate( List, Times ) ->
lists:reverse( leftrotate( lists:reverse( List ), Times ) ).
Not saying this is the best idea or anything :)
Your implementation will not be efficient since the list is not the correct representation to use if you need to change item order, as in a rotation. (Imagine a round-robin scheduler with many thousands of jobs, taking the front job and placing it at the end when done.)
So we're actually just asking ourself what would be the way with least overhead to do this on lists anyway. But then what qualifies as overhead that we want to get rid of? One can often save a bit of computation by consing (allocating) more objects, or the other way around. One can also often have a larger than needed live-set during the computation and save allocation that way.
first_last([First|Tail]) ->
put_last(First, Tail).
put_last(Item, []) ->
[Item];
put_last(Item, [H|Tl]) ->
[H|put_last(Item,Tl)].
Ignoring corner cases with empty lists and such; The above code would cons the final resulting list directly. Very little garbage allocated. The final list is built as the stack unwinds. The cost is that we need more memory for the entire input list and the list in construction during this operation, but it is a short transient thing. My damage from Java and Lisp makes me reach for optimizing down excess consing, but in Erlang you dont risk that global full GC that kills every dream of real time properties. Anyway, I like the above approach generally.
last_first(List) ->
last_first(List, []).
last_first([Last], Rev) ->
[Last|lists:reverse(Rev)];
last_first([H|Tl], Rev) ->
last_first(Tl, [H|Rev]).
This approach uses a temporary list called Rev that is disposed of after we have passed it to lists:reverse/1 (it calls the BIF lists:reverse/2, but it is not doing anything interesting). By creating this temporary reversed list, we avoid having to traverse the list two times. Once for building a list containing everything but the last item, and one more time to get the last item.
One quick comment to your code. I would change the name of the function you call append. In a functional context append usually means adding a new list to the end of a list, not just one element. No sense in adding confusion.
As mentioned lists:split is not a BIF, it is a library function written in erlang. What a BIF really is is not properly defined.
The split or split like solutions look quite nice. As someone has already pointed out a list is not really the best data structure for this type of operation. Depends of course on what you are using it for.
Left:
lrl([], _N) ->
[];
lrl(List, N) ->
lrl2(List, List, [], 0, N).
% no more rotation needed, return head + rotated list reversed
lrl2(_List, Head, Tail, _Len, 0) ->
Head ++ lists:reverse(Tail);
% list is apparenly shorter than N, start again with N rem Len
lrl2(List, [], _Tail, Len, N) ->
lrl2(List, List, [], 0, N rem Len);
% rotate one
lrl2(List, [H|Head], Tail, Len, N) ->
lrl2(List, Head, [H|Tail], Len+1, N-1).
Right:
lrr([], _N) ->
[];
lrr(List, N) ->
L = erlang:length(List),
R = N rem L, % check if rotation is more than length
{H, T} = lists:split(L - R, List), % cut off the tail of the list
T ++ H. % swap tail and head

Resources