호두나무 공방/Exercism in Elixir

Transpose - Exercism in Elixir

2022. 10. 25. 22:49

문제 보기

여러 줄의 문자열이 주어졌을 때 가로세로를 바꿔 반환하는 문제였다. 예를 들어

ABC
DE

와 같이 주어지면

AD
BE
C

와 같이 반환하는 식이다. 원문의 이전 줄보다 다음 줄이 짧은 경우 문자열 끝에 해당하는 C 뒤에는 공백이 없어야 하는 등의 몇 가지 규칙이 조금 더 있다.

기본적으로 Enum.zip/1을 이용하되, 이 함수는 기본적으로 가장 짧은 리스트에 맞춰서 zip 연산을 하는 특징이 있어 패딩을 추가하고 그 패딩을 뒤에서 제거하는 처리를 추가했다. 패딩으로는 일반적인 문자에 존재하지 않을 문자인 <<0>>을 골랐고, 가로세로를 뒤집은 후 뒤쪽에 오는 <<0>>은 제거해야 하지만 나머지 <<0>>은 공백을 유지해야 하므로 공백 문자로 바꿨다.

여담이지만 Enum.map/2을 여러 차례 이어 썼는데, 비효율적인 코드지만 깔끔한 코드를 위해 퍼포먼스를 약간 희생했다고 보면 좋을 것 같다.

defmodule Transpose do
  @spec transpose(String.t()) :: String.t()
  def transpose(input) do
    lines = input |> String.split("\n")

    longest_len = lines |> Enum.max_by(&String.length/1) |> String.length()

    lines
    |> Enum.map(&String.pad_trailing(&1, longest_len, <<0>>))
    |> Enum.map(&String.graphemes/1) # 비효율이지만, 깔끔한 코드를 위한 약간의 희생
    |> Enum.zip()
    |> Enum.map(fn tuple ->
      tuple
      |> Tuple.to_list()
      |> Enum.join("")
      |> String.trim_trailing(<<0>>)
      |> String.replace(<<0>>, " ")
    end)
    |> Enum.join("\n")
  end
end

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

Knapsack - Exercism in Elixir  (0) 2022.10.27
Yacht - Exercism in Elixir  (0) 2022.10.26
Sieve - Exercism in Elixir  (0) 2022.10.24
Scale Generator - Exercism in Elixir  (0) 2022.10.13
Diamond - Exercism in Elixir  (0) 2022.10.12