文字列を先頭から見て同じところまで除去
ちょっと時間が開いてしまったけど、id:fumokmm さんが出題しているお題をこなしていくよ!
今回のお題はこちら↓
お題:文字列を先頭から見て同じところまで除去
http://d.hatena.ne.jp/fumokmm/20110812/1313138407
複数の文字列を受け取り、受け取った文字列をそれぞれ先頭から見てゆき、すべてが同じ内容であれば除去した内容の文字列を返却する関数を書いて下さい。 ※関数の引数と戻り値については複数の文字列が受け渡しできれば型や方法は問いません*1。 例1)hoge("abcdef", "abc123") 戻り値 => "def" と "123" ("abc" が除去される) 例2)hoge("あいうえお", "あいさんさん", "あいどる") 戻り値 => "うえお", "さんさん", "どる" ("あい" が除去される) 例3)hoge("12345", "67890", "12abc") 戻り値 => "12345", "67890", "12abc" (一致なしのため、そのまま返却される)
最新の回答↓
↑がでるまでの経緯
とりあえず問いてみた。
(出題直後に問いてたんだけど、仕様を間違えて一旦置いといたのは秘密)
List method(String... strs) { def f = { list -> if (list.contains("") || list.collect{it[0]}.unique().size() != 1) { return list } else { return call(list.collect{it.substring(1)}) } } f(strs as List) } assert method("abcdef", "abc123") == ["def", "123" ] assert method("あいうえお", "あいさんさん", "あいどる") == ["うえお", "さんさん", "どる" ] assert method("12345", "67890", "12abc") == ["12345", "67890", "12abc"] // 追加したテスト assert method("12345", "12", "12abc") == ["345", "", "abc"]
かなり冗長。
というか、無理やり感に溢れてるw
メソッドを呼び出してるのに中でクロージャー作ってる辺りとか。。。
(でもListにしないと色んなメソッド使えない。。。)
returnが2つもある所とか。。。
後、問題の例にはなかったですが全て除去される文字の場合も対処してます。
(list.contains("")の所)
元が元ですが、ワンライナーにしてみる。
def m(String... s){f={(it.contains("")||it.collect{it[0]}.unique().size()-1)?it:call(it.collect{it.substring(1)})};f(s as List)} assert m("abcdef", "abc123") == ["def", "123" ] assert m("あいうえお", "あいさんさん", "あいどる") == ["うえお", "さんさん", "どる" ] assert m("12345", "67890", "12abc") == ["12345", "67890", "12abc"] assert m("12345", "12", "12abc") == ["345", "", "abc"]
あれ?なんかそれっぽく見えるw
一応条件を「!=1」じゃなくて「-1」にして1バイト削ったり努力は認めて欲しい。
(0の場合はfalseと判断される)
さぁて、他の人の答え見てこよー♪
追記(2011/08/20 0:47)
色々な人の回答を見て気づく。
ループ使えよループwww
最初forを使ってた気がするんだけどなんでこうなったんだろうw
という事で修正したのが冒頭のコード。
かなりわかりやすく、綺麗になった感じ?
皆様方が使っていた「*.」も使ってみました。(collectと同じ)
が、やはり追加したテストの部分がネックで長くなってしまう。。。
明日、もう一回改良してみる予定。
ワンライナーにしてみようとしたけど、returnが途中に入ってるからかうまくできず。
こちらも明日やってみます。
追記(2011/08/20 11:52)
id:fumokmm さんのコードに載ってたテスト流したら、空文字入ってると例外発生。
後で修正!
というか、fumokmmさんのコードやっぱり凄いなぁ。。。