%ex 11
%encode a list with single items not counted
list_encoding_again(L)->
	list_encoding_again(L,[]).
list_encoding_again([H|T],Packed)->
	{Item,Next} = splitwith(fun(X)->X==H end,[H|T]),
	Size = list_size(Item),
	case (Size > 1) of
		true -> list_encoding_again(Next,[[Size,H]|Packed]);
		false -> list_encoding_again(Next,[[H]|Packed])
	end;
list_encoding_again([],Packed)->
	reverse(Packed).
%ex 12
%decode an encoded list from 11
list_decode(L)->
	list_decode(L,[]).
list_decode([H|T],Unpacked)->
	LSize = list_size(H),
	if
		LSize >1 ->
			[Size|Item] = H, 
			List = item_dup(Size,Item);
		LSize ==1->
			List = H
	end,
	list_decode(T,[List|Unpacked]);
list_decode([],Unpacked)->
	reverse(Unpacked).
	
item_dup(Size,Item)->
	item_dup(Size,Item,[]).
item_dup(Size,Item,NewList)->
	if
		Size =<0 -> NewList;
		Size > 0 -> item_dup(Size-1,Item,[Item|NewList])
	end.
%ex 13
% same as 11 but don't create the sublist of duplicates

%14
%duplicate the elements in a list
list_duplicate(L) ->
	list_duplicate(list_encoding(L),[]).
list_duplicate([H|T],Dup)->
	[Size|Item] = H,
	list_duplicate(T,[item_dup(Size*2,Item)|Dup]);
list_duplicate([],Dup)->
	reverse(Dup).
	
%15
%Replicate the elements of a list a given number of times.
list_replicate(L,Number) ->
	list_replicate(L,Number,[]).
list_replicate([H|T],Number,Rep)->
	list_replicate(T,Number,[item_dup(Number,H)|Rep]);
list_replicate([],Number,Rep)->
	reverse(Rep).
%16
%Drop every N'th element from a list.
list_drop_item(L,Number)->
	list_drop_item(L,Number,[],1).
list_drop_item([H|T],Number,Dropped,Count)->
	case (Count rem Number) == 0 of
		true ->
			list_drop_item(T,Number,Dropped,Count+1);
		false ->
			list_drop_item(T,Number,[H|Dropped],Count+1)
	end;
list_drop_item([],Number,Dropped,Count)->
	reverse(Dropped).

%17
%Split a list into two parts; the length of the first part is given.
list_split(L,Number) ->
	list_split(L,Number,[],1).
list_split([H|T],Number,Split,Count) ->
	case (Count rem Number) == 0 of
		true ->
			[reverse([H|Split]),T];
		false ->
			list_split(T,Number,[H|Split],Count+1)
	end;
list_split([],Number,Split,Count)->
		reverse(Split).
%18
%Extract a slice from a list.
list_slice(L,To,From)->
	list_slice(L,To,From,[],1).
list_slice([H|T],To,From,Slice,Count)->
	if 
		Count >= To , Count =< From ->
			list_slice(T,To,From,[H|Slice],Count+1);
		Count < To ; Count > From ->
			list_slice(T,To,From,Slice,Count+1)
	end;
list_slice([],To,From,Slice,Count)->
	reverse(Slice).
%19
% Rotate a list N places to the left.
list_rotate(L,Pos)->
	[First,Second] = list_split(L,Pos),
	[Second|First].
%20
%Remove the K'th element from a list.
remove_item(L,Pos)->
	remove_item(L,Pos,[],1).
remove_item([H|T],Pos,Removed,Count)->
	case Pos == Count of
		true -> remove_item(T,Pos,Removed,Count+1);
		false -> remove_item(T,Pos,[H|Removed],Count+1)
	end;
remove_item([],Pos,Removed,Count)->
	reverse(Removed).