作者: Hiroshi Shinohara
日時: 2003/8/05(21:21)
 風つかいです。
 くすのきさん、ども。

>h.avy.rai でひっかかりますが、正しくは heavy(スペース)rai です。ただし、ここまでくれば
>後ろのスペースについては、無視して .(ピリオッド)を、n と判断すれば、heavyスペースrain が
>導けるのではないかなと思います。

 成る程、了解です。

 さて、Iconは順列組合せとかは得意な言語ですので、Iconで順列を生成した例を
ご参考に。 ずいぶん前に作った procedureを使いましたが、動作はハッキリとは、
覚えていません。 いずれの言語でも、ライブラリが揃っていれば、比較的簡単に
作れそうですね。

-----^ PERMTST.ICN ( date:03-08-05 time:20:08 ) ------------<cut here
####################
# 順列組合せプログラムサンプル
####################
# permtst.icn Rev.1.0 2003/08/05 windy 風つかい H.S.
####################
# Usage permtst 文字列
# 引数の文字列(英文字)の順列組合せを出力、最後に組合せ数を出力
# 引数に同一文字が含まれる場合を考慮
# This file is in the public domain.

procedure main(args)
  if *args < 1 then stop("permtst 文字列")  # 引数が無ければ Usage表示
  n := 0                                    # 生成数カウンタ 
  every s := exsperm(args[1]) do {  # 順列組合せ generatorから文字を取り出し
    n +:= 1                                 # カウンタ+1
    write(s)                                # 組合せ文字列出力
  }
  write("組合せ数 ",n)                      # 組合せ数表示
end


# 以下は、Icon入門講座から引用

####################
# 英文字の組み合わせ(同一文字指定対応)
####################
# 名称変更 expermute -> exsperm
# arg  [1]: s  string
# value:       string
# Usage: every ss := exsperm(s) do ...
# Icon入門講座2(18)

procedure exsperm(s)                   # string permutations
  ss := csort(s)                       # 文字列をソートする。(strings.icn)
  if *s = 0 then return ""             # 
  suspend ss[i := new_pos(ss)] || exsperm(ss[1:i] || ss[i+1:0])
             #    ↑同一文字はスキップする
end


####################
# ソートされた文字列 sの左はじから、順に文字位置を出力する generator。
####################
# 手前の文字と同一ならスキップする。
# arg  [1]: s  string
# value:       integer
# Usage: every i := new_pos(s) do ...

procedure new_pos(s)
  ss := ""                     # 手前の文字を記憶しておく変数
  every i := 1 to *s do {
    if ss ~== s[i] then {      # 手前の文字と違っていたら
      ss := s[i]               # 手前文字を更新
      suspend i                # i を返す。
    }
  }
end


# 以下は、BIPL(Icon基本ライブラリー)の strings.icnに含まれる 文字の
# ソート procedure
# exsperm にて使用。 日本語コメントを少し追加。

procedure csort(s)             #: lexically ordered characters
   local c, s1                 # ローカル変数宣言(無くても良い)
   s1 := ""                    # 初期値クリア
   every c := !cset(s) do      # 引数を cset(文字集合)へ変換し順に取り出す。
      every find(c, s) do      # 取り出した文字で、引数文字列を検索し、
         s1 ||:= c             # 見つかる度に、文字を s1に足し込む。
   return s1
end
# csetから !で要素を取り出す時には、アルファベット順に取り出せる。
-----$ PERMTST.ICN ( lines:72 words:238 ) ------------------<cut here

 permtst abca >aaa として、動かしますと、こんな感じです。
-----^ AAA ( date:03-08-05 time:20:09 ) --------------------<cut here
aabc
aacb
abac
abca
acab
acba
baac
baca
bcaa
caab
caba
cbaa
組合せ数 12
-----$ AAA ( lines:13 words:14 ) ---------------------------<cut here

 permtst a.ahviy.r >bbb として、動かしますと、こうなります。
-----^ BBB ( date:03-08-05 time:20:10 ) --------------------<cut here
..aahirvy
..aahiryv
..aahivry
..aahivyr
..aahiyrv
(中略)
yvrih.a.a
yvrih.aa.
yvriha..a
yvriha.a.
yvrihaa..
組合せ数 90720
-----$ BBB ( lines:90721 words:90722 ) ---------------------<cut here

風つかい(hshinoh@...)
IconのWWWは、  http://www.cs.arizona.edu/icon/
UniconのWWWは、http://unicon.sourceforge.net/index.html
BGM: バビロニア・ウィンド / 杉本喜代志