Skip to content

Instantly share code, notes, and snippets.

@wmealing
Created April 4, 2014 00:49
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save wmealing/9965891 to your computer and use it in GitHub Desktop.
Save wmealing/9965891 to your computer and use it in GitHub Desktop.
Simple erlang example of compressing ranges using recursion.
%%%-------------------------------------------------------------------
%%% @author Wade Mealing <>
%%% Created : 2 Apr 2014 by Wade Mealing <>
%%%-------------------------------------------------------------------
-module(compress).
-include_lib("eunit/include/eunit.hrl").
%% user should only use compress/1
-export([compress/1, run_all_tests/0]).
%%%===================================================================
%%% TESTS
%%%===================================================================
%%%% Removed test generator functions, just simpletest for now.
run_all_tests() ->
eunit:test(compress, [verbose]).
empty_list_test() ->
Ret = compress([]),
?assertEqual(Ret, []).
simple_few_test() ->
Ret = compress([1,2,3]),
?assertEqual(Ret, [{1,3}]).
simple_double_range_test() ->
Ret = compress([1,2,3,1,2,3]),
?assertEqual(Ret,[{1,3},{1,3}]).
negatives_test() ->
Ret = compress([-5,-4,-3,-2,-1]),
?assertEqual(Ret, [{-5,-1}]).
wrap_zero_test() ->
Ret = compress([-1,0,1]),
?assertEqual(Ret,[{-1,1}]).
duplicate_vals_test() ->
Ret = compress([0,0,0]),
?assertEqual(Ret, [{0}, {0}, {0}]).
overlapping_ranges_test() ->
Ret = compress([1,2,3,4,2,3,4]),
?assertEqual(Ret, [{1,4}, {2,4}]).
single_value_test() ->
Ret = compress([1]),
?assertEqual(Ret, [{1}]).
%%%===================================================================
%%% API
%%%===================================================================
compress([]) ->
[];
compress(List) ->
compress(List, []).
%%%===================================================================
%%% PRIVATE STUFF
%%%===================================================================
compress(List, NewAcc) ->
[Next|Rest] = List,
compress(Rest,{Next}, NewAcc).
%% When last element of list is not range
compress([], {N,N}, Acc) ->
lists:append(Acc, [{N}]);
compress(List, {N,N}, Acc) ->
NewAcc = lists:append(Acc, [{N}]),
compress(List, NewAcc);
compress([], Anything, Acc ) ->
lists:append(Acc, [Anything]);
compress(List, {CompressStart}, Acc) ->
process_element(List, CompressStart, CompressStart, {CompressStart}, Acc);
compress(List, {CompressStart,CompressLast}, Acc) ->
process_element(List, CompressLast, CompressStart, {CompressStart,CompressLast}, Acc ).
process_element([Next|Rest], CompareVal, CompressStart, ToAppend, Acc) ->
case is_beside(CompareVal, Next) of
true ->
compress(Rest, {CompressStart, Next}, Acc);
_ ->
NewAcc = lists:append(Acc, [ToAppend]),
compress(Rest, {Next}, NewAcc )
end.
is_beside(First,Second) ->
case First + 1 of
Second ->
true;
_ ->
false
end.
@wmealing
Copy link
Author

wmealing commented Apr 4, 2014

To run:

erlc compress.erl
erl


1> compress:run_all_tests().
======================== EUnit ========================
module 'compress'
  compress: empty_list_test...ok
  compress: simple_few_test...ok
  compress: simple_double_range_test...ok
  compress: negatives_test...ok
  compress: wrap_zero_test...ok
  compress: duplicate_vals_test...ok
  compress: overlapping_ranges_test...ok
  compress: single_value_test...ok
  [done in 0.024 s]
=======================================================
  All 8 tests passed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment