-module(word_split). -export([words/1, to_list/1]). % data WordState = {chunk, S} | {segment, L, C, R} nil() -> nil. singleton(S) -> {single, S}. conc(A, B) -> {conc, A, B}. to_list(nil) -> []; to_list({single, S}) -> [S]; to_list({conc, A, B}) -> to_list(A) ++ to_list(B). maybe_word("") -> nil(); maybe_word(S) -> singleton(S). process_char($ ) -> {segment, "", nil(), ""}; process_char(C) -> {chunk, [C]}. combine({chunk, S1}, {chunk, S2}) -> {chunk, S1 ++ S2}; combine({chunk, S}, {segment, L, C, R}) -> {segment, L ++ S, C, R}; combine({segment, L, C, R}, {chunk, S}) -> {segment, L, C, R ++ S}; combine({segment, L1, C1, R1}, {segment, L2, C2, R2}) -> {segment, L1, conc(C1, conc(maybe_word(R1 ++ L2), C2)), R2}. words([X|XS]) -> T = lists:foldl(fun(A, B) -> combine(B, A) end, process_char(X), lists:map(fun(C) -> process_char(C) end, XS)), case T of {chunk, C} -> maybe_word(C); {segment, L, C, R} -> conc(maybe_word(L), conc(C, maybe_word(R))) end.