호두나무 공방/Exercism in Elixir 122

Transpose - Exercism in Elixir

문제 보기 여러 줄의 문자열이 주어졌을 때 가로세로를 바꿔 반환하는 문제였다. 예를 들어 ABC DE 와 같이 주어지면 AD BE C 와 같이 반환하는 식이다. 원문의 이전 줄보다 다음 줄이 짧은 경우 문자열 끝에 해당하는 C 뒤에는 공백이 없어야 하는 등의 몇 가지 규칙이 조금 더 있다. 기본적으로 Enum.zip/1을 이용하되, 이 함수는 기본적으로 가장 짧은 리스트에 맞춰서 zip 연산을 하는 특징이 있어 패딩을 추가하고 그 패딩을 뒤에서 제거하는 처리를 추가했다. 패딩으로는 일반적인 문자에 존재하지 않을 문자인 을 골랐고, 가로세로를 뒤집은 후 뒤쪽에 오는 은 제거해야 하지만 나머지 은 공백을 유지해야 하므로 공백 문자로 바꿨다. 여담이지만 Enum.map/2을 여러 차례 이어 썼는데, 비효율적인..

Sieve - Exercism in Elixir

문제 보기 소수를 구하는 에라토스테네스의 체를 구현하는 문제였다. 개념은 쉬운데, 코드에서 나눗셈 또는 나머지 연산을 사용하지 말아야 한다는 조건이 붙었다(대신 곱셈을 사용하라는 의도). 우선 처음에 나눗셈을 사용해서 짠 간단한 코드는 이쪽. defmodule Sieve do @doc """ Generates a list of primes up to a given limit. """ @spec primes_to(non_neg_integer) :: [non_neg_integer] def primes_to(limit) do 2..limit//1 |> Enum.to_list() |> do_primes_to([]) |> Enum.reverse() end defp do_primes_to([], primes), d..

Scale Generator - Exercism in Elixir

문제 보기 음계 계산과 관련된 여러 함수를 구현하는 문제였다. 특정 음에서 1도~3도 떨어진 음은 무엇인가, 특정 음에서 시작하는 1옥타브를 플랫 또는 샵 표현으로 나타내거나 등등. 마지막 함수는 앞에서 구현한 함수들을 모두 활용해야 하는 문제였어서 과제가 유기적으로 연결된 듯 하여 재미있게 풀었다. defmodule ScaleGenerator do @spec step(scale :: list(String.t()), tonic :: String.t(), step :: String.t()) :: String.t() def step(scale, tonic, step) do tonic_index = scale |> Enum.find_index(fn s -> s == tonic end) index = case ..

Diamond - Exercism in Elixir

문제 보기 가로세로 위치에 따라 적당한 알파벳을 출력하여 다이아몬드 모양을 만드는, 배열 인덱스 계산의 단골 문제. 어렵지는 않으나 다이아몬드의 상하부를 나눠 생각해야 하기도 하고, 중앙 기준으로도 나눠 생각해야 해서 역시 번거롭다. defmodule Diamond do @doc """ Given a letter, it prints a diamond starting with 'A', with the supplied letter at the widest point. """ @spec build_shape(char) :: String.t() def build_shape(letter) do last_index = 2 * (letter - ?A) center_index = last_index / ..

Palindrome Products - Exercism in Elixir

