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.

Erlang Max Counters
-module(max_counters).
-export([max_counters/2]).

max_counters(N, A) ->
    Condition = N + 1,
    {CountersMap, _MaxCounter, LastUpdate} = lists:foldl(fun(V, {Map, MaxC, Last}) ->
        case V of
            Condition ->
                {Map, MaxC, MaxC};
            _ when V =< N ->
                Index = V - 1,
                NewVal = max(maps:get(Index, Map, 0), Last) + 1,
                {maps:put(Index, NewVal, Map), max(MaxC, NewVal), Last};
            _ ->
                {Map, MaxC, Last}
        end
    end, {#{}, 0, 0}, A),
    [max(maps:get(I, CountersMap, 0), LastUpdate) || I <- lists:seq(0, N - 1)].

This delays the expensive “set all counters to max” work until it is really needed, which keeps the solution fast.

Erlang Max Double Slice Sum
-module(max_double_slice_sum).
-export([max_double_slice_sum/1]).

max_double_slice_sum(A) ->
    Size = length(A),
    case Size < 3 of
        true -> 0;
        false ->
            Arr = array:from_list(A),
            P1 = build_p1(Arr, Size),
            P2 = build_p2(Arr, Size),
            lists:max([array:get(I, P1) + array:get(I, P2) || I <- lists:seq(1, Size - 2)])
    end.

build_p1(Arr, Size) ->
    P0 = array:set(1, 0, array:new(Size)),
    lists:foldl(fun(I, Acc) ->
        V = max(0, array:get(I - 1, Acc) + array:get(I - 1, Arr)),
        array:set(I, V, Acc)
    end, P0, lists:seq(2, Size - 2)).

build_p2(Arr, Size) ->
    P0 = array:set(Size - 2, 0, array:new(Size)),
    lists:foldl(fun(J, Acc) ->
        V = max(0, array:get(J + 1, Acc) + array:get(J + 1, Arr)),
        array:set(J, V, Acc)
    end, P0, lists:seq(Size - 3, 1, -1)).

This keeps the best sum ending on the left and starting on the right, then combines them around each middle position.

Erlang Max Product Of Three
-module(max_product_of_three).
-export([max_product_of_three/1]).

max_product_of_three(A) ->
    Sorted = lists:sort(A),
    N = length(Sorted),
    Top3 = lists:nth(N, Sorted) * lists:nth(N - 1, Sorted) * lists:nth(N - 2, Sorted),
    TwoLowOneHigh = lists:nth(1, Sorted) * lists:nth(2, Sorted) * lists:nth(N, Sorted),
    max(Top3, TwoLowOneHigh).

This checks the useful extremes, because the best product can come from either the three largest numbers or two negatives plus one large positive.

Erlang Max Profit
-module(max_profit).
-export([max_profit/1]).

max_profit([H | T]) ->
    {_, Profit} = lists:foldl(fun(V, {MinPrice, MaxProfit}) ->
        MinPrice1 = min(MinPrice, V),
        {MinPrice1, max(MaxProfit, V - MinPrice1)}
    end, {H, 0}, T),
    Profit.

This tracks the lowest buy price seen so far and updates the best profit as it scans the prices once.

Erlang Max Slice Sum
-module(max_slice_sum).
-export([max_slice_sum/1]).

max_slice_sum([H | T]) ->
    {_, Max} = lists:foldl(fun(V, {Tmp, MaxV}) ->
        Tmp1 = max(Tmp + V, V),
        {Tmp1, max(MaxV, Tmp1)}
    end, {H, H}, T),
    Max.

This is a Kadane-style scan: keep the best running sum and the best overall sum while moving once through the array.

Erlang Min Avg Two Slice
-module(min_avg_two_slice).
-export([min_avg_two_slice/1]).

min_avg_two_slice(A) ->
    N = length(A),
    Arr = array:from_list(A),
    Init = (array:get(0, Arr) + array:get(1, Arr)) / 2,
    {_, Idx} = lists:foldl(fun(I, {MinV, IdxAcc}) ->
        Two = (array:get(I, Arr) + array:get(I + 1, Arr)) / 2,
        Cur = case I + 2 < N of
            true ->
                Three = (array:get(I, Arr) + array:get(I + 1, Arr) + array:get(I + 2, Arr)) / 3,
                min(Two, Three);
            false ->
                Two
        end,
        case Cur < MinV of
            true -> {Cur, I};
            false -> {MinV, IdxAcc}
        end
    end, {Init, 0}, lists:seq(0, N - 2)),
    Idx.

This leans on the key trick for this problem: the minimum average slice is always length 2 or 3.

Erlang Min Perimeter Rectangle
-module(min_perimeter_rectangle).
-export([min_perimeter_rectangle/1]).

min_perimeter_rectangle(N) ->
    find_min(1, N, 1 bsl 128).

find_min(I, N, Min) when I * I >= N ->
    Min;
find_min(I, N, Min) ->
    Min1 = case N rem I of
        0 -> min(Min, 2 * (I + (N div I)));
        _ -> Min
    end,
    find_min(I + 1, N, Min1).

This searches factor pairs up to the square root and picks the pair with the smallest perimeter.

Erlang Missing Integer
-module(missing_integer).
-export([missing_integer/1]).

missing_integer(A) ->
    Positives = [V || V <- lists:usort(A), V > 0],
    find_missing(Positives, 1).

find_missing([], Min) ->
    Min;
find_missing([V | Rest], Min) ->
    case V =:= Min of
        true -> find_missing(Rest, Min + 1);
        false -> Min
    end.

This records the positive numbers that exist, then returns the smallest positive value that is still missing.

Erlang Nesting
-module(nesting).
-export([nesting/1]).

nesting(S) ->
    case close_stack(S, []) of
        [] -> 1;
        _  -> 0
    end.

close_stack([], Stack) -> Stack;
close_stack([$) | T], [$( | Rest]) -> close_stack(T, Rest);
close_stack([$) | _], _Stack) -> error;
close_stack([C | T], Stack) -> close_stack(T, [C | Stack]).

This treats the string like a balance counter: open parentheses add one, closing ones remove one.