호두나무 공방/Exercism in Elixir 122

Community Garden - Exercism in Elixir

문제 보기 상태를 저장하기 위한 목적으로 추상화된 엘릭서 프로세서인 Agent를 사용해보는 개념 문제였다. 데이터를 입력/조회/삭제하는 문제로, 큰 틀은 간단하나 ID 기반 조회/삭제가 가능해야 해서 리스트 대신 맵을 사용했다. # Use the Plot struct as it is provided defmodule Plot do @enforce_keys [:plot_id, :registered_to] defstruct [:plot_id, :registered_to] end defmodule CommunityGarden do def start(opts \\ []) do Agent.start(fn -> %{plots: %{}, last_id: 0} end, opts) end def list_registra..

Top Secret - Exercism in Elixir

문제 보기 엘릭서의 AST를 다루는 개념 문제였다. 심화 개념인 만큼 개념 문제 치고 난이도가 꽤 높은 편이었다. 파싱해야 하는 모듈-함수 중첩 구조를 코드에 어떻게 잘 녹일 것인지 고민할 필요가 있었다. defmodule TopSecret do def to_ast(string) do Code.string_to_quoted!(string) end def decode_secret_message_part(ast, acc) do case ast do {d, _, [{:when, _, [{func_name, _, params} | _]} | _]} when d in [:def, :defp] -> {ast, build_acc(func_name, params, acc)} {d, _, [{func_name, _, p..

Change - Exercism in Elixir

문제 보기 동전의 종류들이 리스트로 주어질 때, 그 동전들을 이용해서 주어진 금액을 맞출 수 있는지 확인하고, 맞출 수 있다면 동전 개수가 최소가 되도록 하는 조합을 찾는 문제였다. Dynamic programming을 쓰면 괜찮겠다 싶어 도입해 보았다. 이를테면 다음과 같다. 1원, 5원, 10원짜리 동전이 있고, 그것으로 18원을 맞춰야 하는 경우 - Case 1) 10원짜리 동전을 하나 사용했다고 가정하고, 같은 동전으로 8원을 추가로 맞추면 됨 - Case 2) 5원짜리 동전을 하나 사용했다고 가정하고, 같은 동전으로 13원을 추가로 맞추면 됨 - Case 3) 1원짜리 동전을 하나 사용했다고 가정하고, 같은 동전으로 17원을 추가로 맞추면 됨 Case 1에서 한단계 더 나아가면 이렇게 된다. C..

Rail Fence Cipher - Exercism in Elixir

문제 보기 지그재그 형식으로 문자를 흩트리는 방식의 'Rail Fence Cipher' 암호화를 구현하는 문제였다. 이를테면 'WE ARE DISCOVERED FLEE AT ONCE'를 암호화하면 W . . . E . . . C . . . R . . . L . . . T . . . E . E . R . D . S . O . E . E . F . E . A . O . C . . . A . . . I . . . V . . . D . . . E . . . N . . 와 같이 문자를 배치하고, 이것을 윗줄부터 순서대로 읽어 WECRLTEERDSOEEFEAOCAIVDEN가 되는 식이다. 문자 길이와 배치할 줄 수가 모두 유동적이어서 Stream을 아주 유용하게 사용했다. 암호화, 복호..

Markdown - Exercism in Elixir

