スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

[Ruby]数字の桁を漢字で表示するモジュールを作ったよ

最近アルゴリズムの本を勉強しつつブログに書いたりしているのですが、そのとき出力した結果がものすごい桁数の数字であることがあります。

まあ、こうやってブログに貼り付ける分にはそのままでもいいのですが、人に口頭で数字を伝えるときにいちいち桁を数えて読み上げるのは非常にめんどくさい。

そこで、FixnumとBignumを拡張するモジュール組んで読み込ませることで、整数を読み上げやすい形式に変換するプログラムを組んでみました。俺得。

# encoding: cp932
module Toj
  def to_j
    number = self
    digit = ["万", "億", "兆", "京", "垓", "禾予", "穣", "溝", "澗", "正",
             "載", "極", "恒河沙", "阿僧祇", "那由他", "不可思議", "無量大数"]
    ketasu = digit.size
    shuturyoku = Array.new
    ketasu.times do |i|
      numbers_stack = Array.new
      4.times do |j|
        stack = number - number / 10 * 10
        numbers_stack.unshift("#{stack}")
        number = number / 10
      end
      shuturyoku.unshift(numbers_stack.join.to_i.to_s)
      if number > 0
        shuturyoku.unshift(digit[i])
      else
        break
      end
    end
    puts shuturyoku.join
  end
end

class Fixnum
  include Toj
end

class Bignum
  include Toj
end

number = 95849480083929012345
number.to_j #=>9584京9480兆839億2901万2345

(自分だけかもしれないけど)便利!

テーマ : プログラミング - ジャンル : コンピュータ

[ゲーム]ネットで手に入るゲーム製作(AI)に関する資料

ゲームAIについて


