お題:文字列を先頭から見て同じところまで除去 - No Programming, No Life
前からちょっとやってみたいなーと思ってたfumokmmさんの「お題」の新しいのが出たのでやってみました。
出題者の土俵であるGroovyでやるあたり、向こう見ずな感じ。
思った以上に苦労した上にGroovyらしさのかけらもない所からスタートしました。だいたいの経緯は gistに上げてます のでそちらを参照くださいませ。
def hoge(String... values) { def i = -1 while (++i < values*.size().min() && values.every {it[i] == values[0][i]}); values.collect { it.substring i } } assert hoge('123', '123') == ['',''] assert hoge('112233', '123123') == ['12233', '23123'] assert hoge('なまむぎ', 'なまごめ', 'なまたまご') == ['むぎ', 'ごめ', 'たまご'] assert hoge('abcde', 'abcdefg') == ['', 'fg'] assert hoge('abcdefg', 'abcde') == ['fg', ''] // 追加したテスト // お題 assert hoge('abcdef', 'abc123') == ['def', '123'] assert hoge("あいうえお", "あいさんさん", "あいどる") == ["うえお", "さんさん", "どる"] assert hoge("12345", "67890", "12abc") == ["12345", "67890", "12abc" ]
- Groovyでも可変長引数はそのまま String... と書ける。
- def... とは書けなかった。
- Object#eachWithIndex も考えたけどうまい使い方が思い浮かばなかった。
- 「異なる文字の出た一番小さい index」見たくできる気はするんだけども。
- なんかいいやり方あると思うんだけど思い浮かばない。
- そんなわけで一度 for で片付けてしまうことにした。
バグってた!
@irof まだGroovyほとんど勉強していないので勘違いだったらすみません。irofさんのコード例で、value[1]とかvalue[2]とかの長さがvalue[0]の長さより短い場合、IndexOutOfBoundsExceptionになりませんか?
2011-08-12 21:38:43 via web to @irof
テスト追加してとりあえず対処。一層不格好になってしまた。
- 最初は第一引数の文字数でループまわしてた(ので指摘の通り例外)。
- とりあえずループカウンタを超えたらbreakするようにOR条件を追加した。
- 気に入らなかったので *. して sort して [0] にした。
その後
def hoge(String... args) {def i = -1;while (++i < args*.size().min() && args.every {it[i] == args[0][i]}){};args.collect {it.substring i}}
- 140文字に収まったよ!(><
- これは冒頭に貼ってるコード。今のとこコレかなー…。
色々やってみたログ
- Groovyでは文字列の引き算ができる。
- assert 'abcde' - 'abc' == 'de'
- これは minus メソッド
- つまり *.minus とすれば全部から引ける
- 「先頭から連続して一致する文字列」がわかればそれを引けば良い
def hoge(String... args) { def i = -1, v = '' while(++i < args*.size().min() && args.every{it[i] == args[0][i]}) { v += args[0][i] } args*.minus(v) }
- 良い案だと思ったのに文字数増えた……
- ゴルフじゃないんだから。
- ひっくり返してみた。
- 引いたときに全部の引数が変わるものって感じ
def hoge(String... args) { for (int i = args*.size().min() - 1; i >= 0; i--) { def v = args[0][0..i] if (args.every { it != it - v }) return args*.minus(v) } args }
- なんかGroovyっぽさが減った気がする…