E-99: 11-20

The second set of 10 problems are now in the bag. Feeling the Erlang-fu! The first set can be found here.

%% Modified run-length encoding. %% Modify the result of problem P10 in such a way that if an element has no duplicates it is simply copied into the result list. %% Only elements with duplicates are transferred as (N E) lists. %% Example: (encode-modified '(a a a a b c c a a d e e e e)) -> ((4 A) B (2 C) (2 A) D (4 E)) p11([]) -> []; p11(L) -> p11encode(p09(L), []). p11encode([], Encoded) -> lists:reverse(Encoded); p11encode([[Elem | SubL] | L], Encoded) -> case length(SubL) of 0 -> p11encode(L, [Elem | Encoded]); \Else -> p11encode(L, [[length(SubL)+1, Elem] | Encoded]) end. %% Decode a run-length encoded list. %% Given a run-length code list generated as specified in problem P11. Construct its uncompressed version. p12([]) -> []; p12(L) -> p12decode(L, []). p12decode([], Decoded) -> lists:reverse(Decoded); p12decode([[N, Elem] | L], Decoded) -> p12decode(L, lists:duplicate(N, Elem) ++ Decoded); p12decode([Elem | L], Decoded) -> p12decode(L, [Elem | Decoded]). %% Run-length encoding of a list (direct solution). %% Implement the so-called run-length encoding data compression method directly. %% I.e. don't explicitly create the sublists containing the duplicates, as in problem P09, but only count them. %% As in problem P11, simplify the result list by replacing the singleton lists (1 X) by X. %% Example: (encode-direct '(a a a a b c c a a d e e e e)) -> ((4 A) B (2 C) (2 A) D (4 E)) p13([]) -> []; p13([H | L]) -> p13encode(L, H, 1, []). %% p13encode(The Remaining List, %% The Current Element, %% The Number Of Repetitions Thus Far, %% The Encoded List Thus Far) p13encode([], Curr, Rep, Encoded) -> case Rep of 1 -> lists:reverse([Curr | Encoded]); \Else -> lists:reverse([[Rep, Curr] | Encoded]) end; p13encode([H | L], Curr, Rep, Encoded) -> case H of Curr -> p13encode(L, Curr, Rep+1, Encoded); \Else -> case Rep of 1 -> p13encode(L, H, 1, [Curr | Encoded]); \Other -> p13encode(L, H, 1, [[Rep, Curr] | Encoded]) end end. %% Duplicate the elements of a list. %% Example: (dupli '(a b c c d)) -> (A A B B C C C C D D) p14([]) -> []; p14([H | L]) -> p14duplicate(L, [H, H]). p14duplicate([], Cloned) -> lists:reverse(Cloned); p14duplicate([H | L], Cloned) -> p14duplicate(L, [H, H | Cloned]). %% Replicate the elements of a list a given number of times. %% Example: (repli '(a b c) 3) -> (A A A B B B C C C) p15([], \Num) -> []; p15([H | L], Reps) -> p15replicate(L, Reps, [lists:duplicate(Reps, H)]). p15replicate([], \Reps, Replicated) -> lists:append(lists:reverse(Replicated)); p15replicate([H | L], Reps, Replicated) -> p15replicate(L, Reps, [lists:duplicate(Reps, H) | Replicated]). %% Drop every N'th element from a list. %% Example: (drop '(a b c d e f g h i k) 3) -> (A B D E G H K) p16([], \Nth) -> []; p16([H | L], Nth) -> p16drop(L, Nth, Nth-1, [H]). p16drop([], \Nth, \Curr, Dropped) -> lists:reverse(Dropped); p16drop([\H | L], Nth, Curr, Dropped) when Curr == 1 -> p16drop(L, Nth, Nth, Dropped); p16drop([H | L], Nth, Curr, Dropped) -> p16drop(L, Nth, Curr-1, [H | Dropped]). %% Split a list into two parts; the length of the first part is given. %% Do not use any predefined predicates. %% Example: (split '(a b c d e f g h i k) 3) -> ( (A B C) (D E F G H I K)) p17([], \SplitPoint) -> []; p17(L, SplitPoint) -> p17split(L, SplitPoint, []). p17split([], \SplitPoint, List) -> lists:reverse(List); p17split(L, SplitPoint, Head) when SplitPoint == 0 -> [lists:reverse(Head) | [L]]; p17split([H | L], SplitPoint, Head) -> p17split(L, SplitPoint-1, [H | Head]). %% Extract a slice from a list. %% Given two indices, I and K, the slice is the list containing the elements %% between the I'th and K'th element of the original list (both limits included). %%Start counting the elements with 1. %% Example: (slice '(a b c d e f g h i k) 3 7) -> (C D E F G) p18([], \Start, \End) -> []; p18(L, Start, End) -> p18slice(L, Start, End-Start, []). p18slice([], \Start, \Count, Sliced) -> lists:reverse(Sliced); p18slice([H | \L], 1, 0, Sliced) -> lists:reverse([H | Sliced]); p18slice([H | L], 1, Count, Sliced) -> p18slice(L, 1, Count-1, [H | Sliced]); p18slice([\H | L], Start, Count, Sliced) -> p18slice(L, Start-1, Count, Sliced). %% Rotate a list N places to the left. %% Examples: (rotate '(a b c d e f g h) 3) -> (D E F G H A B C) %% (rotate '(a b c d e f g h) -2) -> (G H A B C D E F) %% Hint: Use the predefined functions length and append, as well as the result of problem P17. p19([], \Rotate) -> []; p19(L, Rotate) -> case Rotate of Point when Rotate > 0 -> Point; \LT0 -> Point = length(L) + Rotate end, [F, B] = lp:p17(L, Point), B ++ F. %% Remove the K'th element from a list. %% Example: (remove-at '(a b c d) 2) -> (A C D) p20([], \Point) -> []; p20(L, Point) -> p20remove(L, Point, []). p20remove([], \Point, BeforePoint) -> lists:reverse(BeforePoint); p20remove([\H | L], 1, BeforePoint) -> lists:reverse(BeforePoint) ++ L; p20remove([H | L], Point, BeforePoint) -> p20remove(L, Point-1, [H | BeforePoint]).