Erlang Largest String
-module(largest_string).
-export([largest_string/1]).

largest_string(S) ->
    Len = length(S),
    Arr0 = array:from_list(S),
    ArrFinal = process(Len - 1, Arr0, Len),
    array:to_list(ArrFinal).

%% Fewer than 3 characters remain before the current position, so no more
%% "abb" windows can be completed.
process(P, Arr, _Len) when P < 2 ->
    Arr;
process(P, Arr, Len) ->
    I = P - 2,
    {Arr1, I2} = handle_triple(I, Arr, Len),
    process(I2 - 1, Arr1, Len).

handle_triple(I, Arr, Len) ->
    Window = [array:get(I, Arr), array:get(I + 1, Arr), array:get(I + 2, Arr)],
    case Window of
        "abb" ->
            Arr1 = array:set(I, $b, array:set(I + 1, $a, array:set(I + 2, $a, Arr))),
            I1 = advance_on_b(I, Arr1, Len),
            final_adjust(I1, Arr1, Len);
        _ ->
            final_adjust(I, Arr, Len)
    end.

advance_on_b(I, Arr, Len) ->
    case I + 4 < Len andalso array:get(I + 4, Arr) =:= $b of
        true -> I + 4 + 1;
        false ->
            case I + 3 < Len andalso array:get(I + 3, Arr) =:= $b of
                true -> I + 3 + 1;
                false -> I
            end
    end.

final_adjust(I, Arr, Len) ->
    case I + 1 < Len andalso array:get(I + 1, Arr) =:= $b of
        true -> {Arr, I + 2};
        false -> {Arr, I + 1}
    end.

This builds the biggest valid string it can under the challenge rules by always choosing the best next character it is allowed to use.