改め Objective Technician

はぐれ技術者のやりたい放題

SQLで素数サーチ

2010-09-10 00:44:31 | プログラミング
「割り切る数が存在しない」ことをEXISTS述語で表現する


自然数を,順序のない単なる数の集合として扱うところがいかにもSQLらしい.

import sqlite3

db = sqlite3.connect(":memory:");
c = db.cursor();

c.execute("CREATE TABLE Digits(n)");
c.executemany("INSERT INTO Digits VALUES(?)", [
    (0,), (1,), (2,), (3,), (4,), (5,), (6,), (7,), (8,), (9,),
]);

numbers = "SELECT D1.n + 10 * D2.n AS n \
             FROM Digits D1 CROSS JOIN Digits D2";
c.execute("CREATE VIEW Numbers AS " + numbers);

divisor = "(SELECT * \
              FROM Numbers Divisor \
             WHERE Divisor.n <= Dividend.n / 2 \
AND Divisor.n != 1 \ AND Dividend.n % Divisor.n = 0)"; primeNumber = "SELECT n AS primeNumber \ FROM Numbers Dividend \ WHERE n > 1 \ AND NOT EXISTS " + divisor; c.execute(primeNumber + "order by primeNumber"); for row in c: print(row); c.close(); db.close();















Python だと1行で書けるけどな!
print([p for p in range(2, 100) if [1 for d in range(2, 1 + p // 2) if p % d == 0] == []]);

自己非等価結合2

2010-09-02 19:20:14 | プログラミング
自分メモ.




メディアンを求めるSQL.




母集合を上位と下位の2つの部分集合に分けて,その共通部分を探す.という考え方だとエレガントに書ける.

自己結合とCASE式,HAVING句の合わせ技.


import sqlite3

db = sqlite3.connect(":memory:");
c = db.cursor();

c.execute("CREATE TABLE 名簿(名前, 収入)");
c.executemany("INSERT INTO 名簿 VALUES(?, ?)", [
    ("A", 400),
    ("B", 30),
    ("C", 20),
    ("D", 20),
    ("E", 20),
    ("F", 15),
    ("G", 15),
    ("H", 10),
    ("I", 10),
    ("J", 10),
]);


sql = "SELECT org.収入 AS median FROM 名簿 org, 名簿 cp 
        GROUP BY org.収入 
       HAVING SUM(CASE WHEN cp.収入 >= org.収入 THEN 1 ELSE 0 END) >= COUNT(*) / 2 
          AND SUM(CASE WHEN cp.収入 <= org.収入 THEN 1 ELSE 0 END) >= COUNT(*) / 2";

c.execute("SELECT AVG(DISTINCT median) FROM (" + sql + ")");

for row in c:
    print(row);

c.close();
db.close();




結果は 17.5.





これを全く同じ考え方でPythonで書くとこんな感じになる.


Python組込みのset型を使った集合演算とリスト内包表記で4行.


income = {("A", 400),
          ("B", 30),
          ("C", 20),
          ("D", 20),
          ("E", 20),
          ("F", 15),
          ("G", 15),
          ("H", 10),
          ("I", 10),
          ("J", 10)
};


s0 = set([org for org in income if len([1 for cp in income if cp[1] >= org[1]]) >= len(income) / 2]);
s1 = set([org for org in income if len([1 for cp in income if cp[1] <= org[1]]) >= len(income) / 2]);

median = set([v[1] for v in s0.intersection(s1)]);

print(sum(median) / len(median));




















ちなみに,極めて素朴な方法で手続き的にメディアンを求めるPythonコードはこんな.

s = [org[1] for org in income];
s.sort();

idx = len(s) // 2;
print((s[idx] + s[idx - 1 + (len(s) % 2)]) / 2);








自己非等値結合

2010-09-01 18:29:39 | プログラミング
SQL自分メモ




例えば記録に基づく順位表を作るときに,同記録の人を同順位として次の順位は飛び石にするケース.


下はPythonからSQLite3を使った場合の例.


import sqlite3

db = sqlite3.connect(":memory:");
c = db.cursor();

c.execute("CREATE TABLE 走高跳(記録, 名前)");
c.executemany("INSERT INTO 走高跳 VALUES(?, ?)", [
    (1.98, "tatsushi"),
    (1.85, "tatsushi"),
    (1.90, "ok"),
    (1.85, "ok"),
    (1.85, "ok"),
    (1.85, "ok"),
    (1.80, "ok"),
    (1.80, "ok"),
    (1.80, "ok"),
    (1.86, "F"),
    (1.80, "F"),
    (1.80, "masato"),
    (1.80, "masato"),
    (1.75, "masato"),
    (1.75, "masato"),
    (1.75, "masato"),
    (1.60, "showhey"),
    (1.50, "sbt"),
    (1.35, "ed"),
]);

sql = "SELECT  (SELECT COUNT(記録) FROM 走高跳 WHERE 記録 > cp.記録) + 1 AS rank, \
               記録, \
               名前 \
         FROM  走高跳 cp \
        ORDER BY rank";

c.execute(sql);

for row in c:
    print(row);

c.close();
db.close();




実行結果

1 1.98 tatsushi
2 1.9 ok
3 1.86 F
4 1.85 tatsushi
4 1.85 ok
4 1.85 ok
4 1.85 ok
8 1.8 ok
8 1.8 ok
8 1.8 ok
8 1.8 F
8 1.8 masato
8 1.8 masato
14 1.75 masato
14 1.75 masato
14 1.75 masato
17 1.6 showhey
18 1.5 sbt
19 1.35 ed




このSQL文がミソ↓.
sql = "SELECT  (SELECT COUNT(記録) FROM 走高跳 WHERE 記録 > cp.記録) + 1 AS rank, \
               記録, \
               名前 \
         FROM  走高跳 cp \
        ORDER BY rank";




こういう集合指向的な書き方には萌えますなぁ.


再帰集合を使う "SELECT COUNT(記録) FROM 走高跳 WHERE 記録 > cp.記録" の部分とか,これだけでご飯三杯いける.





SQLを書くときは,Cみたいな手続き型言語の世界とは違う思考に頭を切り替えないといけない.


staticな書き方をする関数型言語MLの考え方と根っこが共通している.

AS3:fl.controls.Slider の バグ

2010-01-27 00:34:03 | プログラミング
ActionScript3.0 で Component.swc を使ってスライダー (fl.controls.Slider) を生成すると,スライドトラックとスライダサムの領域が半分ずれて配置される


環境依存のバグなのか何なのかは分からないけど,使うごとに毎回直すのは面倒なので,継承して内部で勝手に修正するようにした.

背景色で半分塗りつぶして反対側にもう半分描くだけ.


package  
{
	import fl.controls.Slider;
	import flash.display.Sprite;
	
	public class MySlider extends Slider
	{
		
		public function MySlider() 
		{
			super();
		}
		
		internal function mySetSize(w:Number, h:Number = 0):void {

			setSize(w, h);
			
			var w2:Number = w / 2;			
			
			var occluder:Sprite = new Sprite();
			occluder.graphics.beginFill(0x0);
			occluder.graphics.drawRect( -w2, 0, w2 - 3, 4);
			occluder.graphics.endFill();
			occluder.graphics.beginFill(0xffffff, 0.6);
			occluder.graphics.drawRect( w2, 0, w2 + 3, 4);
			occluder.graphics.endFill();
			
			addChild(occluder);
		}
		
	}
	
}


Flash 物理シミュレーション その8

2010-01-13 01:12:16 | プログラミング
これの続き

バイトで作ってる物理シミュレーションFlash3件




いいかげんアイディアが底をついたと思ってても,むりやり絞り出せば意外と出てくるもんだ.


来週は譲れないイベントが立て続けにあって,本来はFlashなんて作ってる場合じゃないが,なんか仕事が立て込んでるときほどいろいろ思いつきやすい.


頭の中に新しい考えがちらついたとき,僕の損得勘定はもろくも飛散する.というわけで,気づいたらFlashDevelopを立ち上げてガリガリとActionScriptを書いていた.


あと,学会終わったらSQLを本格的に勉強したい.今までデータベースはあまり興味を持ってこなかったけど,集合知を扱う言語を覚えれば研究の強烈な武器になりそうな気がする.

というか,純粋にSQLの世界が奥が深そうで面白そう.自由に使いこなせるようになったらたぶん絶対楽しいと思う.



これからますますアレな時期だけど,忙しいとか眠いとか,そういうことの先にあるんです.面白いものへの愛情は.










画像をクリックするとFlashページに飛びます.




・モーターが回る原理(3次元版)





・凸レンズ





・凹レンズ




Flash 物理シミュレーション その7

2010-01-10 20:22:33 | プログラミング
これの続き

バイトで作ってる物理シミュレーションFlash2件



画像をクリックするとFlashページに飛びます.




慣性モーメント(空き缶,ジュースの入った缶,凍らせた缶,を転がすやつ)







単振動で速度がゼロのとき加速度が最大になるのがイメージしにくいと言うので作ったもの.






つづく

ラピッドプロトタイピングの利点

2010-01-07 22:01:14 | プログラミング
ソフトウェアのラピッドプロトタイピングについて



一般に,ソフト開発では初期の段階から最後まで仕様が変わらないことはまずなく,作っていく途中で分かってくる問題点や改善点などに基づいて仕様がしょっちゅう変更される.


なので,はじめから完成物を作るのではなく,先にプロトタイプを作ってそこから改良点を洗い出してまた作り直して…,というループを短い周期で何回も繰り返して完成に近づけていくという方法.


というか,意識してこれをやるというよりは,気づいたらいつの間にかこの形で動いていたというのが僕の周りでは普通.

たぶん.コーディングに限らず,研究でも何でも.




ラピッドプロトタイピングができると,相手の意見をその都度反映することができる,柔軟に動けるので作り直しのコストを抑えられる,などの利点がある.と言われている.




しかし僕は他にもう一点,決定的な利点があると思っている.

それは,相手に対して「仕事がこんなに順調に進んでますよ」とアピールする効果が絶大であるということである.

これは特に,ビジュアルに訴えるところだけ先に作って提案することで,さらに10倍くらい効果が高くなる.


視覚的に動くところを見せると,中身はまだできてないにも関わらず「仕事速いねぇ」という言葉を頂くことができたりするので,これで相手にファーストインパクトを与えておけば,あとはそれなりにいい関係で仕事が進められるというもの.

Flash でぷよぷよ

2010-01-05 01:02:16 | プログラミング
高速バスで久しぶりに偶然マリさんに会った.

話してた中で,ぷよぷよを実装するにはどんな方法があるかという話題になったので,自分も頭の体操代わりに ActionScript で作ってみた.





画像クリックでぷよぷよページに飛びます





なかなか,2010年初めのコーディングにふさわしく,手応えのある実装だった








Flash 物理シミュレーション その6

2010-01-04 20:46:02 | プログラミング
これの続き

バイトで作ってる物理シミュレーションFlash



画像をクリックするとFlashページに飛びます.



ローレンツ力




Papervision3D のプリミティブで alpha 値を直接操作したいときは,useOwnContainer = true にする.

テクスチャは,こんなマテリアル new BitmapFileMaterial("hoge.jpg") を引数で渡すだけ.必要に応じて material.doubleSided = true にする.




Box2D の b2DistanceJoint をいっぱいつなげて作った物体




つづく