問題内容
関数型言語問題でElixirも対応しているhackerrankの問題を解きます
ここでは2つの長さが同じな文字列を交互に出力するコードを書いていきます
input
(string P, length = N)
(string Q, length = N)
output
PとQの文字列が交互に現れる文字列
sample
# input
abcde
fghij
# output
afbgchdiej
解1(失敗)
方針
- 入力文字列をListにし、その長さを元にループさせて各要素にアクセスして文字列を結合していきます
defmodule StringMingling do
def string_mingling(p, q) do
0..(length(p) - 1)
|> Enum.map(&(Enum.at(p, &1) <> Enum.at(q, &1)))
|> Enum.reduce("", &(&2 <> &1))
|> IO.write
end
end
p = IO.gets("") |> String.trim |> String.codepoints
q = IO.gets("") |> String.trim |> String.codepoints
StringMingling.string_mingling(p, q)
結果
Terminated due to timeout
(時間切れ)
😇😇😇😇😇😇😇😇😇😇😇😇
原因
- Nの範囲が10^5だったのでクソ長いリストにそれぞれアクセスしたのが失敗の原因でした
解2(成功)
方針
- そこでリストの先頭のアクセスが速いってことを思い出したので、先頭以外のリスト再起呼び出しで末尾までループさせて文字列結合していきます
defmodule StringMingling do
def string_mingling([], []), do: ""
def string_mingling([p_hd | p_tl], [q_hd | q_tl]), do: p_hd <> q_hd <> string_mingling(p_tl, q_tl)
def main(p, q), do: string_mingling(p, q) |> IO.puts
end
p = IO.gets("") |> String.trim |> String.codepoints
q = IO.gets("") |> String.trim |> String.codepoints
StringMingling.main(p, q)
結果
†Accepted†
所感
- リストの先頭へのアクセスが速いってことを思い出させられました
- 関数型言語の書き方ってなかなか慣れないと難しいって思いました
- 最終的なコードがふつくしい