Elixir | 99-Haskell Problems 問題 1 – 10 解答例

関数型プログラミングの練習問題として 99 Haskel Problems というのがあります。

この記事では、Elixir を用いて問題の解答例を紹介します。

Problem 1

問題

Find the last element of a list.

リストの末尾要素を見つけよ。

iex> Prob01.my_last([1, 2, 3, 4])
4
iex> Prob01.my_string_last("elixir")
"r"
解答例
defmodule Prob01 do
  def my_last([]), do: nil
  def my_last([x]), do: x
  def my_last([_ | tail]), do: my_last(tail)
  
  def my_string_last(string), do: string |> String.graphemes() |> my_last()
end
標準ライブラリでの実行例
iex> List.last([1, 2, 3, 4])
4
iex> String.last("elixir")
"r"

Problem 2

問題

Find the last-but-one (or second-last) element of a list.

リストの末尾からひとつ手前の要素を見つけよ。

iex> Prob02.my_but_last([1, 2, 3, 4])
3
iex> Prob02.my_string_but_last("elixir")
"i"
解答例1
defmodule Prob02 do
  def my_but_last([]), do: nil
  def my_but_last([_]), do: nil
  def my_but_last([x, _]), do: x
  def my_but_last([_ | tail]), do: my_but_last(tail)
  
  def my_string_but_last(string), do: string |> String.graphemes() |> my_but_last()
end
解答例2
defmodule Prob02 do
  def my_but_last(list), do: list |> Enum.drop(-1) |> List.last()
  
  def my_string_but_last(string), do: string |> String.graphemes() |> my_but_last()
end

Problem 3

問題

Find the K’th element of a list.

リストの K番目の要素を見つけよ。

iex> Prob03.my_at([1, 2, 3, 4], 2)
3
iex> Prob03.my_string_at("elixir", 3)
"x"
解答例
defmodule Prob03 do
  def my_at([], _), do: nil
  def my_at([head | _], 0), do: head
  def my_at([_ | tail], n), do: my_at(tail, n - 1)

  def my_string_at(string, n), do: string |> String.graphemes() |> my_at(n)
end
標準ライブラリでの実行例
iex> Enum.at([1, 2, 3], 1)
2
iex> String.at("elixir", 3)
"x"

Problem 4

問題

Find the number of elements in a list.

リストの要素数を求めよ。

iex> Prob04.my_length([1, 2, 3, 4])
4
iex> Prob04.my_string_length("elixir")
6
解答例
defmodule Prob04 do
  def my_length([]), do: 0
  def my_length([_ | tail]), do: 1 + length(tail)
  
  def my_string_length(string), do: string |> String.graphemes() |> my_length()
end
標準ライブラリでの実行例
iex> length([1, 2, 3, 4])
4
iex> String.length("elixir")
6

Problem 5

問題

Reverse a list.

リストを反転せよ。

iex> Prob05.my_reverse([1, 2, 3, 4])
[4, 3, 2, 1]
iex> Prob05.my_string_reverse("A man, a plan, a canal, panama!")
"!amanap ,lanac a ,nalp a ,nam A"
解答例
defmodule Prob05 do
  def my_reverse(list), do: List.foldl(list, [], fn x, acc -> [x | acc] end)

  def my_string_reverse(string) do
    string |> String.graphemes() |> my_reverse() |> List.to_string()
  end
end
標準ライブラリでの実行例
iex> Enum.reverse([1, 2, 3, 4])
[4, 3, 2, 1]
iex> String.reverse("A man, a plan, a canal, panama!")
"!amanap ,lanac a ,nalp a ,nam A"

Problem 6

問題

Find out whether a list is a palindrome.

リストが回文構造になっているかどうか判別せよ。

iex> Prob06.is_palindrome([1, 2, 3])
false
iex> Prob06.is_palindrome([1, 2, 4, 8, 16, 8, 4, 2, 1])
true
解答例
defmodule Prob06 do
  def is_palindrome(list), do: list == Enum.reverse(list)
end

Problem 7

問題

Flatten a nested list structure.

ネスト構造のリストをフラットにせよ。

iex> Prob07.my_flatten([1, [2, [3, 4], 5]])
[1, 2, 3, 4, 5]
解答例
defmodule Prob07 do
  def my_flatten([]), do: []

  def my_flatten([head | tail]) do
    cond do
      is_list(head) -> my_flatten(head) ++ my_flatten(tail)
      true -> [head | my_flatten(tail)]
    end
  end
end
標準ライブラリでの実行例
iex> List.flatten([1, [2, [3, 4], 5]])
[1, 2, 3, 4, 5]

Problem 8

問題

Eliminate consecutive duplicates of list elements.

リストから連続した重複要素を除去せよ。

iex> Prob08.compress("aaaabccaadeeee")
"abcade"
解答例
defmodule Prob08 do
  def compress(string) do
    string
    |> String.graphemes()
    |> Enum.chunk_by(&Function.identity/1)
    |> Enum.map(&List.first/1)
    |> List.to_string()
  end
end

Problem 9

問題

Pack consecutive duplicates of list elements into sublists.

リストから連続した重複要素をサブリストとしてまとめよ。

iex> Prob09.pack("aaaabccaadeeee")
"abcade"
解答例
defmodule Prob09 do
  def pack(string) do
    string
    |> String.graphemes()
    |> Enum.chunk_by(&Function.identity/1)
    |> Enum.map(&List.to_string/1)
  end
end

Problem 10

問題

Run-length encoding of a list.

リストに対してランレングス圧縮を施せ。

iex> Prob10.encode("aaaabccaadeeee")
[{4, "a"}, {1, "b"}, {2, "c"}, {2, "a"}, {1, "d"}, {4, "e"}]
解答例
defmodule Prob10 do
  def encode(string) do
    string
    |> String.graphemes()
    |> Enum.chunk_by(&Function.identity/1)
    |> Enum.map(fn x -> {length(x), List.first(x)} end)
  end
end
  • URLをコピーしました!
  • URLをコピーしました!

コメント

コメントする

目次