Erlang Number Of Disc Intersections
-module(number_of_disc_intersections).
-export([number_of_disc_intersections/1]).

number_of_disc_intersections(A) ->
    C = length(A),
    Indexed = lists:zip(lists:seq(0, C - 1), A),
    {Start, End} = lists:foldl(fun({K, V}, {S, E}) ->
        KeyS = case K < V of true -> 0; false -> K - V end,
        KeyE = case K + V >= C of true -> C - 1; false -> K + V end,
        {array:set(KeyS, array:get(KeyS, S) + 1, S),
         array:set(KeyE, array:get(KeyE, E) + 1, E)}
    end, {array:new(C, {default, 0}), array:new(C, {default, 0})}, Indexed),
    compute_sum(0, 0, 0, C, Start, End).

compute_sum(K, _Active, Sum, C, _Start, _End) when K >= C ->
    Sum;
compute_sum(K, Active, Sum, C, Start, End) ->
    StartK = array:get(K, Start),
    EndK = array:get(K, End),
    Sum1 = Sum + Active * StartK + (StartK * (StartK - 1)) div 2,
    case Sum1 > 10000000 of
        true -> -1;
        false -> compute_sum(K + 1, Active + StartK - EndK, Sum1, C, Start, End)
    end.

This sorts disc start and end points and counts active overlaps without comparing every pair directly.

Erlang Odd Occurrences In Array
-module(odd_occurrences_in_array).
-export([odd_occurrences_in_array/1]).

odd_occurrences_in_array(A) ->
    lists:foldl(fun(X, Acc) -> Acc bxor X end, 0, A).

This uses XOR to cancel out pairs, leaving only the value that appears an odd number of times.

Erlang Palindrome Rearranging
-module(palindrome_rearranging).
-export([palindrome_rearranging/1]).

