|
| 1 | +-module(my_deque). |
| 2 | + |
| 3 | +-export([empty/0, is_empty/1, |
| 4 | + cons/2, head/1, tail/1, |
| 5 | + snoc/2, last/1, init/1]). |
| 6 | + |
| 7 | +-compile(export_all). |
| 8 | + |
| 9 | +empty() -> {[], []}. |
| 10 | + |
| 11 | +is_empty({[],[]}) -> true; |
| 12 | +is_empty(_) -> false. |
| 13 | + |
| 14 | +%% insert to front of deque |
| 15 | +cons(X, {[],[]}) -> {[X], []}; |
| 16 | +cons(X, {[],[Y]}) -> {[X], [Y]}; |
| 17 | +cons(X, {[],_R}=Q) -> cons(X, checkf(Q)); |
| 18 | +cons(X, {F, R}) -> checkf({[X|F], R}). |
| 19 | + |
| 20 | +%% inspect head |
| 21 | +head({[], []}=Q) -> {undefined, Q}; |
| 22 | +head({[], [X]}) -> {X, {[], []}}; |
| 23 | +head({[], _R}=Q) -> head(checkf(Q)); |
| 24 | +head({[X|F],R}) -> {X, {F, R}}. |
| 25 | + |
| 26 | +%% remove head from deque |
| 27 | +tail({[], []}) -> undefined; |
| 28 | +tail({[], [_X]}) -> empty(); |
| 29 | +tail({[],_R}=Q) -> tail(checkf(Q)); |
| 30 | +tail({[_X|F], R}) -> checkf({F, R}). |
| 31 | + |
| 32 | +%% insert to end of list |
| 33 | +snoc(X, {[],[]}) -> {[], [X]}; |
| 34 | +snoc(X, {[Y],[]}) -> {[Y], [X]}; |
| 35 | +snoc(X, {_F,[]}=Q) -> snoc(X, checkf(Q)); |
| 36 | +snoc(X, {F, R}) -> checkf({F, [X|R]}). |
| 37 | + |
| 38 | +%% inspect the last element |
| 39 | +last({[], []}=Q) -> {undefined, Q}; |
| 40 | +last({[X], []}) -> {X, {[], []}}; |
| 41 | +last({_F, []}=Q) -> last(checkf(Q)); |
| 42 | +last({F,[X|R]}) -> {X, {F, R}}. |
| 43 | + |
| 44 | +%% remove last element from deque |
| 45 | +init({[], []}) -> undefined; |
| 46 | +init({[_X], []}) -> empty(); |
| 47 | +init({_F,[]}=Q) -> init(checkf(Q)); |
| 48 | +init({F, [_X|R]}) -> checkf({F, R}). |
| 49 | + |
| 50 | +checkf({[],[]}=Q) -> Q; |
| 51 | +checkf({[], R}) -> |
| 52 | + {F, R1} = lists:split(length(R) div 2, R), |
| 53 | + {lists:reverse(F), R1}; |
| 54 | +checkf({[_X], []}=Q) -> Q; % don't need to move the first el over to the end list |
| 55 | +checkf({F, []}) -> |
| 56 | + {F1, R} = lists:split(length(F) div 2, F), |
| 57 | + {F1, lists:reverse(R)}; |
| 58 | +checkf(Q) -> Q. |
0 commit comments