2009-06-30[n年前へ]
■有限要素法を理解するには、プログラムリストが最も適切な表現手段である 
20年前に出版された(今ではミステリ作家として有名な)森博嗣の「C言語による有限要素法入門
」から。(ちなみに森博嗣
には「C言語によるマトリックス演算
」という著書もある)
本書は、有限要素法をC言語で実行することはもちろんだが、むしろ、C言語によって有限要素法を理解する目的に適している。有限要素法を理解するには、プログラムリストが最も適切な表現手段であるからであり、C言語のリストは、目に優しい端正なコーディングが可能である。
1989年1月 森博嗣
2009-08-05[n年前へ]
■速くなった「IronRuby 0.9」で開発が変わる? 
本格的なコーディングを開始する前にかんたんなプロトタイプを作成する、という開発者は少なくないはず。プロトタイプよりも前の段階、単なる発想が動作するかどうか試すことが目的の場合は、なおさらのこと余分なコーディングは避けたいところ。
2010-04-20[n年前へ]
■正規表現と「美しいコード」 
しばらく前のことだったと思う。正規表現の書き方の話題になり、「美しいコード」とか「目的に対する実装のバランス」といった話になった。
その時、「コンパイル(NFA->DFA)にどの程度の時間がかかるか」という観点からのアドバイスを受けた。これまで、そういった基本的なことを考えたこともなかったので、今さらながら、そのアドバイスを消化するために、正規表現とNFA・DFAについて、さらってみた。
DFA:Deterministic Finite Automaton=決定性有限オートマトン、やら、NFA:Nondeterministic Finite Automaton=非決定性オートマトンといった文字列を眺めながら、こんなワクワクさせられる面白いことを、なぜ今まで楽しむことができなかったのだろうと、そんなことを切実に感じさせられた。
なお、オートマトンの日本語訳は、自動機械であって、自動羊肉ではないらしい。ところで、あなたの「マトン」のイメージは、どんなものでしょう?
2010-04-25[n年前へ]
■Ruby で書いた計算プログラムの実行速度 
「入門レベルの問題ですが」と前置きをされた上で、プログラミングの「問題」を出された。「5分間でコーディングして下さい。あと、プログラムの実行時間が2秒を超えるなら誤答です」と言う、厳しいオマケの言葉付きで、そんなお題を出された。
とりあえず、頭を雑巾のように振りしぼり、単純そうな解法のRubyコードを書いてみた。…しかし、2秒で計算を終えることはどうしてもできそうにない。少なくとも、その100倍以上の計算時間がかかる。
「これは見当違いの解法アルゴリズムだったか…」と思いながら、出題者におそるおそる提出してみると、「アルゴリズムは合っている」という。とりあえず、「解法を思いつかない」という最悪の自体は避けられたが、それにしても、もう少し高速化して提出したかった。
Rubyで書いたのは、こんなコードだ。このRubyコードを高速化しようと思うなら、どのようにすれば計算時間を短くすることができるだろうか。また、同じ解法を他言語で実装した場合、Rubyコードとどのくらい計算速度が違ってくるものなのだろうか。
def makeRect(n)
data=[]
n.times{ data<<[rand(),rand(),rand(),rand()] }
return data
end
def makeMesh(rects)
xg=[]
yg=[]
rects.each do |xt,xb,yt,yb|
xg<<xt<<xb
yg<<yt<<xb
end
xg.sort!
yg.sort!
mesh=[]
(xg.length-1).times do |x|
(yg.length-1).times do |y|
cx=(xg[x]+xg[x+1])/2
cy=(yg[y]+yg[y+1])/2
area=(xg[x+1]-xg[x])*(yg[y+1]-yg[y])
mesh<<[cx,cy,area] if area>0
end
end
return mesh
end
rects=makeRect(1000)
mesh=makeMesh(rects)
area=0
mesh.each do |x,y,a|
rects.each do |xt,xb,yt,yb|
if xt<x&&x<xb&&yt<y&&y<yb
area+=a
break
end
end
end
puts area
「お題」を書け、と言われそうですが、どこぞのプログラミング・コンテストで出題されるかもしれないということもあり、「お題」自体は書かないでおきます。また、「お題」がわかりづらいように、コメントを削除してあります(といっても関数名・変数名から、ある程度は想像できそうにも思いますが)。というわけで、回答コードをもとに、「お題」の内容を逆に想像してみると、そしてより良い解法を考えてみたりするのも、面白いかもしれません。ちなみに、上記コードで、makeRect(1000) としている部分は、問題が訂正され、数百程度になりそう、ですね。
2010-12-02[n年前へ]
■数学(コーディング)パズル、大好き!? 
ここのところ、数学パズル||コーディング・パズルにハマっています。きっかけは、国際情報オリンピック(International Olympiad in Informatics)の予選問題にもなったことがあるという「入門レベルの問題」で、「200個以内の長方形の上左および右下座標(32bit floatで表現できるような実数)が与えられる。長方形は相互に重なりが許されるとき、与えられた長方形群により覆われた部分の面積を求めるコードを書け。今すぐ書け。あっ、実行時間が2秒を越えるようなコードはダメだかんね」というお題でした。
あなたなら、このお題に対して、どんなコードを書くでしょう?VisualBasicでも、Perlでも、C++でも、Lispでも・・・、自分の言葉で問題を書き綴り・解き明かす「数学(コーディング)パズル」はっても楽しくスリリングなことなのだろう、と思います。きっと、それは固くなりがちな頭を柔らかくし、何らかの瞬発力を与えてくれるものであるような気がします。
ちなみに、そのお題を与えられたとき、適当にRubyで書いたコードが下のものになります。あなたなら、どんなコードを書きますか?
def makeRect(n)
data=[]
n.times{ data<<[rand(),rand(),rand(),rand()] }
return data
end
def makeMesh(rects)
xg=[]
yg=[]
rects.each do |xt,xb,yt,yb|
xg<<xt<<xb
yg<<yt<<xb
end
xg.sort!
yg.sort!
mesh=[]
(xg.length-1).times do |x|
(yg.length-1).times do |y|
cx=(xg[x]+xg[x+1])/2
cy=(yg[y]+yg[y+1])/2
area=(xg[x+1]-xg[x])*(yg[y+1]-yg[y])
mesh<<[cx,cy,area] if area>0
end
end
return mesh
end
rects=makeRect(200)
mesh=makeMesh(rects)
area=0
mesh.each do |x,y,a|
rects.each do |xt,xb,yt,yb|
if xt<x&&x<xb&&yt<y&&y<yb
area+=a
break
end
end
end
puts area