11738


0〜9やa〜zの配列の要素から3個を選んだときの重複順列を数え上げたければ、

[code]

    p ('000'..'999').to_a
    p ('aaa'..'zzz').to_a
    
[/code]

ですみます。  
平仮名で同様のことをしようと

[code]

    # -*- coding: cp932 -*-
    p ('あああ'..'んんん').to_a
    
[/code]

とするとパソコンが止まりました。（ **上記コードは実行しないでください。** ）  
なぜ上手くいかないか知ろうと、

[code]

    # -*- coding: cp932 -*-
    p ('ああ'..'んん').to_a
    
[/code]

を実行すると、  
重複順列に「あ〜ん以外の別の文字が混ざっている」ことがわかりました。  
なぜ、「あ〜ん以外の別の文字が混ざる」か教えてください。


CC BY-SA 3.0
2015-06-25T14:07:30.947
11731
2015-06-25T17:21:33.980
5363
question
ruby
平仮名の重複順列が上手く出力されないのはなぜか？


調べてみました。

`('ああ'..'んん').to_a` では [Range#each](http://docs.ruby-
lang.org/ja/2.1.0/method/Range/i/each.html) が呼ばれるので、2 つめ以降の要素は `String#succ`
で生成されます。

たとえば `'aa'.succ` は `'ab'` に `'az'.succ` は `'ba'` になるので、最初に挙げられた例は期待通り動作します。

ただしこれは、英数字の場合で、[String#succ のドキュメント](http://docs.ruby-
lang.org/ja/2.1.0/method/String/i/succ.html) を見てみると、下記の記述があります。

> アルファベットや数字をまったく含まない場合は、 単純に文字コードを 1 増やします。

このため "あん" の次が "いあ" などにはならず、カタカナや漢字など、文字コード表で "ん" より後にある文字も含むことになります。

期待する結果を得るには、例えば、配列の組み合わせを得る `Array#permutation` を使って次のように書く事ができます。

[code]

    ('ぁ'..'ん').to_a.permutation(3){|chars| p chars.join }
    
[/code]

なお、エンコーディングが UTF-8 だと、`"ん".succ.succ.succ.succ` が `"ぁぁ"`
になり、英数字に似た挙動になりました。ご参考まで。


CC BY-SA 3.0
2015-06-25T16:05:56.237
11738
2015-06-25T17:21:33.980
2015-06-25T17:21:33.980
5789
5789
11731
answer