호두나무 공방/Exercism in Elixir

Freelancer Rates - Exercism in Elixir

2021. 10. 24. 02:03

문제 보기

프리랜서의 시급(과 할인율)이 주어졌을 때의 일당, 월급, 예산 안에서 고용할 수 있는 최대 일수를 계산하는 산수 문제였다.

어떤 함수는 실수를 반환해야 하고, 어떤 것은 정수를 반환해야 해서 타입 변환에 대해 고민하는 경우도 있을 것 같은데 (특히 타입 개념이 강한 언어를 쓰고 있던 경우), 엘릭서의 사칙연산에서는 좌우항의 값(피연산자, operand) 중 하나라도 실수인 경우 연산 결과가 항상 실수가 된다고 생각해 두면 그다지 어렵지 않게 코드를 작성할 수 있겠다. 즉 연산할 때 값의 타입을 정수 또는 실수에서 어느 한 쪽으로 명시적으로 캐스팅할 필요가 기본적으로는 없다.
덧: 실수에서 정수로의 변환이 필요한 경우 Kernel 모듈의 round/1, trunc/1, ceil/1, floor/1 등 필요에 따라 다양한 함수가 제공되니 골라 사용하면 된다(타입을 변환한다기보다는 실수에 대해 연산을 적용하여 정수 결과를 얻는다는 느낌이다). 정수에서 실수로 바꾸려는 경우는 앞에서 소개한 엘릭서 사칙연산의 특성으로 인해 거의 없겠지만, 굳이 필요하다면 값 * 1.0과 같이 쓰면 되지 않을까 싶다.

defmodule FreelancerRates do
  def daily_rate(hourly_rate) do
    hourly_rate * 8.0
  end

  def apply_discount(before_discount, discount) do
    before_discount * (100 - discount) / 100.0
  end

  def monthly_rate(hourly_rate, discount) do
    (daily_rate(hourly_rate) * 22)
    |> apply_discount(discount)
    |> ceil()
  end

  def days_in_budget(budget, hourly_rate, discount) do
    daily = daily_rate(hourly_rate) |> apply_discount(discount)

    (budget / daily)
    |> Float.floor(1)
  end
end

여담이지만 아직 Exercism에서 소개되지 않은 파이프 연산자(|>)를 사용했다. 레퍼런스 보기 진도상 안 쓰는 것이 낫기는 하겠지만, 엘릭서에서 함수를 여러 개 연달아 호출하는데 파이프 연산자를 쓰지 않는 것은 너무나도 끔찍한 일이라 그냥 쓰게 되었다.
사칙연산을 포함하여 모든 연산에 파이프 연산자를 써 볼까 하는 생각도 했었다. 불가능하지는 않다.

def monthly_rate(hourly_rate, discount) do
  hourly_rate
  |> daily_rate()
  |> Kernel.*(22)
  |> apply_discount(discount)
  |> ceil()
end

파이프 관점에서만 보면 제법 깔끔한 코드이긴 하나, 의미를 이해하기에는 그다지 좋지 않은 듯하여 사칙연산은 기본적인 형태 그대로 사용했다.

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

Log Level - Exercism in Elixir  (0) 2021.10.24
Language List - Exercism in Elixir  (0) 2021.10.24
Pacman Rules - Exercism in Elixir  (0) 2021.10.24
Secrets - Exercism in Elixir  (0) 2021.10.17
Lasagna - Exercism in Elixir  (0) 2021.10.17