Lisp Count Non Divisible
(defun count-non-divisible (a)
  (let* ((vec (coerce a 'vector))
         (size (length vec))
         (occurrences (make-array (1+ (reduce #'max vec)) :initial-element 0)))
    (loop for v across vec do (incf (aref occurrences v)))
    (loop for v across vec
          collect (let ((count 0) (i 1))
                    (loop while (<= (* i i) v)
                          do (progn
                               (when (zerop (mod v i))
                                 (incf count (aref occurrences i))
                                 (unless (= (/ v i) i)
                                   (incf count (aref occurrences (/ v i)))))
                               (incf i)))
                    (- size count)))))

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

PHP Count Non Divisible
function countNonDivisible(array $a): array
{
    $size       = count($a);
    $nondivisor = array_fill(0, $size, 0);
    $occurences = array_fill(0, max($a) + 1, 0);

    foreach ($a as $v) {
        $occurences[$v]++;
    }

    foreach ($a as $k => $v) {
        $count = 0;
        $i     = 1;
        while ($i * $i <= $v) {
            if ($v % $i === 0) {
                $count += $occurences[$i];
                if ($v / $i !== $i) {
                    $count += $occurences[$v / $i];
                }
            }
            $i++;
        }
        $nondivisor[$k] = $size - $count;
    }

    return $nondivisor;
}

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

Python Count Non Divisible
def count_non_divisible(a: list[int]) -> list[int]:
    size = len(a)
    occurrences = [0] * (max(a) + 1)
    for v in a:
        occurrences[v] += 1

    nondivisor = [0] * size
    for k, v in enumerate(a):
        count = 0
        i = 1
        while i * i <= v:
            if v % i == 0:
                count += occurrences[i]
                if v // i != i:
                    count += occurrences[v // i]
            i += 1
        nondivisor[k] = size - count

    return nondivisor

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

Rust Count Non Divisible
fn count_non_divisible(a: &[i64]) -> Vec<i64> {
    let size = a.len();
    let max_val = *a.iter().max().unwrap() as usize;
    let mut occurrences = vec![0i64; max_val + 1];

    for &v in a {
        occurrences[v as usize] += 1;
    }

    let mut nondivisor = vec![0i64; size];
    for (k, &v) in a.iter().enumerate() {
        let mut count = 0;
        let mut i = 1i64;
        while i * i <= v {
            if v % i == 0 {
                count += occurrences[i as usize];
                if v / i != i {
                    count += occurrences[(v / i) as usize];
                }
            }
            i += 1;
        }
        nondivisor[k] = size as i64 - count;
    }

    nondivisor
}

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

TypeScript Count Non Divisible
function countNonDivisible(a: number[]): number[] {
  const size = a.length;
  const nondivisor: number[] = new Array(size).fill(0);
  const occurences: number[] = new Array(Math.max(...a) + 1).fill(0);

  for (const v of a) {
    occurences[v]++;
  }

  for (let k = 0; k < size; k++) {
    const v = a[k];
    let count = 0;
    let i = 1;
    while (i * i <= v) {
      if (v % i === 0) {
        count += occurences[i];
        if (v / i !== i) {
          count += occurences[v / i];
        }
      }
      i++;
    }
    nondivisor[k] = size - count;
  }

  return nondivisor;
}

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

Bash Count Semi Primes
count_semi_primes() {
    local _n=$1
    local -n _pArr="$2"
    local -n _qArr="$3"
    local -n _outArr="$4"
    local -a _is_prime _semi _cum
    local _i _k _idx
    for ((_i = 0; _i <= _n; _i++)); do _is_prime[_i]=1; _semi[_i]=0; done
    for ((_i = 2; _i * _i <= _n; _i++)); do
        if (( _is_prime[_i] )); then
            for ((_k = _i * _i; _k <= _n; _k += _i)); do
                _is_prime[_k]=0
            done
        fi
    done
    for ((_k = 2; _k * _k <= _n; _k++)); do
        if (( _is_prime[_k] )); then
            for ((_i = 2; _i * _k <= _n; _i++)); do
                if (( _is_prime[_i] )); then
                    _semi[_k * _i]=1
                fi
            done
        fi
    done
    _cum[0]=${_semi[0]}
    for ((_i = 1; _i <= _n; _i++)); do
        _cum[_i]=$(( _cum[_i-1] + _semi[_i] ))
    done
    _outArr=()
    for _idx in "${!_pArr[@]}"; do
        local _lo=${_pArr[$_idx]}
        local _hi=${_qArr[$_idx]}
        _outArr[_idx]=$(( _cum[_hi] - _cum[_lo-1] ))
    done
}

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

C++ Count Semi Primes
#include <cstddef>
#include <vector>

std::vector<int> countSemiPrimes(int n, const std::vector<int>& p, const std::vector<int>& q)
{
    std::vector<bool> primes(n + 1, true);
    std::vector<int> semiPrimes(n + 1, 0);
    std::vector<int> semiPrimeCounts(p.size(), 0);

    for (int i = 2; i * i <= n; ++i) {
        if (primes[i]) {
            for (int k = i * i; k <= n; k += i) {
                primes[k] = false;
            }
        }
    }

    for (int k = 2; k * k <= n; ++k) {
        if (primes[k]) {
            for (int i = 2; i * k <= n; ++i) {
                if (primes[i]) {
                    semiPrimes[k * i] = 1;
                }
            }
        }
    }

    for (int i = 1; i <= n; ++i) {
        semiPrimes[i] += semiPrimes[i - 1];
    }

    for (std::size_t k = 0; k < p.size(); ++k) {
        semiPrimeCounts[k] = semiPrimes[q[k]] - semiPrimes[p[k] - 1];
    }

    return semiPrimeCounts;
}

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

C# Count Semi Primes
static int[] CountSemiPrimes(int n, int[] p, int[] q)
{
    var primes = new bool[n + 1];
    Array.Fill(primes, true);
    var semiPrimes = new int[n + 1];

    for (int i = 2; i * i <= n; i++)
    {
        if (primes[i])
        {
            for (int k = i * i; k <= n; k += i)
            {
                primes[k] = false;
            }
        }
    }

    for (int k = 2; k * k <= n; k++)
    {
        if (primes[k])
        {
            for (int i = 2; i * k <= n; i++)
            {
                if (primes[i])
                {
                    semiPrimes[k * i] = 1;
                }
            }
        }
    }

    for (int i = 1; i <= n; i++)
    {
        semiPrimes[i] += semiPrimes[i - 1];
    }

    var semiPrimeCounts = new int[p.Length];
    for (int k = 0; k < p.Length; k++)
    {
        semiPrimeCounts[k] = semiPrimes[q[k]] - semiPrimes[p[k] - 1];
    }

    return semiPrimeCounts;
}

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

Elixir Count Semi Primes
defmodule CountSemiPrimes do
  def count_semi_primes(n, p, q) do
    primes = sieve(n)
    semi_flags = semi_prime_flags(n, primes)
    prefix = prefix_sums(semi_flags, n)

    p
    |> Enum.zip(q)
    |> Enum.map(fn {pi, qi} -> Map.get(prefix, qi) - Map.get(prefix, pi - 1, 0) end)
  end

  defp sieve(n) do
    initial = for i <- 0..n, into: %{}, do: {i, i >= 2}
    limit = :math.sqrt(n) |> trunc()

    Enum.reduce(2..limit//1, initial, fn i, primes ->
      if Map.get(primes, i) do
        Enum.reduce(i * i..n//i, primes, fn k, acc -> Map.put(acc, k, false) end)
      else
        primes
      end
    end)
  end

  defp semi_prime_flags(n, primes) do
    initial = for i <- 0..n, into: %{}, do: {i, 0}
    limit = :math.sqrt(n) |> trunc()

    Enum.reduce(2..limit//1, initial, fn k, flags ->
      if Map.get(primes, k) do
        mark_multiples(k, 2, n, primes, flags)
      else
        flags
      end
    end)
  end

  defp mark_multiples(k, i, n, _primes, flags) when i * k > n, do: flags

  defp mark_multiples(k, i, n, primes, flags) do
    flags = if Map.get(primes, i), do: Map.put(flags, k * i, 1), else: flags
    mark_multiples(k, i + 1, n, primes, flags)
  end

  defp prefix_sums(flags, n) do
    {result, _last} =
      Enum.reduce(1..n//1, {%{0 => Map.get(flags, 0, 0)}, Map.get(flags, 0, 0)}, fn i,
                                                                                      {acc, prev} ->
        cur = prev + Map.get(flags, i, 0)
        {Map.put(acc, i, cur), cur}
      end)

    result
  end
end

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

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.