palindrome_rearranging(InputString) ->
    Counts = lists:foldl(fun(C, Map) ->
        maps:update_with(C, fun(N) -> N + 1 end, 1, Map)
    end, #{}, InputString),
    OddCount = length([ok || {_, V} <- maps:to_list(Counts), V rem 2 =/= 0]),
    OddCount =< 1.

This counts character frequency and checks whether the string has the right number of odd counts to form a palindrome.

Erlang Passing Cars
-module(passing_cars).
-export([passing_cars/1]).

passing_cars(A) ->
    {Result, _Multiply} = lists:foldl(fun(I, {Passing, Multiply}) ->
        case I of
            0 -> {Passing, Multiply + 1};
            _ when Multiply > 0 -> {Passing + Multiply, Multiply};
            _ -> {Passing, Multiply}
        end
    end, {0, 0}, A),
    case Result > 1000000000 of
        true -> -1;
        false -> Result
    end.

This counts eastbound cars as it scans, then adds them whenever a westbound car appears.

Erlang Peaks
-module(peaks).
-export([peaks/1]).

peaks(A) ->
    N = length(A),
    case N =< 2 of
        true -> 0;
        false ->
            {Sum0, Dist0, Last0} = build_sums(A, N),
            LastVal = array:get(N - 2, Sum0),
            Sum1 = array:set(N - 1, LastVal, Sum0),
            case LastVal =:= 0 of
                true -> 0;
                false ->
                    Dist1 = max(Dist0, N - Last0),
                    case find_block_size(Dist1, N, Sum1) of
                        {ok, BlockSize} -> N div BlockSize;
                        not_found ->
                            FinalSize = smallest_divisor_from(Dist1, N),
                            N div FinalSize
                    end
            end
    end.

build_sums(A, N) ->
    Arr = array:from_list(A),
    Sum0 = array:new(N, {default, 0}),
    {SumF, {DistF, LastF}} = lists:foldl(fun(I, {Sum, {Dist, Last}}) ->
        SumPrev = array:get(I - 1, Sum),
        Ai = array:get(I, Arr),
        IsPeak = Ai > array:get(I - 1, Arr) andalso Ai > array:get(I + 1, Arr),
        case IsPeak of
            true -> {array:set(I, SumPrev + 1, Sum), {max(Dist, I - Last), I}};
            false -> {array:set(I, SumPrev, Sum), {Dist, Last}}
        end
    end, {Sum0, {0, -1}}, lists:seq(1, N - 2)),
    {SumF, DistF, LastF}.

find_block_size(Dist, N, Sum) ->
    find_block_size((Dist bsr 1) + 1, Dist, N, Sum).

find_block_size(I, Dist, _N, _Sum) when I >= Dist ->
    not_found;
find_block_size(I, Dist, N, Sum) ->
    case N rem I =:= 0 andalso check_blocks(I, I, N, Sum, 0) of
        true -> {ok, I};
        false -> find_block_size(I + 1, Dist, N, Sum)
    end.

check_blocks(J, _Step, N, _Sum, _Last) when J > N ->
    true;
check_blocks(J, Step, N, Sum, Last) ->
    SumJ = array:get(J - 1, Sum),
    case SumJ =< Last of
        true -> false;
        false -> check_blocks(J + Step, Step, N, Sum, SumJ)
    end.

smallest_divisor_from(Dist, N) ->
    case N rem Dist of
        0 -> Dist;
        _ -> smallest_divisor_from(Dist + 1, N)
    end.

This finds the peak positions, then tests how many equal blocks can each contain at least one peak.

Erlang Perm Check
-module(perm_check).
-export([perm_check/1]).

perm_check(A) ->
    Sorted = lists:sort(A),
    Indexed = lists:zip(lists:seq(1, length(Sorted)), Sorted),
    case lists:all(fun({I, V}) -> I =:= V end, Indexed) of
        true -> 1;
        false -> 0
    end.

This validates that every value from 1 to N appears exactly once.

Erlang Perm Missing Element
-module(perm_missing_element).
-export([perm_missing_element/1]).

perm_missing_element(A) ->
    find_missing(lists:sort(A), 1).

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

This uses the expected sum of 1..N+1 and subtracts the actual sum to find the missing value.

Erlang Plagiarism Check
-module(plagiarism_check).
-export([plagiarism_check/2]).

%% Re-derived as a token-isomorphism check instead of porting PHP's
%% placeholder/regex substitution dance: tokenize both snippets, build a
%% one-way rename map from the mismatched, non-numeric tokens of Code1 onto
%% Code2, then verify applying that map to every token of Code1 reproduces
%% Code2 exactly.
plagiarism_check(Code1, Code2) ->
    C1 = string:join(Code1, " "),
    C2 = string:join(Code2, " "),
    case C1 =:= C2 of
        true ->
            false;
        false ->
            D1 = tokenize(C1),
            D2 = tokenize(C2),
            Map = lists:foldl(fun({T1, T2}, Acc) ->
                case T1 =/= T2 andalso not is_numeric_token(T1) of
                    true -> maps:put(T1, T2, Acc);
                    false -> Acc
                end
            end, #{}, lists:zip(D1, D2)),
            [maps:get(T, Map, T) || T <- D1] =:= D2
    end.

tokenize(S) ->
    case re:run(S, "[A-Za-z0-9_]+", [global, {capture, all, list}]) of
        {match, Matches} -> [Tok || [Tok] <- Matches];
        nomatch -> []
    end.

is_numeric_token(T) ->
    case string:to_integer(T) of
        {_, ""} -> true;
        _ ->
            case string:to_float(T) of
                {_, ""} -> true;
                _ -> false
            end
    end.

This flattens both snippets, tries consistent identifier replacements, and checks whether the rewritten code matches.

Erlang Shape Area
-module(shape_area).
-export([shape_area/1]).

shape_area(N) when N =< 1 ->
    1;
shape_area(N) ->
    shape_area(N - 1) + 4 * (N - 1).

This returns the area of the growing n-interesting polygon using the direct formula instead of building the shape.

Erlang Stone Blocks
-module(stone_blocks).
-export([stone_blocks/1]).

stone_blocks(H) ->
    {_, Blocks} = lists:foldl(fun(Hi, {Stack, BlocksCount}) ->
        Stack1 = pop_while_greater(Stack, Hi),
        case Stack1 of
            [Hi | _] -> {Stack1, BlocksCount};
            _ -> {[Hi | Stack1], BlocksCount + 1}
        end
    end, {[], 0}, H),
    Blocks.

pop_while_greater([Top | Rest], Hi) when Top > Hi ->
    pop_while_greater(Rest, Hi);
pop_while_greater(Stack, _Hi) ->
    Stack.

This uses a stack of active heights and only counts a new block when the wall needs a new height segment.