문제 보기 마크다운 파서를 리팩토링하는 문제였다. 다른 문제와 다르게 테스트를 모두 통과하는 코드가 먼저 주어지고, 그것을 테스트를 깨트리지 않으면서 최대한 리팩하는 것이 목표. 괄호로 겹겹이 싸인 코드들이 있어서 우선 파이프라인으로 모두 고쳐주고, 단어 단위로 처리하는 부분을 줄 단위로 처리하도록 수정했다. 대충 스무 줄 정도는 줄인 것 같다. 정규식의 Lookahead, lookbehind 기능의 도움을 크게 받았다. defmodule Markdown do @doc """ Parses a given string with Markdown syntax and returns the associated HTML for that string. ## Examples iex> Markdown.parse("This..

OCR Numbers - Exercism in Elixir

문제 보기 7-세그먼트 방식으로 기록된 숫자가 담긴 문자열이 들어왔을 때 이를 숫자로 바꿔 반환하는 문제였다. 한 줄에 여러 숫자가 담기고, 그것이 또 여러 줄 있을 수 있어서(또 행과 열이 맞지 않을 때의 유효성 검사도 해야 해서) 어느 쪽으로 먼저 문자열을 나눠야 할지 시행착오가 많았던 문제였다. Early return이 있으면 참 편했을텐데 하는 생각이 들었다. defmodule OcrNumbers do @doc """ Given a 3 x 4 grid of pipes, underscores, and spaces, determine which number is represented, or whether it is garbled. """ @spec convert([String.t()]) :: {:ok..

List Ops - Exercism in Elixir

문제 보기 엘릭서에서 제공되는 내장 함수들(Kernel의 리스트 연산 함수들, List, Enum 등)을 쓰지 않고 리스트 연산을 구현해보는 문제였다. 리스트 연산을 공부하는 사람들이라면 한번쯤은 짜 봤을 법한 기본적인 내용. 하나하나 구현하다가, 생각해보니 엘릭서의 Enum이 그렇듯 대부분의 것을 reduce(=foldl)로 처리할 수 있음을 깨닫고 그렇게 고쳤다. 기록이 될까 싶어 고치기 전후 버전을 코드에 모두 남겨둔다. do_reverse, do_map 등 호출되지 않는 함수들이 고치기 전의 코드다. defmodule ListOps do # Please don't use any external modules (especially List or Enum) in your # implementa..

Robot Simulator - Exercism in Elixir

문제 보기 주어진 명령어에 따라 로봇을 움직이는 문제였다. 동서남북에 따라 달리 처리해야 하는 부분이 있고, 잘못된 입력에 대해 처리해야 하는 부분이 있어 코드가 자잘하게 길어졌는데, 그것 말고는 별 것이 없기도 하다. 여담이지만 이 문제의 원래 분야는 Multiple clause functions였는데, 동서남북에 따라 함수를 4개씩 만들기에는 조금 투머치인가 싶어 case로 처리했다. defmodule RobotSimulator do @type robot() :: any() @type direction() :: :north | :east | :south | :west @type position() :: {integer(), integer()} defmodule Robot do defstruct [:p..

Knapsack - Exercism in Elixir

문제 보기 각 물건의 무게와 가치가 주어졌을 때, 최대 무게 maximum_weight 안에서 가져갈 수 있는 물건의 최대 가치를 구하는 문제였다. 코딩 테스트 바닥에서 말하는 완전탐색 타입의 문제. 조금 더 최적화할 여지는 있어보이긴 하는데, 파이프라인이 제법 깔끔하게 만들어져서 만족하고 끝내기로 했다. defmodule Knapsack do @doc """ Return the maximum value that a knapsack can carry. """ @spec maximum_value(items :: [%{value: integer, weight: integer}], maximum_weight :: integer) :: integer def maximum_value(items, maximum_w..

Yacht - Exercism in Elixir

문제 보기 일정한 점수 계산 규칙(풀하우스, 스트레이트 등등...)이 있을 때, 주어진 주사위 숫자가 특정 규칙에 들어맞는지, 맞는다면 몇 점인지 계산하는 문제였다. cond로 계산하기에는 조금 양이 많아서 카테고리별로 구현을 나눠 구현했다. 코드가 다소 길 뿐, 어렵지는 않았다. defmodule Yacht do @type category :: :ones | :twos | :threes | :fours | :fives | :sixes | :full_house | :four_of_a_kind | :little_straight | :big_straight | :choice | :yacht @doc """ Calculate the score of 5 dice using the given category&#3..