000000 ランダム
 ホーム | 日記 | プロフィール 【フォローする】 【ログイン】

ricefish

全5件 (5件中 1-5件目)

1

2007年12月25日
XML
カテゴリ:幾何






最終更新日  2007年12月25日 23時25分37秒


2007年12月24日
カテゴリ:幾何






最終更新日  2007年12月24日 21時45分51秒
2007年09月23日
#!/usr/local/bin/ruby

def help
print <<-HELP_END

 mkwild

      mkwild  [-1] [field1 field2 ...]

オプション
     -1 最初のワイルドカードだけにする
 
説明
    mkwild は、bash のパス名展開の [] とほとんど逆の操作(集約)を行います。
    パス名展開では、例えば
       aa[abc]  -->  aaa aab aac
   という展開が行われますが、mkwild はこれとほとんど逆の操作(集約)
        aaa aab aac  --> aa[abc]
   を行います。

   オプション以外の引数が与えられた場合は、引数1個ずつをレコードとします。
   オプション以外の引数がない場合、標準入力からレコードを取り込みます。
  
   レコードの最初のフィールドとそれに続く区切り記号を除いた部分が全く同じ
   文字列で、最初のフィールドが1文字違いのときに集約が行われます。
   例をあげれば
      aaa  --> aa[ab] --+--> a[ab][ab]
      aab               |
      aba  --> ab[ab] --+
      abb
   となります。(例は最初のフィールドだけ表示しています)
   ホワイトスペースだけのレコードがあれば消去されます。
  
   オプション -1 は、集約を1段階だけ(前述の例で左から2番目のコラムまで)で
   中断します。デフォルトでは、可能なかぎり繰り返します。
  
   入力レコードの順番が、集約結果に影響する場合があります。
   集約結果は、ソートされずに、入力の出現順番に出力されます。
  
   [] の中の文字はソートされません。出現順番です。
   [] の中の文字は重複は残されませんので、入力に全く同じレコードがいくつ
  あっても、1個のときと出力は変わりません。
  
   mkwild の行う集約は、パス名展開の「ほとんど」逆の操作ですが、次の点が
   異なります。
  
    1. bash のパス名展開は、* や ? の展開を行いますが、集約には関係ありません。
       また、パス名展開で使うことのできる、文字クラスや - による文字の範囲での
       指定は、集約には関係ありません。
  
    2. bash のパス名展開は、ファイルが存在する場合だけ展開しますが、
       集約は、ファイルの存在には関係ありません。
       集約された [] の中には、入力に存在するものだけ含んでいます。
       ファイルの存在と関係がないため、ファイル名以外の用途で使う事も可能です。

バグ
   入力レコードの順番が、集約結果に影響する場合がありますが、異なる集約結果を
   得るためには、mkwild の内部動作を考えて、入力を変更するしか方法がありません。
   入力が sort されている場合、集約結果は人間にとって分かりやすい物であると
   思います。

   フィールドの区切り記号は、空白文字(ruby の \\s で [ \\t\\n\\r\\f])です。
   例えば grep は、ファイル名を出力する場合のファイル名とマッチの出力の区切り
   記号は ':' ですが、これと mkwild のフィールド区切り記号の整合が取れていません。

HELP_END
end

opt=Hash.new
ARGV.delete_if {|x| case x
  when "-1" then opt[x]=true
  when "-h","--help"  then help;exit
end}

if ($*.size==0)
  data=$stdin.readlines
else
  data=$*
end

data.uniq!; data.each {|i| i.chomp!}; data.delete_if {|a| a=~/^\s*$/}
   #最初のレコードとそれ以降を切り分けて Arrayにする
