##はじめに
最近プログラミングElixirの勉強をはじめたので、解答を残していきたいと思います。(おかしなところがあれば言ってください...)
##ListsAndRecursion-0
sum関数はアキュームレータを使わずに実装できる。
iex>MyList.sum [1,2,3]
6
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
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
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
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がマイナスつまり逆回りも対応しました。上のコードと若干変更があります。)
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]
defmodule MyList do
def span(from, to) when from > to, do: []
def span(from, to), do: [from | span(from+1, to)]
end
##さいごに
なんか3番の回答が気に入らない。 -> @torifukukaiouさんの解答に修正させていただきました。