マッチ箱の脳
ゼビウスセミナー
y_miyakeのゲームAI千夜一夜
[GDC 2009#02]「ゲームAI」とは何か? AIプログラマーのギルドがセミナーを開催
ゲームAI連続セミナー「ゲームAIを読み解く」全講演資料(2009年11月改訂版)

Twitter上でのAI議論


Togetter - まとめ「ゲームAIラウンドテーブル・オン・ツイッター(2010年4月期)」
Togetter - まとめ「ゲームAIラウンドテーブル・オン・ツイッター第2回-前半-(2010年5月期)」
Togetter - まとめ「ゲームAIラウンドテーブル・オン・ツイッター第2回-後半-(2010年5月期)」

オセロ


リバーシプログラムの作り方 サンプル
-鶯教-コンピュータ・リバーシ講座
オセロプログラムの作り方

アルゴリズム


A*探索アルゴリズムにチャレンジ - mirichiの日記
経路探索アルゴリズムA* - gan2 の Ruby 勉強日記
経路探索アルゴリズムA*をRubyで実装してみた - gan2 の Ruby 勉強日記
Rubyで最短経路を探索しよう! - hp12c
e
Rubyでローグライクダンジョン生成 - アーユルベーダはインドのエステみたいなもん
【DiGRA公開講座】モンテカルロ木探索とは何か?|遠藤雅伸公式blog「ゲームの神様」
ダイクストラ法(最短経路問題)
経路探索アルゴリズムの「ダイクストラ法」と「A*」をビジュアライズしてみた - てっく煮ブログ
2010-03-13 - らいおんの隠れ家:遺伝的アルゴリズム
脳とベイジアンネット

学会など


日本デジタルゲーム学会
国際ゲーム開発者協会日本(IGDA日本)
Serious Games Japan
CEDEC 2010 | CESA Developers Conference


用語集


ゲーム批評用語小辞典

ゲームデザイン


ゲームデザインの理論
げーむ ぷれいあびりてぃー(↑の人が書いてるブログ)
Well Played 1.0
ゲーム作者の集い[ゲームヘル2000]レベルデザイン
なぜ、人はゲームにハマルのか?
第一回
第二回
第三回


大学とゲーム


ゲームとアカデミーの素敵なカンケイ
第一回
第二回(ゲームAIについての記事です.参考文献表あり)
第三回


フリーで遊べる著作権的に完全アウトなゲームたち


パックマン
ゼビウス
ギャラガ
マリオ


ゲームプログラミングについて


言語別ゲームプログラミング制作講座一覧
ジャンル別ゲームの作り方とアルゴリズムまとめ
TNKソフトウェア - クラスまみれのゲームプログラミング入門
リバーシプログラムの作り方 サンプル
O-Planning ゲーム制作のちょっといい話: ゲームエンジン・目次
O-Planning ゲーム制作のちょっといい話: SIG-Glocalizationの記事まとめ


ゲームプランナー編


ゲーム企画書の書き方:新卒篇
企画書の書き方

ゲーム研究


ゲーム研究の方法と意義についての序説(伊藤憲二)
Spore におけるゲームAI技術とプロシージャル
同人ゲームの全体像(改訂版)
ゲーム情報学から見たコンピュータ囲碁
モンテカルロ木探索 理論編
モンテカルロ木探索 実践編
これからのゲームAIの作り方
ゲーム作りの文化のために―独立系デベロップメントシーンの比較試論―
サッカーシミュレーションのAI、サッカーゲームのAI1
サッカーシミュレーションのAI、サッカーゲームのAI2
ゲーム産業における職業とキャリア ヒット数
70年代・80年代のゲーム開発環境について
80年代・90年代のゲーム開発環境について
2000年代・現在の環境とHSP、プログラミング教育について
テキスト解析による日米ゲームレビューの比較

番外編


http://togetter.com/li/831

最終更新日 2009/12/04

テーマ : ゲーム - ジャンル : ゲーム

[Ruby][アルゴリズム入門]補間

第二章「数値計算」 目次

総合目次

2-1 乱数
2-2 数値積分
2-3 テイラー展開
2-4 非線形方程式の解法
2-5 補間
2-6 多桁計算
2-7 長いπ
2-8 連立方程式の解法
2-9 線形計画法
2-10 最小2乗法

ラグランジュ補間

何組かのx, yデータが与えられているとき、これらの点を通る補間多項式をラグランジュ補間により求め、データ点以外の点を求める。

(x0, y0), (x1, y1), …, (xn-1, yn-1)というn個の点が与えられたとき、これらの点を全て通る関数f(x)は次のように求められる。
ラグランジュ補間のf(x)を求める式
def lagrange(x, y, n, t)
  s = 0.0
  n.times do |i|
    p = y[i]
    n.times do |j|
      p = p * (t - x[j]) / (x[i] - x[j]) unless i == j
    end
    s = s + p
  end
  return s
end

x = [0.0, 1.0, 3.0, 6.0, 7.0]
y = [0.8, 3.1, 4.5, 3.9, 2.8]

puts "      x       y"
(0.0).step(7.0, 0.5) do |t|
  printf "%7.2f%7.2f\n"%[t, lagrange(x, y, 5, t)]
end


ニュートン補間

何組かのx, yデータが与えられているとき、これらの点を通る補間多項式をニュートン補間により求め、データ点以外の点を求める。

ニュートンの補間公式
fj(x)を,fj(xi)=yi,i=0,・・・,j
を満たす高々j次の多項式とすると,
fj+1(xi)=yi,i=0,・・・,j,j+1
を満たす高々j+1次の多項式fj+1(xi)は適当な定数cj+1に対して次の式で与えられる。

fj+1(x)=fj(x)+cj+1(x-x0)(x-x1)・・・(x-xj)

ニュートンの補間公式
def newton(x, y, n, t)
  flag = true
  a = Array.new(100) # 係数配列
  w = Array.new(100) # 作業用
  if flag
    n.times do |i|
      w[i] = y[i]
      (i - 1).downto(0) do |j|
        w[j] = (w[j + 1] - w[j]) / (x[i] - x[j])
      end
      a[i] = w[0]
    end
    flag = false
  end
  s = a[n - 1]
  (n - 2).downto(0) do |i|
    s = s * (t - x[i]) + a[i]
  end
  return s
end

x = [0.0, 1.0, 3.0, 6.0, 7.0]
y = [0.8, 3.1, 4.5, 3.9, 2.8]

puts "      x       y"
(0.0).step(7.0, 0.5) do |t|
  printf "%7.2f%7.2f\n"%[t, newton(x, y, 5, t)]
end

テーマ : プログラミング - ジャンル : コンピュータ

[Ruby][アルゴリズム入門]非線形方程式の解法

第二章「数値計算」 目次

総合目次

2-1 乱数
2-2 数値積分
2-3 テイラー展開
2-4 非線形方程式の解法
2-5 補間
2-6 多桁計算
2-7 長いπ
2-8 連立方程式の解法
2-9 線形計画法
2-10 最小2乗法

2分法

方程式f(x)=0の根を二分法により求める。

1次方程式(グラフ上で直線)以外の方程式を非線形方程式と呼ぶ。このような方程式の根(f(x)^2が最小値(=0)になるxの値)を求める方法に二分法がある。
1:根の左右にある2点a,bをlowとhighの初期値とする。
2:lowとhighの中間点xをx=(low + high) / 2で求める。
3:f(x) > 0なら根はxより左にあるからhigh = xとし、上限を半分に狭める。f(x) < 0なら根はxより右にあるからlow = xとし、下限を半分に狭める。
4:f(x)が0か|high - low| / |low| < EPSになったときのxの値を求める根とし、そうでないなら2以後を繰り返す。EPSは収束判定値で、適当な精度を選ぶ。
# encoding: cp932
def f(x)
  return x * x * x - x + 1
end

EPS = 1e-08  # 打ち切り誤差
LIMIT = 50   # 打ち切り回数

low = -2.0
high = 2.0

1.upto(LIMIT) do |k|
  x = (low + high) / 2
  if f(x) > 0
    high = x
  else
    low = x
  end

  if f(x) == 0 or (high - low).abs < low.abs * EPS
    puts "x = #{x}"
    break
  end
  if k == LIMIT
    puts "この試行回数、または誤差設定では収束しない"
  end
end


ニュートン法

方程式f(x)=0の根をニュートン法により求める。

1:根の近くの適当な値x0を初期値とする。
2:y = f(x)のx = x0における接戦を引き、x軸と交わったところをx1とし、以下同様の手順でx2, x3, …, xn-1, xnと求めて行く。
3:ニュートン法の収束判定になったときのxnの値を求める根とし、そうでないなら2以降を繰り返す。EPSは収束判定値で、適当な精度を選ぶ。

xnは、
ニュートン法のxnを求める式
と前の値xn-1を用いて求めることができる。ニュートン法の方が2分法より収束が早い。
# encoding: cp932
def f(x)
  return x * x * x - x + 1
end

def g(x)
  return 3 * x * x - 1
end

EPS = 1e-08  # 打ち切り誤差
LIMIT = 50   # 打ち切り回数

x = -2.0

1.upto(LIMIT) do |k|
  dx = x
  x = x - f(x) / g(x)
  if (x - dx).abs < dx.abs * EPS
    puts "x = #{x}"
    break
  end
  if k == LIMIT
    puts "この試行回数、または誤差設定では収束しない"
  end
end

テーマ : プログラミング - ジャンル : コンピュータ

[Ruby][アルゴリズム入門]テイラー展開

第二章「数値計算」 目次

総合目次

2-1 乱数
2-2 数値積分
2-3 テイラー展開
2-4 非線形方程式の解法
2-5 補間
2-6 多桁計算
2-7 長いπ
2-8 連立方程式の解法
2-9 線形計画法
2-10 最小2乗法

e^x

e^xをテイラー展開を用いて計算する。

# encoding: cp932
def myexp(x)
  eps = 1e-08;
  s = 1.0
  e = 1.0
  d = 1.0
  1.upto(200) do |i|
    d = s
    e = e * x / i
    s += e
    return s if (s - d).abs < eps * d.abs
  end
  return 0.0
end

puts "    x       myexp(x)        exp(x)"
0.step(40, 10) do |x|
  printf "%5.1f%14.6g%14.6g\n"%[x, myexp(x), Math.exp(x)]
end


負の値版e^x

e^xのxが負の場合にも対応できるようにする。

# encoding: cp932
def myexp(x)
  eps = 1e-08;
  s = 1.0
  e = 1.0
  d = 1.0
  a = x.abs # xの絶対値を取り、計算にはこれを使う
  1.upto(200) do |i|
    d = s
    e = e * a / i
    s += e
    if (s - d).abs < eps * d.abs
      # 元のxの値が0以上ならそのまま、0以下なら1/sを返す。
      if x > 0
        return s
      else
        return 1.0 / s
      end
    end
  end
  return 0.0
end

puts "    x       myexp(x)        exp(x)"
-40.step(40, 10) do |x|
  printf "%5.1f%14.6g%14.6g\n"%[x, myexp(x), Math.exp(x)]
end


cos x

cos xをテイラー展開により求める

# encoding: cp932
def mycos(x)
  eps = 1e-08
  s = e = d = 1.0
  # xの値を0~2πに収める
  x = x % (2 * 3.14159265358979)
  k = 1
  1.step(200, 2) do |k|
    d = s
    e = -e * x * x / (k * (k + 1))
    s += e
    return s if (s - d).abs < eps * d.abs
  end
  return 9999.0
end

rd = 3.14159 / 180
puts "    x       mycos(x)        cos(x)"
x = 0
0.step(180, 10) do |x|
  printf "%5.1f%14.6g%14.6g\n"%[x, mycos(x * rd), Math.cos(x * rd)]
  x += 10
end

テーマ : プログラミング - ジャンル : コンピュータ

上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。