作者: Hiroshi Shinohara
日時: 2003/8/06(07:55)
 風つかいです。

 先日、書いた AWKスクリプトは、くすのきさんの期待なさる動作とは、
違ってしましたが、折角ですので、Icon版も作ってみました。

-----^ CROSS01.ICN ( date:03-08-06 time:07:47 ) ------------<cut here
####################
# クロスワード ヒント辞書検索
####################
# cross01.icn Rev.1.0 2003/08/06 windy 風つかい H.S.
####################
# Usage: cross01 辞書ファイル名 升目文字 文字列長
#        cross01 edict きむたく 6
# This file is in the public domain.

procedure main(args)
  Usage := "cross01 辞書ファイル名 升目文字 文字列長"
  if *args < 3 then stop(Usage) # 引数が少なければ、Usageを表示
  dir := open(args[1]) | stop(args[1]," がありません!") # 辞書ファイルオープン
  s_Masume    := args[2]        # 升目の文字で判っているもの
  n_Moji      := args[3]        # 文字列長

  # set(集合)に、升目文字を格納
  S := set()                           # setを生成
  every insert(S,retrieve(s_Masume,2)) # 升目文字を2バイト単位で切り出し
                                       # Sへ格納
# 辞書ファイル処理
  while line := read(dir) do {         # 辞書ファイルを1行ずつ読み込み
    if *line ~= n_Moji*2 then next     # 単語長チェック(2バイト文字)
    count := *s_Masume /2              # カウンタ(単語数: 2バイト文字)
    every c := !S do {                 # Sの全ての要素に対して、
      line ? if find(c) then {         # lineを走査対象として、cがあるか
                                       # をチェック
               count -:= 1             # カウンタ−1
               if count = 0            # 全べての升目文字を含むならば、
               then write(line)        # 辞書の単語を書き出し
             }
             else next                 # 升目文字がみつからない場合は、次へ
    }
  }
  close(dir)                           # 辞書ファイルクローズ
end


# Icon入門講座より引用

####################
# list/stringの要素を n個区切りにした 部分 list/stringを 順次返す generator
####################
# 元の list/stringは保存
# args  : [1]:list/string [2]:区切り数
# value : sequence of sub-list/sub-string
# Usage : every xx := retrieve(x) do {...}
# Icon入門講座4 ちょっと Icon(4)

procedure retrieve(x,n)
  /n := 1                       # default
  every m := 1 to *x by n do {  # mを 1から n飛びで 順次増加させて
    suspend \x[m+:n]            # xの m番目の要素から n個要素が
                                # 存在すれば それを値として返す。
  }
  suspend x[(*x -n+1) < \m :0]  # n個区切りで、余った要素を返す。
end

# 解説
# *x       : xの size(要素数または長さ)
# /n       : /は nが null(指定が無い時)の check。   存在すればその値を持つ。
# x[m+:n]  : list(または string)の mの位置から n個分の部分。
# \x[m+:n] : \は x[m+:n]が、存在すればという check。存在すればその値を持つ。
#            \mも同様に mの値が存在すれば、その値を持つ。
# suspend  : 複数の値を返す return
# a < b    : 数字比較 a < b が成立すれば、bを値として持つ。
-----$ CROSS01.ICN ( lines:66 words:272 ) ------------------<cut here

風つかい(hshinoh@...)
IconのWWWは、  http://www.cs.arizona.edu/icon/
UniconのWWWは、http://unicon.sourceforge.net/index.html
BGM: なし