호두나무 공방/Exercism in Elixir

Complex Numbers - Exercism in Elixir

2022. 8. 19. 22:02

문제 보기

복소수 연산을 구현하는 문제였다. 어려운 것은 아니고, 구현 양이 많아서 조금 번거로웠던 문제.

defmodule ComplexNumbers do
  @typedoc """
  In this module, complex numbers are represented as a tuple-pair containing the real and
  imaginary parts.
  For example, the real number `1` is `{1, 0}`, the imaginary number `i` is `{0, 1}` and
  the complex number `4+3i` is `{4, 3}'.
  """
  @type complex :: {float, float}

  @doc """
  Return the real part of a complex number
  """
  @spec real(a :: complex) :: float
  def real({r, _}) do
    r
  end

  @doc """
  Return the imaginary part of a complex number
  """
  @spec imaginary(a :: complex) :: float
  def imaginary({_, i}) do
    i
  end

  @doc """
  Multiply two complex numbers, or a real and a complex number
  """
  @spec mul(a :: complex | float, b :: complex | float) :: complex
  def mul(a, b) do
    {ra, ia} = wrap(a)
    {rb, ib} = wrap(b)
    {ra * rb - ia * ib, ia * rb + ra * ib}
  end

  @doc """
  Add two complex numbers, or a real and a complex number
  """
  @spec add(a :: complex | float, b :: complex | float) :: complex
  def add(a, b) do
    {ra, ia} = wrap(a)
    {rb, ib} = wrap(b)
    {ra + rb, ia + ib}
  end

  @doc """
  Subtract two complex numbers, or a real and a complex number
  """
  @spec sub(a :: complex | float, b :: complex | float) :: complex
  def sub(a, b) do
    {ra, ia} = wrap(a)
    {rb, ib} = wrap(b)
    {ra - rb, ia - ib}
  end

  @doc """
  Divide two complex numbers, or a real and a complex number
  """
  @spec div(a :: complex | float, b :: complex | float) :: complex
  def div(a, b) do
    {ra, ia} = wrap(a)
    {rb, ib} = wrap(b)
    {
      (ra * rb + ia * ib) / (rb * rb + ib * ib), 
      (ia * rb - ra * ib) / (rb * rb + ib * ib)
    }
  end

  @doc """
  Absolute value of a complex number
  """
  @spec abs(a :: complex) :: float
  def abs({r, i}) do
    Float.pow(r * r + i * i * 1.0, 0.5)
  end

  @doc """
  Conjugate of a complex number
  """
  @spec conjugate(a :: complex) :: complex
  def conjugate({r, i}) do
    {r, -1 * i}
  end

  @doc """
  Exponential of a complex number
  """
  @spec exp(a :: complex) :: complex
  def exp({r, i}) do
    {:math.exp(r) * :math.cos(i), :math.exp(r) * :math.sin(i)}
  end

  defp wrap(a) when is_number(a), do: {a, 0}
  defp wrap(a) when is_tuple(a), do: a
end

'호두나무 공방 > Exercism in Elixir' 카테고리의 다른 글

Luhn - Exercism in Elixir  (0) 2022.09.06
Meetup - Exercism in Elixir  (0) 2022.09.05
Square Root - Exercism in Elixir  (0) 2022.08.18
Pythagorean Triplet - Exercism in Elixir  (0) 2022.08.17
Custom Set - Exercism in Elixir  (0) 2022.08.16