defmodule Firebird.WasmModules.Algorithms do Module.register_attribute(__MODULE__, :wasm, accumulate: true) @moduledoc """ Common algorithms compiled to WebAssembly. Demonstrates the Elixir-to-WASM compilation for algorithmic workloads. All functions use only the compilable subset of Elixir. """ @wasm true def is_prime(n) do if n <= 1 do 0 else if n <= 3 do 1 else if rem(n, 2) == 0 do 0 else is_prime_check(n, 3) end end end end @wasm true def is_prime_check(n, i) do if i * i > n do 1 else if rem(n, i) == 0 do 0 else is_prime_check(n, i + 2) end end end @wasm true def count_primes(0), do: 0 def count_primes(n), do: is_prime(n) + count_primes(n - 1) @wasm true def ackermann(0, n), do: n + 1 def ackermann(m, 0), do: ackermann(m - 1, 1) def ackermann(m, n), do: ackermann(m - 1, ackermann(m, n - 1)) @wasm true def binary_search_sqrt(n) do binary_search_sqrt_helper(n, 0, n) end @wasm true def binary_search_sqrt_helper(n, lo, hi) do if lo > hi do lo - 1 else mid = div(lo + hi, 2) if mid * mid == n do mid else if mid * mid < n do binary_search_sqrt_helper(n, mid + 1, hi) else binary_search_sqrt_helper(n, lo, mid - 1) end end end end @wasm true def tribonacci(0), do: 0 def tribonacci(1), do: 1 def tribonacci(2), do: 1 def tribonacci(n), do: tribonacci(n - 1) + tribonacci(n - 2) + tribonacci(n - 3) @wasm true def digital_root(n) do if n < 10 do n else digital_root(div(n, 10) + rem(n, 10)) end end end