문제 보기 자연수의 범위가 주어질 때, 범위 내의 두 수를 곱해 만들어지는 수 중에서 앞뒤가 똑같은 수(palindrome)를 찾아내는 문제였다. 처음에는 퍼포먼스를 생각하느라 Enum.reduce/3를 써서 조건에 맞는 수와 아닌 수를 다 저장하는 식으로 복잡하게 구현했는데, Exercism 웹에서 돌리는 테스트에서는 큰 수 테스트가 아예 빠져 있어서 그냥 마음 편하게 간단한 코드로 고쳤다. defmodule PalindromeProducts do @doc """ Generates all palindrome products from an optionally given min factor (or 1) to a given max factor. """ @spec generate(non_neg_integer,..

Affine Cipher - Exercism in Elixir

문제 보기 고대 중동의 암호화 알고리즘을 간단하게 구현하는 문제였다. 이런 치환암호(substitution cipher) 방식의 알고리즘은 엘릭서에서는 문자 리스트로 바꿔서 처리하는 것이 간단하다. 배경 지식인 건지 내가 텍스트에서 못 찾은 건지, 설명에 몇 가지 내용이 빠져 있어서 테스트 케이스를 더듬어가며 답을 찾아야 하는 과정이 조금 번거로웠다. MMI(나머지 연산의 역원)를 구하는 과정에 스트림을 쓴 것이 내심 만족스럽다. defmodule AffineCipher do @typedoc """ A type for the encryption key """ @type key() :: %{a: integer, b: integer} @doc """ Encode an encrypted message usin..

Tournament - Exercism in Elixir

문제 보기 대회 결과가 문자열 형태(예: Allegoric Alaskans;Blithering Badgers;win)로 주어질 때, 순위표를 만들어 출력하는 문제였다. 로직은 단순한데 양 팀을 모두 생각해야 하고 출력부도 있어서 코드 양이 조금 많다. 구조체를 써서 필요한 필드를 갖추고 시작하니 편했다. defmodule Tournament do defmodule Team do defstruct [:name, w: 0, d: 0, l: 0, p: 0] end @spec tally(input :: list(String.t())) :: String.t() def tally(input) do input |> Enum.reduce(%{}, fn match, acc -> with [team_a, team_b, r..

Phone Number - Exercism in Elixir

문제 보기 규칙에 맞게 전화번호 유효성 검증을 하는 문제였다. 지역번호나 국번의 첫 자리가 0이나 1이 아니어야 한다든가 하는 세세한 규칙이 있어 코드가 좀 늘어난 것 빼고는 크게 어렵지는 않았다. 원본 입력 문자열에서 숫자만 취해서 값을 검증하기만 하면 되는 것이 아니라, 자리수를 구분하는 -나 지역번호를 구분하는 ()는 제거하되, 다른 문자가 섞여 있는 것을 찾기 위해 알파벳이나 다른 특수문자는 일시적으로 남겨둬야 한다는 부분이 다소 번거로웠다. defmodule PhoneNumber do @doc """ Remove formatting from a phone number if the given number is valid. Return an error otherwise. """ @spec clean..

Grep - Exercism in Elixir

문제 보기 파일 안의 내용을 검색하는 grep 명령어의 기능을 엘릭서를 사용하여 구현하는 문제였다. 기본적인 기능은 당연하게도 어렵지 않으나, 여러 플래그에 따라 다르게 동작해야 하는 부분이 있어 다소 까다로웠다. 몇몇 플래그는 함수를 따로 만들어 분리할 수 있었는데, 지나치게 간단하거나 지나치게 복잡한 것들은 함수로 분리하기도 애매하여... 결국 조건문 투성이인 코드가 되었다. 문제 카테고리를 뒤늦게 보니 정규식을 쓰기를 의도한 것 같다. 실제로 검색에 영향을 주는 앞쪽 플래그 3개는 정규식으로 바꾸면(문자열로 정규식을 조합한 뒤 Regex.compile/2를 호출하는 흐름이 되었으리라) 조금 더 깔끔히 풀 수 있었을 듯도 싶다. defmodule Grep do @spec grep(String.t(),..

Kindergarten Garden - Exercism in Elixir

문제 보기 유치원에서 원생들이 식물을 키울 수 있도록 화분을 일정한 규칙에 따라 각 4개씩 배정해 주는데, 문자열로 구성된 화분 데이터를 받아 누가 어떤 식물을 키우고 있는지를 반환하는 함수를 작성하는 문제였다. Easy 난이도 문제이긴 하지만 원생의 이름이 알파벳 순으로 정렬되어야 한다든가, 화분을 배정하지 않은 원생의 항목도 갖고 있어야 한다든가 등등 이래저래 요구하는 부분이 있어 코드가 조금 길어졌다. defmodule Garden do @doc """ Accepts a string representing the arrangement of cups on a windowsill and a list with names of students in the class. The student names lis..