Erlang Century From Year
-module(century_from_year).
-export([century_from_year/1]).

century_from_year(Year) ->
    (Year + 99) div 100.

This converts a year into its century. Years 1-100 are century 1, 101-200 are century 2, and so on.

Erlang Check Palindrome
-module(check_palindrome).
-export([check_palindrome/1]).

check_palindrome(InputString) ->
    lists:reverse(InputString) =:= InputString.

This compares the string with its reverse. If they match, it is a palindrome.

Erlang Chocolates By Numbers
-module(chocolates_by_numbers).
-export([chocolates_by_numbers/2]).

chocolates_by_numbers(N, M) ->
    G = gcd(N, M),
    (N * M) div G div M.

gcd(N, M) when N rem M =:= 0 -> M;
gcd(N, M) -> gcd(M, N rem M).

This uses the greatest common divisor to figure out how many chocolates get eaten before the pattern repeats.

Erlang Common Prime Divisors
-module(common_prime_divisors).
-export([common_prime_divisors/2]).

common_prime_divisors(A, B) ->
    length([ok || {X, Y} <- lists:zip(A, B), has_same_prime_divisors(X, Y)]).

has_same_prime_divisors(X, Y) ->
    D = gcd(X, Y),
    case remove_common(X, D) of
        1 -> remove_common(Y, D) =:= 1;
        _ -> false
    end.

remove_common(1, _) -> 1;
remove_common(N, M) ->
    case gcd(N, M) of
        1 -> N;
        D -> remove_common(N div D, M)
    end.

gcd(N, M) when N rem M =:= 0 -> M;
gcd(N, M) -> gcd(M, N rem M).

This checks whether two numbers are built from the same prime factors by repeatedly dividing out their shared parts.

Erlang Count Div
-module(count_div).
-export([count_div/3]).

count_div(A, B, K) ->
    FirstDiv = case A rem K of
        0 -> A;
        R -> A + (K - R)
    end,
    LastDiv = B - (B rem K),
    (LastDiv - FirstDiv) div K + 1.

This counts how many numbers in a range are divisible by K without looping through every value.

Erlang Count Factors
-module(count_factors).
-export([count_factors/1]).

count_factors(N) ->
    count_factors(N, 1, 0).

count_factors(N, I, Count) when I * I < N ->
    NewCount = case N rem I =:= 0 of
        true -> Count + 2;
        false -> Count
    end,
    count_factors(N, I + 1, NewCount);
count_factors(N, I, Count) when I * I =:= N ->
    Count + 1;
count_factors(_, _, Count) ->
    Count.

This checks divisors in pairs up to the square root, which keeps the work much smaller than testing every number.

Erlang Count Non Divisible
-module(count_non_divisible).
-export([count_non_divisible/1]).

count_non_divisible(A) ->
    Size = length(A),
    Occ = lists:foldl(fun(V, Map) ->
        maps:update_with(V, fun(C) -> C + 1 end, 1, Map)
    end, #{}, A),
    [Size - count_divisors(V, Occ) || V <- A].

count_divisors(V, Occ) ->
    count_divisors(V, Occ, 1, 0).

count_divisors(V, _Occ, I, Count) when I * I > V ->
    Count;
count_divisors(V, Occ, I, Count) ->
    case V rem I of
        0 ->
            Base = Count + maps:get(I, Occ, 0),
            Total = case V div I =:= I of
                true -> Base;
                false -> Base + maps:get(V div I, Occ, 0)
            end,
            count_divisors(V, Occ, I + 1, Total);
        _ ->
            count_divisors(V, Occ, I + 1, Count)
    end.

This counts how often each value appears, then subtracts the divisor matches so you get the non-divisible count for each item.

Erlang Count Semi Primes
-module(count_semi_primes).
-export([count_semi_primes/3]).

count_semi_primes(N, P, Q) ->
    IsPrime = sieve(N),
    Flags = mark_semiprimes(N, IsPrime),
    Prefix = prefix_cumulative(N, Flags),
    [array:get(Qi, Prefix) - array:get(Pi - 1, Prefix) || {Pi, Qi} <- lists:zip(P, Q)].

sieve(N) ->
    Arr0 = array:new(N + 1, {default, true}),
    Arr1 = array:set(0, false, Arr0),
    Arr2 = case N >= 1 of
        true -> array:set(1, false, Arr1);
        false -> Arr1
    end,
    sieve(2, N, Arr2).

sieve(I, N, Arr) when I * I > N ->
    Arr;
sieve(I, N, Arr) ->
    Arr1 = case array:get(I, Arr) of
        true -> mark_multiples(I * I, I, N, Arr);
        false -> Arr
    end,
    sieve(I + 1, N, Arr1).

mark_multiples(K, _Step, N, Arr) when K > N ->
    Arr;
mark_multiples(K, Step, N, Arr) ->
    mark_multiples(K + Step, Step, N, array:set(K, false, Arr)).

mark_semiprimes(N, IsPrime) ->
    Flags0 = array:new(N + 1, {default, 0}),
    mark_k(2, N, IsPrime, Flags0).

mark_k(K, N, _IsPrime, Flags) when K * K > N ->
    Flags;
mark_k(K, N, IsPrime, Flags) ->
    Flags1 = case array:get(K, IsPrime) of
        true -> mark_i(2, K, N, IsPrime, Flags);
        false -> Flags
    end,
    mark_k(K + 1, N, IsPrime, Flags1).

mark_i(I, K, N, _IsPrime, Flags) when I * K > N ->
    Flags;
mark_i(I, K, N, IsPrime, Flags) ->
    Flags1 = case array:get(I, IsPrime) of
        true -> array:set(K * I, 1, Flags);
        false -> Flags
    end,
    mark_i(I + 1, K, N, IsPrime, Flags1).

prefix_cumulative(N, Flags) ->
    {_, Prefix} = lists:foldl(fun(I, {Prev, Acc}) ->
        Cur = Prev + array:get(I, Flags),
        {Cur, array:set(I, Cur, Acc)}
    end, {0, Flags}, lists:seq(1, N)),
    Prefix.

This precomputes semiprimes and prefix sums so each range query becomes a quick subtraction.

Erlang Cyclic Rotation
-module(cyclic_rotation).
-export([cyclic_rotation/2]).

cyclic_rotation([], _K) ->
    [];
cyclic_rotation(A, K) ->
    N = length(A),
    Shift = K rem N,
    {Front, Back} = lists:split(N - Shift, A),
    Back ++ Front.

This rotates the array to the right by K steps and keeps the wrap-around values in the correct order.

Erlang Distinct
-module(distinct).
-export([distinct/1]).

distinct(A) ->
    length(lists:usort(A)).

This counts unique values by tracking what has already been seen.