Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Return adjacent duplicates in Erlang

I'm trying to learn recursion in Erlang and I am working through a book. But I'm hitting a wall when faced with the problem of taking a list and returning only the duplicate elements. I tried writing a function which returns only the unique elements and then removing them from the original list.

adjacent_dups(L) -> L -- uniques(L).

uniques([])    -> [];
uniques([H|T]) -> [H | [X || X <- uniques(T), X /= H]].

This will however not give the correct result when the list is not well structured.

L = [7,3,4,3]

My code will return

adjacent_dups([7,3,4,3]) -> 3 

How can I get

adjacent_dups([7,3,4,3]) -> [] 
like image 999
Capa Avatar asked Jan 08 '23 13:01

Capa


1 Answers

Use pattern matching in the function head to find adjacent identical values:

adjacent_dups(L) ->
    adjacent_dups(L, #{}).
adjacent_dups([], Acc) ->
    maps:keys(Acc);
adjacent_dups([H,H|T], Acc) ->
    adjacent_dups(T,maps:put(H,H,Acc));
adjacent_dups([_|T], Acc) ->
    adjacent_dups(T, Acc).

The first function adjacent_dups/1 is meant to be exported. The rest, adjacent_dups/2, are helper functions.

The adjacent_dups/1 function creates an empty map to pass to adjacent_dups/2 as the initial value of an accumulator. Recursive functions often use accumulators.

The first clause of adjacent_dups/2 handles the case where the incoming list has been exhausted or was empty to start with. In that case, we retrieve the keys of the accumulator map; these are our adjacent values.

The second clause of adjacent_dups/2 handles the case of adjacent values using pattern matching. In this case, we add the value as a key and value to the accumulator map, and call ourselves recursively with the tail of the list. Using a map eliminates duplicates from the final result.

The final clause of adjacent_dups/2 handles the case where a value does not have an adjacent value; it simply makes a recursive call with the tail of the list and an unmodified accumulator.

like image 139
Steve Vinoski Avatar answered Jan 18 '23 18:01

Steve Vinoski