charlists 9

Advent of Code 2022 Day 3 in Elixir - Rucksack Reorganization 풀이

문제 보기 가방에 들어갈 여러 종류의 물건이 있고, 가방이 크게 두 칸으로 나뉘어 있을 때, 한 종류의 물건은 한쪽 칸에만 들어가게 하고 싶단다. 첫 번째 문제는 양쪽 칸에 딱 하나씩 들어간 같은 물건을 찾는 문제, 두 번째 문제는 여러 가방 사이에서 공통적으로 등장하는 물건을 찾는 문제였다. 엘릭서의 MapSet이 이럴 때 정말 유용하다. defmodule Omicron.Day3 do @dir "data/day3/" def q1(file_name \\ "q.txt") do File.read!(@dir file_name) |> String.split("\n") |> Enum.map(fn backpack -> part_size = div(String.length(backpack), 2) [set1, set..

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 / ..

Simple Cipher - Exercism in Elixir

문제 보기 카이사르 암호 식의 기본적인 암호를 구현하는 문제였다. 차이라면 문자 사이가 일정하게 주어지는 것이 아니라 문자마다 거리를 지정할 수 있도록 일종의 암호화 키(key)가 주어진다는 점. 문자 리스트로 바꿔서 편하게 풀 수 있었다. defmodule SimpleCipher do def encode(plaintext, key) do extended_key = extend_key(key, String.length(plaintext)) Enum.zip(String.to_charlist(plaintext), extended_key) |> Enum.map(fn {ch, k} -> encoded = ch + k if encoded > ?z, do: encoded - 26, else: encoded end)..

Atbash Cipher - Exercism in Elixir

문제 보기 영문자를 역순으로 뒤집고, 띄어쓰기를 무시하고 5글자 단위로 나누는 기본적인 암-복호화를 구현하는 문제였다. Enum.map/2 안에 들어간 알파벳을 뒤집는 익명 함수는 별도로 분리해서 암-복호화할 때 공통으로 사용할 수도 있었는데, 대문자나 숫자 처리는 암호화 때에만 쓰는 부분이어서 괜히 공통으로 만들었다가 코드가 어려워질 것 같아 다소 중복을 허용하는 형태로 그대로 두었다. defmodule Atbash do @doc """ Encode a given plaintext to the corresponding ciphertext ## Examples iex> Atbash.encode("completely insecure") "xlnko vgvob rmhvx fiv" """ @spec encod..

Rotational Cipher - Exercism in Elixir

문제 보기 카이사르 암호(영문자를 주어진 거리만큼 밀어서 다른 문자로 변환하는 식으로 암호화하는 방식)를 구현하는 문제였다. 이런 경우에는 문자가 영문자 범위를 넘어가는지 아닌지 확인해야 하므로 문자 리스트로 처리하는 것이 자연스럽다. convert 함수가 약간 중언부언하는 느낌이 있는데 rem을 쓰는 것보다는 코드를 읽기에 이쪽이 조금 더 나은 것 같아 그대로 두었다. defmodule RotationalCipher do @spec rotate(text :: String.t(), shift :: integer) :: String.t() def rotate(text, shift) do text |> String.to_charlist() |> Enum.map(&convert(&1, shift)) |> Li..

RNA Transcription - Exercism in Elixir

문제 보기 문자 리스트의 각 문자를 대응하는 다른 문자로 변형하는 문제였다. 몇 년 전에 엘릭서를 처음 배우면서 풀 때는 문자열과 문자 리스트를 구분하지 못해 뭐 이런 문제가 다 있나 하고 머리를 싸맸던 기억이 있다. 이제는 아무렇지도 않게 풀 수 있어서 그래도 조금은 배우긴 배웠구나 하는 생각이 들었다. defmodule RnaTranscription do @mapping %{ ?G => ?C, ?C => ?G, ?T => ?A, ?A => ?U } @spec to_rna([char]) :: [char] def to_rna(dna) do Enum.map(dna, fn c -> @mapping[c] end) end end

Pangram - Exercism in Elixir

문제 보기 주어진 문장이 '다람쥐 헌 쳇바퀴에 타고파' 류의 팬그램인지 확인하는 문제였다. 역시 구현하는 방법은 여러 가지가 있겠지만, 이번에는 알파벳만을 고유하게 취한 뒤 길이가 26인지를 확인하는 식으로 구현했다. defmodule Pangram do @spec pangram?(String.t()) :: boolean def pangram?(sentence) do sentence |> String.downcase() |> String.graphemes() |> Enum.filter(fn c -> c >= "a" and c Enum.uniq() |> length() |> Kernel.==(26) end end 다 풀고 나서 보니 관련 개념으로 'charlists'가 나와서,..

Nucleotide Count - Exercism in Elixir

문제 보기 DNA 가닥의 각 염기가 각각 몇 개 있는지 세는 문제였다. 이럴 때 쓰라고 만든 듯한 아주 좋은 함수 Enum.frequencies/1이 있어서 편하게 구현할 수 있었다. histogram 함수에서 반환되는 맵에 키가 고정되어 있어야 해서 구조체를 쓸까 하고도 생각했는데, 굳이 구조체를 정의하지 않아도 주어진 키로 맵 기본값을 만들어 두고 맵을 병합하는 것으로 충분할 것 같아 그렇게 작성했다. defmodule NucleotideCount do @nucleotides [?A, ?C, ?G, ?T] @spec count(charlist(), char()) :: non_neg_integer() def count(strand, nucleotide) do strand |> histogram() |>..

German Sysadmin - Exercism in Elixir

문제 보기 문자 리스트(그리고 겸사겸사 case문)를 다루는 문제였다. 문자 리스트 내의 일부 non-latin 문자를 ascii로 바꾸고, 그 외의 문자를 제거하는 문제. 개념은 알고 있고 사실 생각하면 당연한데, 막상 코드를 짜려니 문자 리스트의 각 문자가 리스트가 아니라 정수라는 것이 제법 헷갈린다. 처음에는 flat_map을 썼다가, 나머지 처리에서 c -> [c]로 감싸는 것이 아무래도 마음에 들지 않아 일단 map을 한 뒤에 따로 flatten을 호출하는 쪽으로 정리했다. defmodule Username do def sanitize(username) do username |> Enum.map(fn u -> case u do ?ä -> 'ae' ?ö -> 'oe' ..