americandog1993の日記

プログラマー歴半年のメモ

もし女 六村リオの緊急事態 Ruby解答

paiza.jp

『もし次の常駐先が女子エンジニアばっかりだったら』をやっていたら『六村リオの緊急事態』(Bクラス相当)で4時間くらいひっかかって(いかにも要領の悪そうな長いコードができあがり、しかも動かない)、答えを探した。
もし女に関しては解答のシェアを認められているようだが、PAIZA問題は解答をネットに書くのは厳禁なので注意。

Rubyで挑戦していたのでRubyの解答を探したが、見つからない。
公式ブログにPythonの解答例があったが、Pythonの文法が全くわからず、解読できなかった。
最終的にこちらのPHP解答を参考にした。

blog.mimsys.net

PHP経験はないが、Pythonと比べるとはるかに推測可能だった。
ほとんどパクリというか、Rubyに書き直しただけだが、以下が無事通過したRuby解答。
このブログを書いた方には本当に感謝しかない。

input_lines = gets.split(' ')
cur_arr = input_lines[0].split('/')
path_arr = input_lines[1].split('/')
for path in path_arr
    if path == '..'
        cur_arr.pop
    elsif path == '.'
        #何もしない
    else
        cur_arr.push(path)
    end
end
cur_arr.delete('') #'//'を防ぐ
puts '/' + cur_arr.join('/')

敗因はArray.popメソッドを知らなかったことだろう。
これを知るまで拡張Forで全部取り出して最後だけ削除してまた結合し直すとか意味不明なことをやってしまっていた。
ところで、

cur_arr.delete('') #'//'を防ぐ
puts '/' + cur_arr.join('/')

この最後の2行だが、例えば /home/current という入力値を .split してまた .join でくっつけるような単純な処理で考えると、まず、"/"で区切って "", "home", "current" となる。
1行目はこの頭の "" を消すための.deleteメソッドだ。
このまま .join すると home/current となってしまうので2行目の頭で "/" を加えている。
それなら最初からこう書けばいいのではないかと思える。

puts cur_arr.join('/') #=>/home/current

配列先頭の "" を残すことで、何もしなくても先頭に "/" が挿入される。
これは間違いなく正解である。少なくとも例に出したような入力値の場合は。
しかし、自動採点時に5パターンほど値が入力されるのだが、その中に "/ .." という意地悪な入力がある。
後者の書き方だと、この時に "" を出力してしまい不正解となる(正解は"/")。
先のPHP解答の記事を読んでも、この場合の処理にやや苦心された様子が伺える。