data=data.collect {|a| /^\s*([^\s]*)\s*(.*)/.match(a).to_a.values_at(1,2)}
data_size=0;
begin
data=data.inject([]) {|r,aa| a=aa[0]; j=0; wild=nil;
  ri=(0...r.size).find  {|ri|
    if (aa[1]==r[ri][1]) 
      b=r[ri][0]; i=j=0; wild=nil
      until (i>=a.size || j>=b.size)
        if (a[i]==b[j]) ;then i+=1;j+=1
        elsif (wild)    ;then j=b.size+1; wild=nil ##2個以上異なる
        elsif (b[j]!=?[);then wild=[j,"["+b[j].chr+a[i].chr+"]"];i+=1;j+=1 ## make []
        elsif (c=b.index(/\]/,j));then  ## add to []
          wild=[j..c,b[j...c]+(b[j..c].include?(a[i])?"":a[i].chr)+"]"];
          i+=1;j=c+1
        else j=b.size+1  ## [] が対応していない 通常の文字として処理
        end;end ## until
      wild && i==a.size && j==b.size; end}
  if (ri)
    r[ri][0][wild[0]]=wild[1];
  else
    r.push(aa)
  end
  r }
end while (!opt["-1"] && data_size!=(data_size=data.size))
s=data.collect {|a| a[0].size}.max
data.collect {|a| (a[1].size==0)?a[0]:sprintf("%-*s %s",s,a[0],a[1])}.each {|a| (a+"\n").display}

# end of mkwild






最終更新日  2007年09月25日 09時54分07秒
2007年08月29日
カテゴリ:パズル

数独を解くruby スクリプトです。

#!/usr/local/bin/ruby
#
# 数独 を解く
#

def printd(d)
  " +-------+-------+-------+\n".display
  (0...9).each {|i|
  (0...9).each {|j| ((j%3==0)?" | ":" ").display;  ((d[i][j]==0)?"*":d[i][j]).display }
    " |\n".display;
    " +-------+-------+-------+\n".display if (i%3==2) }end

def suudoku1(d)
  s=0;
  begin
    s0=s;
    d.each_index {|i| d[i].each_index {|j| if ((a=d[i][j]).size==1) ## aを候補から消す
      (0...9).each {|k| d[k][j]-=a if (i!=k)}
      (0...9).each {|k| d[i][k]-=a if (j!=k)}
      (i/3*3...i/3*3+3).each {|k| (j/3*3...j/3*3+3).each {|l| d[k][l]-=a if (i!=k && j!=l)}}
    end}}
  end until (s0==(s=d.inject(0) {|s,i| s+=i.inject(0) {|s,j| s+=j.size}}))
  mi=mj=m=10
  d.each_index {|i| d[i].each_index {|j| a=d[i][j].size; mi,mj,m=i,j,a if (a!=1 && a<m) }}
  if (m==0)   ## 解なし
    return []
  elsif (m<10) ## d[mi][mj] の取り得る値を入れて解を求める
    dd=d[mi][mj].collect {|k|
      dd=d.collect {|i| i.collect {|j| j.dup}}  ##copy
      dd[mi][mj]=[k]; dd}
    dd=dd.inject([]) {|dd,d| dd+=suudoku1(d)}
    return dd
  else  ## 解けた
    return [d]
  end
end

def suudoku(d)
  printd(d);
  d.each_index {|i| d[i].each_index {|j|
    if (d[i][j]==0) then  d[i][j]=[1,2,3,4,5,6,7,8,9]; else d[i][j]=[d[i][j]];end}}
  dd=suudoku1(d)
  printf("Number of solutions: %d\n",dd.size);
  dd.each {|d| printd(d); "\n".display}
end

#
#  問題は下記のように Array で記述
#

d=[[1,2,0,0,0,0,7,8,9],
   [0,0,0,7,0,9,1,0,4],
   [7,0,9,1,2,0,0,0,6],

   [2,0,0,0,6,7,0,9,1],
   [0,0,0,0,0,1,2,0,0],
   [0,9,1,2,0,0,5,0,0],

   [0,0,0,6,0,0,0,1,2],
   [0,7,0,0,0,2,0,0,0],
   [9,0,2,0,0,0,0,7,8]]

suudoku(d)








最終更新日  2007年08月29日 22時02分54秒
カテゴリ:雑談
なに書こうかな? 最初のブログです。
自分の忘備録ですけどね。






最終更新日  2007年08月29日 15時02分47秒

全5件 (5件中 1-5件目)

1

PR


Copyright (c) 1997-2020 Rakuten, Inc. All Rights Reserved.