LoginSignup
4
1

More than 3 years have passed since last update.

プログラミングElixir 第7章 練習問題 解答

Last updated at Posted at 2020-05-29

はじめに

最近プログラミングElixirの勉強をはじめたので、解答を残していきたいと思います。(おかしなところがあれば言ってください...)

ListsAndRecursion-0

sum関数はアキュームレータを使わずに実装できる。
iex>MyList.sum [1,2,3]
6

main.exs
defmodule MyList do
  def sum([]), do: 0
  def sum([head | tail]), do: head + sum(tail)
end

ListsAndRecursion-1

リストと関数を引数に取るmapsum関数を書いてみよう。リストの各要素に関数を適用して、その結果を合計する。
iex>MyList.mapsum [1,2,3], &(&1 * &1)
14

main.exs
defmodule MyList do
  def mapsum([], _func), do: 0
  def mapsum([head | tail], func) do
    func.(head) + mapsum(tail, func)
  end
end

ListsAndRecursion-2

リストの要素の最大値を返すmax(list)関数を書いてみよう
iex>MyList.max [2,4,1,6,5,3]
6

main.exs
defmodule MyList do
  def max(list), do: _max(list, hd(list))
  defp _max([], value), do: value
  defp _max([head | tail], value) when head > value, do: _max(tail, head)
  defp _max([head | tail], value) when head <= value, do: _max(tail, value)
end

ListsAndRecursion-3

Elixirのシングルクオートで囲まれた文字列は、実際は文字コードのリストだ。
リストの各要素にnを足して、足した結果、その文字がzを超えたらaにぐるっと回るようにする、caesar(list,n)関数を書いてみよう。

@torifukukaiouさんのおかげでnが大きくなっても対応できるようになりました。

iex>MyList.caesar('ryvkve', 13)
elixir

main.exs
defmodule MyList do
  def caesar([], _), do: []
  def caesar([head | tail], n), do: [char(head + n) | caesar(tail, n)]
  defp char(n) when ?a <= n and n <= ?z, do: n
  defp char(n), do: ?a + rem(n - ?z, ?z - ?a + 1) - 1
end

#iex> MyList.caesar('ryvkve', 1444444444444443)
#elixir

*2021/02/13 追記(nがマイナスつまり逆回りも対応しました。上のコードと若干変更があります。)

main.exs
defmodule Mylist do
  def ceasar([], _), do: []
  def ceasar([head | tail], n) when n >= 0, do: [_calc(head, n) | ceasar(tail, n)]
  def ceasar([head | tail], n), do: [_calc(head, n) | ceasar(tail, n)]
  defp _calc(h, n) when ?a <= h + n and ?z >= h + n, do: h + n
  defp _calc(h, n) when n < 0, do: ?z + rem(h + n - ?z, 26)
  defp _calc(h, n), do: ?a + rem(h + n - ?z, 26) - 1
end
#iex> MyList.caesar('ryvkve', -1444444444444443)
#elixir

ListsAndRecursion-4

fromからtoまでの数のリストを返す関数MyList.span(from, to)をつくろう。
iex>MyList.span(1, 10)
[1,2,3,4,5,6,7,8,9,10]

main.exs
defmodule MyList do
  def span(from, to) when from > to, do: []
  def span(from, to), do: [from | span(from+1, to)]
end

さいごに

なんか3番の回答が気に入らない。 -> @torifukukaiouさんの解答に修正させていただきました。

4
1
6

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
1