「String」を含む日記 RSS

はてなキーワード: Stringとは

2011-01-11

人材獲得作戦・4 試験問題ほか

http://okajima.air-nifty.com/b/2010/01/post-abc6.html

迷路の最短経路を求める問題が出たので解いてみた

幅優先探索を使えばいいのがわかっていたのですんなりかけたのだが無限ループになる個所があったので動くようになるまで時間がかかった

using System;
using System.Collections.Generic;
using System.Text;
using System.Linq;

namespace MazeFind
{
    class Point
    {
        public int x;
        public int y;
        public Point before;
        public Point(int x, int y,Point before)
        {
            this.x = x;
            this.y = y;
            this.before = before;
        }
    }
    class Program
    {
        static void Main(string[] args)
        {
            const char BreakChar = 'B';
            const char GoalChar = 'G';
            const char WallChar = '*';
            const char BeforeChar = '.';

            StringBuilder[] maze = new StringBuilder[]{
                new StringBuilder("**************************"),
                new StringBuilder("*S* *                    *"),
                new StringBuilder("* * *  *  *************  *"),
                new StringBuilder("* *   *    ************  *"),
                new StringBuilder("*    *                   *"),
                new StringBuilder("************** ***********"),
                new StringBuilder("*                        *"),
                new StringBuilder("** ***********************"),
                new StringBuilder("*      *              G  *"),
                new StringBuilder("*  *      *********** *  *"),
                new StringBuilder("*    *        ******* *  *"),
                new StringBuilder("*       *                *"),
                new StringBuilder("**************************"),
            };
            Point start = new Point(1, 1,null);

            //最短経路を探索する
            Queue<Point> queque = new Queue<Point>();
            queque.Enqueue(start);

            while (queque.Count > 0)
            {
                Point now = queque.Dequeue();
                if (maze[now.y][now.x] == BreakChar)
                    Console.WriteLine("break");
                if (maze[now.y][now.x] == WallChar || maze[now.y][now.x] == BeforeChar)
                    continue;
                else if (maze[now.y][now.x] == GoalChar)
                {
                    Point p = now.before;
                    while (p != null)
                    {
                        maze[p.y][p.x] = '@';
                        p = p.before;
                    }
                    break;
                }

                if (maze[now.y - 1][now.x] != '#')
                {
                    queque.Enqueue(new Point(now.x, now.y - 1, now));
                    maze[now.y][now.x] = '.';
                }
                if (maze[now.y][now.x + 1] != '#')
                {
                    queque.Enqueue(new Point(now.x + 1, now.y, now));
                    maze[now.y][now.x] = '.';
                }
                if (maze[now.y + 1][now.x] != '#')
                {
                    queque.Enqueue(new Point(now.x, now.y + 1, now));
                    maze[now.y][now.x] = '.';
                }
                if (maze[now.y][now.x - 1] != '#')
                {
                    queque.Enqueue(new Point(now.x - 1, now.y, now));
                    maze[now.y][now.x] = '.';
                }
            }

            //結果を出力する
            foreach (StringBuilder s in maze)
                Console.WriteLine(s.ToString().Replace(BeforeChar,' '));

            Console.ReadLine();
        }
    }
}
<||

2011-01-09

http://anond.hatelabo.jp/20110109000805

最近は、24インチ 30インチディスプレイなんて安いんだから、横80ではなく横120ぐらいは平気で使える。

classname::enumname という毎回指定でも エディタインテリジェントに保管してくれるから問題ない。

個人的には、毎回、スコープを明示して欲しい

 

基本的に 外部ツールがチェックしてくれるんだから

class{

enum{

{

};

で問題ないと思われ

言い方を変えれば、class内部以外でenum定義することなんて最近はあるのか?グローバルなenumなんて余り無いと思うが・・・

クラス内部では、省略できるし、外部からクラス内部の値を呼ぶときは、どのクラスのこのenumって外部だよって意味で毎回書いたほうが安全だろ?

 

スコープの省略は基本、オススメできない。

using namespace std

ですら、書かないほうが安全 毎回std::って書かないと、うっかり、stringクラス定義する人がいないとは限らんからね・・・

一斉に変更したい? エディタ正規表現で置換すればよろしい・・・

 

原則、外部のツールで解決できる問題は、外部のツールで解決すればいい。

言語仕様拡張されると、初心者に、その理屈を説明するという問題が出てきて、そういうのは初心者には無理。

他方、ツールを使えない初心者でも、毎回コピペや手で置換は出来る。

 

ソーシャルな人を使うという観点から、そういう言語拡張オススメできない。

2010-08-06

なんで・・・どいつもこいつもStringクラスとかを独自で作るんだ?STLにあるものは、STLのを使えよSTLのを・・・

複数のオープンソースとかをまたいでアプリ作るときにStringの載せ替えでメモリコピーが発生とか、泣きたくなる。

とか言うのは有りですか?

2010-07-28

std::copy(v.begin(), v.end(), std::ostream_iterator<string>(std::cout, "\n"));

とか書くやつなんなの

2010-07-24

google発のProtocol Buffersについて

オブジェクトシリアライズツールであるプロトコルバッファについて書きます。

プロトコルバッファって何って方はこちらへ

Protocol Buffers 本家

http://code.google.com/apis/protocolbuffers/

XMLはもう不要!? Googleシリアライズツール「Protocol Buffer」

http://journal.mycom.co.jp/articles/2008/07/18/protocolbuffer/index.html

Protocol Buffers (Protocol Buffers の内部解説記事。とても参考になります)

http://dodgson.org/omo/t/?date=20080712

内容

プロトコルバッファは異種言語間でオブジェクトのやりとりをするための規格です。

独自の言語によりオブジェクトインターフェースを規定することで、多言語対応を行っています。

例えばこんな感じ。

  • address.proto
package tutorial;

message Person {
  required string name = 1;
  required int32 id = 2;        // Unique ID number for this person.
  optional string email = 3;

  enum PhoneType {
    MOBILE = 0;
    HOME = 1;
    WORK = 2;
  }

  message PhoneNumber {
    required string number = 1;
    optional PhoneType type = 2 [default = HOME];
  }

  repeated PhoneNumber phone = 4;
}

// Our address book file is just one of these.
message AddressBook {
  repeated Person person = 1;
}

以上のようなprotoファイルから各言語ソースコード、または何らかのデータ操作ライブラリを使いオブジェクトの処理を行います。

googleによってC++, Java, Python用のライブラリ作成されましたが、他の言語対応したサードパーティー製のライブラリがいくらでもあるので、実質的にほぼすべての言語で使えると言っても過言ではありません。

以下はこのライブラリを使ってみた感想などです。

整数型はVarintという可変長型でバイナリに保存される

数字が多きければ大きいほど、長いバイト長で保存されます。ただし、負数の場合符号ビットが立つ関係で、ほとんど常に変換後のバイト数が最長バイト数(10)になってしまいます。フィールドの型をsint32, sint64で宣言しると、各数値にzig-zags変換が行われるため、負数であってもその値の絶対値で使用バイト数が決まるようになります。

保存されるデータは各メッセージID/型/値のみ

バイナリに保存されるデータは各メッセージID/型/値のみです。なので、同じ定義の二つのメッセージ型は、プロトコルバッファ上では全く同じように扱うことが出来ます。例えば、片方からシリアライズしたデータを、もう片方の型でデシリアライズすることが可能です。

またオブジェクト連続シリアライズ/デシリアライズすることもできます。

継承されたクラスマッピング

すでに存在する継承関係のあるクラスを、Protocol Buffersでシリアライズ/デシリアライズしたい場合は次のようにします。

(Base, Derived はすでに存在するとします)

(ソースコード中になぜか日本語が書けないので、コメントはすべて英語になっています)

message PbBase {
        require int32 id = 1;
        require int32 value = 2;

        require Derived derived = 10; // - Point !!!
}

message PbDerived {
        require string string_value = 1;
}

継承元のメッセージ定義に、継承先のメッセージを持たせます。Base継承するクラスシリアライズ/デシリアライズしたい場合は、PbBaseメッセージを中心に処理を行うことで、比較的簡単に処理を実装することが出来ます。

例えばこんな感じ

Base *Base_DeserializeFrom(PbBase &pbobj)
{
    // Arrange the classes which inherits from Base.
    if (pbobj.has_derived()) {
        return new Derived(pbobj);
    }
    else
    ...
}

class Base {
    ...
    virtual void Base::SerializeTo(PbBase &pbobj) {
        // Set the fields of 'pbobj',
    }
    ...
};

class Derived {
    ...
    virtual void Base::SerializeTo(PbBase &pbobj)
    {
        PbDerived *derived = pbobj.mutable_derived();

        Base::SerializeTo(pbobj);
        // Set the fields of 'derived',
        ...
    }
    ...
};

protoファイルを以下のように書くと、メッセージの扱いが非常に難しくなります。

message PbBase {
        require int32 id = 1;
        require int32 value = 2;
}

message PbDerived {
        required PbBase base = 1; // - Here is the point !!!
        require string string_value = 2;
}

2010-04-20

頭痛

DLRでさ、ホスト側からホストされる側の変数定義できるじゃん。

~.SetVariable(名前, );

みたいなコードでさ。

それでさ、ホストされる側の文字列型がmutableな場合に、ホスト側のStringクラス(immutable)を、ホストされる側の文字列型として扱っていいのか悩むんだよ。

ホストされる側で文字列を変更する操作でエラーになるのは嫌だけどさ(ホストされる側の言語をそれだけで使ってれば絶対に発生しないエラーだから)、読み取りだけでもホストされる側の文字列として使えれば便利かなぁとも思うんだよ。

IronSchemeはどうしてるのかなぁ。

2010-02-13

R基礎文法最速マスター

基礎

外部スクリプトの読み込み

Rコンソールに一行ずつコマンド入力してもいいけど、実際に使うにはテキストファイルコマンドを書いて(ソースコード)一気に実行させる方が楽。

source('hogehoge.R')

hogehoge.Rというのがソースコードを書いたファイルソースファイル)の名前

ライブラリの追加

CRANという、CPANパクリがある。膨大な数のライブラリがあるので、好きなものをインストールするには、

install.packages('hoge',dependencies=TRUE)

とするのが楽。

変数宣言

不要。変数に使える文字も結構多い。日本語でもOK。

> あ<-1
> あ
[1] 1
代入
a<-1
b=2
1->a

どれでもいい。但し推奨されてるのは一番上。Rの人は「束縛」という言葉を使いたがる傾向があるけど、どっちでもいいと思う。

余談だけど、関数引数の中で代入できる、しかもその値をそのあとの引数で使える。これ実は便利。

> sum(a<-1,a)
[1] 2
変数の内容を確認

基本は変数名を入力すれば表示される。

> a
[1] 1
> str(a)
 num 1
> summary(a)
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
      1       1       1       1       1       1 

最後のsummaryはRっぽい。strっていうのはstringではなくstructの略(だと思ってる)。Rの変数はいくらでも複雑な構造になり得るけど、そのときにぱっと見がわかるように構造を出力してくれる。

ベクトル

Rの基本はベクトル

ベクトルを作る

ベクトルの作り方はいくらでもあるけど、例示するのが早いでしょう。

> x<-1:3
> y<-c(TRUE, FALSE, TRUE)
> z<-c("a","b","c")
> x
[1] 1 2 3
> y
[1]  TRUE FALSE  TRUE
> z
[1] "a" "b" "c"

他にもいっぱいあるし、関数返値ベクトルってこともよくある。

> runif(3)
[1] 0.2200965 0.6391403 0.1089252

一様乱数を三個作った。

ベクトルの要素にアクセス
> x<-letters[1:5]
> x
[1] "a" "b" "c" "d" "e"
> x[2]
[1] "b"
> x[4:5]
[1] "d" "e"
> x[c(1,3,5)]
[1] "a" "c" "e"

こんな感じで、[]の中に添え字でアクセス。1-indexなので注意。2,3番目の例では添え字にもベクトルを使って、複数の要素に一気にアクセスしてる。

ベクトルの要素に代入
> x[3]<-"z"
> x
[1] "a" "b" "z" "d" "e"

でOK。

終わりに

要望があれば続くかも。

2010-01-20

続・id:JavaBlack氏って

http://anond.hatelabo.jp/20100119023114

しょぼい煽りだなあ。

煽りに見えるのかなあ。

優れたIT技術者だからといってなにか役に立つアプリを公開したいという欲があるとは限らない。

そりゃそうですが。

よくできたアプリを公開している人は、定義からして優れたプログラマなわけですが、何も公開しない人は、優れたプログラマかどうかはわからない。

優れたプログラマアプリを公開しているとは限らないですが、公開しない人が優れたプログラマであるとは限らない。

もちろん「優れたプログラマであるとは限らない」だけで、優れたプログラマではないと断定はできないですが、これだけの長期にわたってこれだけ大量のエントリを投下している割に、具体的な技術の話がさっぱりないのはかなり異様に見えます。

昔はコードを少し載せてた。

ちょっと見てみた。

http://d.hatena.ne.jp/JavaBlack/archive/200503

2005年の分をタイトルだけさらってみたけど、コードが載ってるのは上記のStringの結合ネタぐらいのような……もちろんこういう記事はJavaプログラマにとっては(中級異常のプログラマには常識の範疇とはいえ)かなり役に立つ記事だと思うんですよ。でも、その後そういう記事は減少の一方じゃないですか?

このリストJavaやる人なら必須でしょ。このリストを作ってくれてるだけでブログレベルでは十分だと思う。

Javaオブジェクト指向参考書リスト2007年版)http://d.hatena.ne.jp/JavaBlack/20070522/p1

普通ブログ記事として、この記事だけを見たら、悪くないエントリだと思う。

でも、逆に言うとどれも標準的な必読書。内容に関する言及もないので、それこそ本をまったく読まなくても、ネットで評判を調べるだけでこのリストは作れそうだ(JavaBlack氏がこれらの本を読んでないと言っているわけじゃない。邦訳ぐらいは読んでると思う)。

でもさ、普段あれだけ上から目線の偉そうなエントリを連投している割には、ご本人の技術力は、さっぱり具体的には見えてこない。

ブコメだと、(今回の地震の話はさておき)そこそこ好意的なコメントが付くようだけど、そのへんみんなどう思ってるのかな、と思ったわけですよ。

ちょうどシロクマ先生がこんなエントリあげてるけど、

全能感を維持するために「なにもしない」人達

http://d.hatena.ne.jp/p_shirokuma/20100119/p1

JavaBlack氏は、自らの全能感を維持するために、コードを書いたり公開したりしないのかな、という気もちょっとする。

実力を晒さない限りは、馬鹿にされることもないからね。

ええと、ご本人がこれを見ることがあるとしたら、

プログラマならコードで語れ

と言いたいです。JavaBlack氏がまだ求職中なのかどうか知らないけど、もし私がうちの会社の人事権を持っていたとしても、悪いがこの人は採らない。

2010-01-14

http://anond.hatelabo.jp/20100114003544

34分

現役のときに比べて腕が鈍ってるなあ

ソースは汚いよ


同じところを二回訪れないことに注意して、次の状態をキューに入れていけばいいだけ

隣は距離1なのでただのFIFOでいい

重み付きのグラフならpriority queueを使う


dequeなんちゃらの前までが入力で、while の中が重要コード

答えはSとGも塗り潰しちゃったのを出力してる

サンプルの入力で最短距離であることを確認してる


増田できれいにC++を出力するにはどうすればいいんだろう?

#include <map&gt;
#include <string&gt;
#include <iostream&gt;
#include <vector&gt;
#include <iterator&gt;
#include <deque&gt;
#include <set&gt;

using namespace std;
typedef pair<int, int&gt; P;

int dir_x[] = {0,1, -1, 0};
int dir_y[] = {1, 0, 0, -1};

int main() {
  string line;
  vector<string&gt; input;

  while (getline(cin, line)) {
    input.push_back(line);
  }
  const int X = input.size();
  const int Y = input.begin()-&gt;size();

  vector<P&gt; start;
  P goal;
  for (int i = 0; i < X; i++) {
    for (int j = 0; j < Y; j++) {
      if (input[i][j] == 'S') {
        start.push_back(P(i, j));
      }
      else if (input[i][j] == 'G') {
        goal = P(i, j);
      }
    }
  }

  deque<vector<P&gt; &gt; Q;
  set<P&gt; visited;
  Q.push_back(start);

  while (!Q.empty()) {
    vector<P&gt; p = Q.front();
    Q.pop_front();

    if (visited.find(p.back()) != visited.end()) { continue; }
    visited.insert(p.back());

    if (p.back() == goal) {
      for (int i = 0; i < p.size(); i++) {
        input[p[i].first][p[i].second] = '$';
      }
      copy(input.begin(), input.end(), ostream_iterator<string&gt;(cout, "\n"));
      break;
    }

    for (int i = 0; i < 4; i++) {
      P next = P(p.back().first + dir_x[i], p.back().second + dir_y[i]);
      if (input[next.first][next.second] == '*') { continue; }
      vector<P&gt; new_state(p.begin(), p.end());
      new_state.push_back(next);
      Q.push_back(new_state);
    }
  }
  return 0;
}

http://anond.hatelabo.jp/20100113192313

これで40分。

タイムアタックってことでアルゴリズムは全幅探索で書き上げました。

エラーチェック皆無。

A*ならもう5分ほど延びるかな?

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;

namespace Maze
{
    class Program
    {
        // 探索用地図
        static int[,] maze;

        // 始点終点
        static Position Start = new Position(0, 0), Goal = new Position(0, 0);

        static void Main(string[] args)
        {
            //////////////////////////// まずは各行のリストとして読み込み
            string[] inMaze;

            using (var fp = new FileStream(args[0], FileMode.Open, FileAccess.Read))
            using (var iStream = new StreamReader(fp))
                inMaze = iStream.ReadToEnd().Split('\n');

            // 迷路幅
            int height = inMaze.Length;

            // 迷路高さ
            int width = inMaze[0].Length;

            /////////////////////////// 読み込んだ迷路を作業用地図に展開
            maze = new int[width, height];
            for (int y = 0; y < height; ++y)
            {
                string line = inMaze[y];
                for (int x = 0; x < line.Length; ++x)
                {
                    maze[x, y] = line[x] == '*'
                        ? -1
                        : 0;
                    if (line[x] == 'S') Start = new Position(x, y);
                    if (line[x] == 'G') Goal = new Position(x, y);
                }
            }

            // 探索実行
            int dist = Search(maze, Start);

            // 探索結果から最短経路を再現
            Position backTracer = Goal;
            while (dist&gt;1){
                --dist;
                backTracer = backTracer.Nearbys.First(pos =&gt; maze[pos.X,pos.Y] == dist);
                maze[backTracer.X, backTracer.Y] = -2;
            }

            //////////////////// 最短経路こみのアスキー地図に変換
            char[,] outMaze = new char[width, height];

            for (int y = 0; y < height; ++y)
            {
                for (int x = 0; x < width; ++x)
                {
                    outMaze[x, y] = maze[x, y] == -2
                        ? '$'
                        : maze[x, y] == -1
                            ? '*'
                            : ' ';
                }
            }
            outMaze[Start.X, Start.Y] = 'S';
            outMaze[Goal.X, Goal.Y] = 'G';


            ////////////////////// 結果は標準出力に。
            for (int y = 0; y < height; ++y)
            {
                for (int x = 0; x < width; ++x)
                    Console.Write(outMaze[x, y]);
                Console.WriteLine();
            }
            Console.ReadLine();
        }

        /// <summary&gt;
        /// 探索する。SG間の道のりを返す(道のり=SGが隣接しているなら1)
        /// </summary&gt;
        private static int Search(int[,] maze, Position Start)
        {
            List<Position&gt; FrontLine = new List<Position&gt;();
            FrontLine.Add(Start);
            int dist = 1;
            for (; ; )
            {
                List<Position&gt; NextFrontLine = new List<Position&gt;();
                foreach (var pos in FrontLine)
                {
                    foreach (var nextPos in pos.Nearbys)
                    {
                        if (nextPos == Goal) return dist;
                        if (maze[nextPos.X, nextPos.Y] == 0)
                        {
                            maze[nextPos.X, nextPos.Y] = dist;
                            NextFrontLine.Add(nextPos);
                        }
                    }
                }
                FrontLine = NextFrontLine;
                ++dist;
            }
        }
    }

    struct Position
    {
        public readonly int X, Y;
        public Position(int x, int y) { X = x; Y = y; }

        public IEnumerable<Position&gt; Nearbys
        {
            get
            {
                return new[]{
                    new Position(X-1,Y),
                    new Position(X,Y-1),
                    new Position(X+1,Y),
                    new Position(X,Y+1),
                };
            }
        }

        public static bool operator==(Position p1, Position p2){
            return p1.X == p2.X &amp;&amp; p1.Y == p2.Y;
        }

        public static bool operator!=(Position p1, Position p2){
            return p1.X != p2.X || p1.Y != p2.Y;
        }
    }
}

2009-10-04

グーグルマップ壁紙にしてみる

10/18 改訂

グーグルマップ航空写真をつなげて一枚にするスクリプト

なお、取得した画像著作権グーグル他各社が保持しています。

ご利用は計画的に私的範囲でどうぞご利用ください。

#!/usr/bin/perl

use strict;
use warnings;
use Getopt::Long;
use LWP::UserAgent;
use GD;

my $cmdline = join(" ", $0, @ARGV);
my $usage = "usage: $0 -sx=116423 -sy=51603 -ex=116426 -ey=51605 -dx=4 -dy=3 -z=17 -size=300 -get=30 -dir=cache -output=output.jpg -nodebug";
my ($sx, $sy) = (0, 0);
my ($ex, $ey) = (0, 0);
my ($dx, $dy) = (4, 3);
my $z = 17;
my $size = 300;
my $get = 30;
my $dir = "cache";
my $output = "output.jpg";
my $debug = 0;
GetOptions("sx=i" => \$sx, "sy=i" => \$sy,
	   "ex=i" => \$ex, "ey=i" => \$ey,
	   "dx=i" => \$dx, "dy=i" => \$dy,
	   "z=i" => \$z,
	   "size=i" => \$size, "get=i" => $get,
	   "dir=s" => \$dir, "output=s" => \$output,
	   "debug!" => \$debug) or die "$usage\nDied";
if ($ex == 0) {
    $ex = $sx + $dx;
} else {
    $ex++;
    $dx = $ex - $sx;
}
if ($ey == 0) {
    $ey = $sy + $dy;
} else {
    $ey++;
    $dy = $ey - $sy;
}
$sx>0 and $dx>0 and $sy>0 and $dy>0 and $z>0 and $dir and $output
    or die "$usage\nBad arguments";
$dx*$dy > $size and die "Getting too large.";

$debug and print "debug: mkdir $dir\n";
mkdir $dir;
-d $dir or die "can't make dir $dir: $!";

my $base = sprintf("http://khm%d.google.co.jp/kh/v=46&z=%d", int(rand(4)), $z);
my $ua = LWP::UserAgent->new;
printf "now get %d images...\n", $dx*$dy;
for (my $x=$sx; $x < $ex; $x++) {
    for (my $y=$sy; $y < $ey; $y++) {
	my $file = sprintf("%s/%02dz%06dx%06d.jpg", $dir, $z, $x, $y);
	$debug and print "debug: check of $file\n";
	-s $file and next;
	--$get < 0 and last;
	my $req = HTTP::Request->new(GET=>+"$base&x=$x&y=$y");
	$debug and print "debug: fetch from ".$req->uri."\n";
	my $res = $ua->request($req);
	unless ($res->is_success) {
	    print "fail fetch from $file: ", $res->status_line, "\n";
	    next;
	}
	if (open(my $fh, ">", $file)) {
	    $debug and print "debug: write of $file\n";
	    binmode $fh;
	    print $fh $res->content;
	    close $fh;
	} else {
	    print "fail open in $file: $!\n";
	}
    }
}
$get < 0 and print "reach the getting limit, skip after all.\n";

printf "creating %dX%d image...\n", 256*$dx, 256*$dy;
my $image = new GD::Image(256*$dx, 256*$dy);
for (my $x=$sx; $x < $ex; $x++) {
    for (my $y=$sy; $y < $ey; $y++) {
	my $file = sprintf("%s/%02dz%06dx%06d.jpg", $dir, $z, $x, $y);
	$debug and print "debug: check of $file\n";
	-s $file or next;
	$debug and print "debug: read of $file\n";
	my $part = GD::Image->newFromJpeg($file);
	$debug and print "debug: image copy\n";
	$image->copy($part, 256*($x-$sx), 256*($y-$sy), 0, 0, 256, 256);
    }
}
#$image->string(gdSmallFont, 0, 0, $cmdline, $image->colorAllocate(255, 255, 255));
open(my $fh, ">", $output) or die "fail open $output: $!";
$debug and print "debug: write of $output\n";
binmode $fh;
print $fh $image->jpeg();
close $fh;

例えば秋葉原とか

perl gmwall.pl -sx=116423 -sy=51603 -ex=116427 -ey=51606

駅だけとか

perl gmwall.pl -sx=465701 -sy=206420 -ex=465705 -ey=206423 -z=19

使う数値はfirebugなどで拾ってください。

2009-09-29

OOPFizzBuzz

あえてプログラミングゴルフの正反対を目指してみる。

class FizzBuzzProgram{
	public static void main(String args[]){
		for (int i = 0; i++ < 100; ) {
			System.out.println(new Number(i).checkMod3().checkMod5());
		}
	}
}

interface Mod3Mod5Unchecked extends Mod5Unchecked {
	public Mod5Unchecked checkMod3();
}

interface Mod5Unchecked {
	public Object checkMod5();
}

class Number implements Mod3Mod5Unchecked{
	private int no;
	public Number (int no) { this.no = no; }
	public Mod5Unchecked checkMod3() {
		return no % 3 == 0 ? new Fizz(no) : this;
	}
	public Object checkMod5() {
		return no % 5 == 0 ? new Buzz() : this;
	}
	public String toString() { return Integer.toString(no); }
}

class Fizz implements Mod5Unchecked{
	private int no;
	public Fizz (int no) { this.no = no; }
	public Object checkMod5() {
		return no % 5 == 0 ? new FizzBuzz() : this;
	}
	public String toString() { return "Fizz"; }
}

class Buzz {
  	public String toString() { return "Buzz"; }
  }

class FizzBuzz {
	public String toString() { return "FizzBuzz"; }
}

2009-09-24

http://anond.hatelabo.jp/20090924180748

今の場合はstd::stringですけどね…。

stringは便利になりました!とか言って、大して変わんねーよと思うわけですよ。

最近プライベートではpythonばっか使ってるからなおさら…。

http://anond.hatelabo.jp/20090924180059

std::stringchar配列で話は変わってくると思うが

まぁchar配列のCだとますます発狂だわな

それがアセンブラだったら、、、、

結論

単なるメモリ操作

2009-07-06

C#用FMFリーダー

platinumで吐き出せるFMFを読み取るためクラスを置いておく。特に反省はしてない。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Data;

namespace RPG
{
    class MapFile
    {
        //FMFファイルのヘッダー
        struct FMFHeader
        {
            public string dwIdentifier;	// ファイル識別子 'FMF_'
            public int dwSize;			// ヘッダを除いたデータサイズ
            public int dwWidth;		// マップの横幅
            public int dwHeight;		// マップの高さ
            public byte byChipWidth;	// マップチップ1つの幅(pixel)
            public byte byChipHeight;	// マップチップ1つの高さ(pixel)
            public byte byLayerCount;	// レイヤーの数
            public byte byBitCount;		// レイヤデータビットカウント
        }

        private FileStream fs;
        private BinaryReader br;
        private FMFHeader _head;
        private byte[] _data8 = null;
        private short[] _data16 = null;

        public int width
        {
            get { return _head.dwWidth; }
        }

        public int height
        {
            get { return _head.dwHeight; }
        }

        public int chip_width
        {
            get { return _head.byChipWidth; } 
        }

        public int chip_height
        {
            get { return _head.byChipHeight; }
        }

        //マップファイルを読み込む。
        //エラーが起きた場合は例外を投げます
        public void Load(String fname)
        {
            try
            {
                fs = new FileStream(fname, FileMode.Open);
                br = new BinaryReader(fs);

                //識別子を確認する
                _head.dwIdentifier = new String(br.ReadChars(4));
                if (_head.dwIdentifier != "FMF_")
                {
                    throw new Exception("ファイルが壊れています");
                }

                //ヘッダーの残りの情報を読み込む
                _head.dwSize = br.ReadInt32();
                _head.dwWidth = br.ReadInt32();
                _head.dwHeight = br.ReadInt32();
                _head.byChipWidth = br.ReadByte();
                _head.byChipHeight = br.ReadByte();
                _head.byLayerCount = br.ReadByte();
                _head.byBitCount = br.ReadByte();
                switch (_head.byBitCount)
                {
                    case 8:     //8bit layer
                        _data8 = br.ReadBytes(_head.dwSize);
                        break;
                    case 16:    //16it layer
                        int count = _head.dwSize / 2;
                        _data16 = new short[count];
                        for(int i = 0; i < count; i++)
                            _data16[i] = br.ReadInt16();
                        break;
                }
            }
            catch(Exception ex)
            {
                throw ex;
            }
            finally
            {
                br.Close();
            }
        }
        //マップファイルを閉じます
        public void close()
        {
            //読み込んだデータを破棄する
            _data8 = null;
            _data16 = null;
        }
        //マップファイルからチップ番号を取得します
        public int getValue(int layer_index, int x, int y)
        {
            if (_data8 == null &amp;amp;&amp;amp; _data16 == null)
                return -1;
            if (layer_index &gt;= _head.byLayerCount ||
                x &gt;= _head.dwWidth ||
                y &gt;= _head.dwHeight)
                    return -1;

            int index = 0;
            int layer_offset = getLayerAddr(layer_index);
            switch (_head.byBitCount)
            {
                case 8:     //8bit layer
                    index = _data8[layer_offset + x + y * _head.dwWidth];
                    break;
                case 16:    //16it layer
                    index = _data16[layer_offset + x + y * _head.dwWidth];
                    break;
            }
            return index;
        }
        //該当レイヤーが存在する_dataのindexを返す
        private int getLayerAddr(int layer_index)
        {
            if (layer_index &gt;= _head.byLayerCount || (_data8 == null &amp;amp;&amp;amp; _data16 == null))
                return -1;
            return _head.dwWidth * _head.dwHeight * layer_index;
        }
    }
}

#訂正

致命的なバグがあったので修正しました&データを取得する部分をわかりやすくした

2009-06-17

PHPの比較の素晴らしさ加減は正常


if ("0x0A" == "10") {
    print '(´ε` )チュッ';
}

チュッ。されちゃいます。

文字列であっても整数解釈できる文字列の場合は勝手に型変換しやがる今世紀最大の愚行を犯してしまうってのは有名な話だよね。

文字列であっても整数解釈できる文字列の場合は自動的に整数に型変換してくれる超便利機能があるってのは有名な話だよね。

だけどなんでコレが一致するかわけがわからんかった。

0x0Aは10進数で10になるので一致する。と、言いたいところなんですがそう単純な話じゃないんだ。

以下の例を目ん玉見開いて見て欲しい。


var_dump(0x0A);
var_dump("0x0A");
var_dump((int)"0x0A");
var_dump((float)"0x0A");
var_dump(intval("0x0A"));

実行結果
int(10)
string(4) "0x0A"
int(0)
float(0)
int(0)

つまり文字列の"0x0A"ってやつはどう考えても0と解釈されるはずなんだ。だから上記if文が本来一致するはずがいない。

でも実際は何故か10と解釈されて一致してしまう。

そう、つまり演算子で比較した場合、やらんでもいいのにわざわざ16進表記かどうかまでチェックして余計なお世話的うんこ変換しやがるということになる。

そう、つまり演算子で比較した場合は、16進表記かどうかまでチェックして10進数に変換してくれているということになる。

明示的に書くならこんな感じだ。


if (intval("0x0A",16) == "10") {
    print '(´ε` )チュッ';
}

クソが。

なるほどねー。

ただでさえ文字列同士の比較なのにintに変換されるだけでもミソ糞うぜぇのに、わざわざ16進数の場合は10進数に変換してくれる超糞尿仕様

文字列同士の比較であってもintに自動変換してくれるだけでも素晴らしいのに、それに加えて16進数の場合は10進数に変換してくれる超便利仕様

ってこたぁ、8進数表記の場合も糞糞マジ死ぬほど余計なお世話するんだろうなぁと思ってしぶしぶ試してみた。

ということは8進数表記の場合もこの素晴らしい自動変換しれくるのかなと思って試してみた。


if ("0x0A" == "012") {
    print '(´ε` )チュッ';
}
else {
    print '\(^o^)/';
}

実行結果
\(^o^)/

おー、さすがPHP!、やっぱ8進数の場合は10進数と似てるから8進数と見なすよりも10進数と見なしたほうが効率いいですもんね。いやーわかってるなー。ますますPHPが好きになりました。I Love PHP. We Love P☆H☆P!

はは、はははっ、ははははっ。やるならやる!やらないならやらない!どっちかに統一せーやこのプリンシパル校長ヘッドハンティンピープルぺーぺーぽりんき味噌マッチョ変態改造エアガン陵辱-2くらいのスカンク殺ろうがぁああああああ★ああああああああああああああああああああああああああああああああああああああfじょ★えいjfsきじぇいつつしまじいのそるいつのだ★ひろけがきちもするけけけそあいんぼろうれあああぁあああああaaaaaa


プログラ増田のあなぐら

2009-03-26

ハッシュ関数を調べる

セキュリティ目的ではない。ハッシュテーブルで使うような奴でキャッシュで使いたい。

手軽なほうが良い。軽いほうが良い。推測可能でよい。数十バイトくらいの文字列にしたい。

md5が一番汎用っぽいけど、無駄に重い気がする。crc32は軽そうだしそれなりに汎用っぽいけど、ハッシュ長が短いのがめんどい

ベターはなんだろう。セオリーはなんだろう。

調べた→ http://anond.hatelabo.jp/20090327015620

ベンチ用スクリプト

#!/usr/local/bin/python
from sys import argv, stderr
from time import time
from string import ascii_letters, join
from random import choice
from hashlib import md5
from binascii import crc32
from itertools import izip

time_fmt = '%10s: %5d ms'
shift = int(argv[1]) if len(argv)&gt;1 and argv[1].isdigit() else 2
length = 0x100 << shift
cycle = 0x10000 &gt;&gt; shift
print &gt;&gt; stderr, 'string length: 0x%x, cycle: 0x%x' % (length, cycle)
data = tuple(''.join(choice(ascii_letters) for i in xrange(length)) for j in xrange(cycle))

start = time()
md5hex = tuple(md5(s).hexdigest() for s in data)
print &gt;&gt; stderr, time_fmt % ('md5hex', (time() - start) * 1000)

start = time()
crc32x4 = tuple(''.join('%08x' % abs(crc32(s[i::4])) for i in (0, 1, 2, 3)) for s in data)
print &gt;&gt; stderr, time_fmt % ('crc32x4', (time() - start) * 1000)

start = time()
startend = tuple(s[:16]+s[-16:] for s in data)
print &gt;&gt; stderr, time_fmt % ('headtail', (time() - start) * 1000)

start = time()
skip = tuple(s[::(len(s)/32+1)] for s in data)
print &gt;&gt; stderr, time_fmt % ('skipover', (time() - start) * 1000)

for s in izip(data, md5hex, crc32x4, startend, skip):
    print join(s)

実行結果

% python hashbench.py 0 &gt; hash0.txt
string length: 0x100, cycle: 0x10000
    md5hex:   199 ms
   crc32x4:  1081 ms
  headtail:    30 ms
  skipover:    41 ms
% python hashbench.py 2 &gt; hash1.txt
string length: 0x400, cycle: 0x4000
    md5hex:    83 ms
   crc32x4:   363 ms
  headtail:    10 ms
  skipover:    20 ms
% python hashbench.py 4 &gt; hash2.txt
string length: 0x1000, cycle: 0x1000
    md5hex:    52 ms
   crc32x4:   170 ms
  headtail:     2 ms
  skipover:     5 ms

2009-03-18

公明党都議選重視?

コピーして、test.htaのような拡張子HTAで保存

HTAプログラム

 ↓

<html&gt;

<head&gt;

<style type="text/css"&gt;dt{float:left;clear:left;width:10em;}</style&gt;

<meta content="charset=Shift_JIS"/&gt;

</head&gt;

<body&gt;

<script type="text/javascript"&gt;</p&gt; <p&gt;window.onload = init;</p&gt; <p&gt;var url = [</p&gt; <p&gt; "<a href="http://www.senkyo.metro.tokyo.jp/h19sangiin/san_kekka/h19san_hkai.html"&gt;http://www.senkyo.metro.tokyo.jp/h19sangiin/san_kekka/h19san_hkai.html</a&gt;",</p&gt; <p&gt; "<a href="http://www.senkyo.metro.tokyo.jp/h17shugiin/sokuhou/7kaijyo_s.htm"&gt;http://www.senkyo.metro.tokyo.jp/h17shugiin/sokuhou/7kaijyo_s.htm</a&gt;",</p&gt; <p&gt; "<a href="http://www.senkyo.metro.tokyo.jp/h17togisen/sokuhou/2kaijyo_s.htm"&gt;http://www.senkyo.metro.tokyo.jp/h17togisen/sokuhou/2kaijyo_s.htm</a&gt;",</p&gt; <p&gt; "<a href="http://www.senkyo.metro.tokyo.jp/data/h16san_hkai.html"&gt;http://www.senkyo.metro.tokyo.jp/data/h16san_hkai.html</a&gt;",</p&gt; <p&gt; "<a href="http://www.senkyo.metro.tokyo.jp/data/h15shu_hkai.html"&gt;http://www.senkyo.metro.tokyo.jp/data/h15shu_hkai.html</a&gt;",</p&gt; <p&gt; "<a href="http://www.senkyo.metro.tokyo.jp/data/data01_01_03.html"&gt;http://www.senkyo.metro.tokyo.jp/data/data01_01_03.html</a&gt;",</p&gt; <p&gt; "<a href="http://www.senkyo.metro.tokyo.jp/data/data01_02_05.html"&gt;http://www.senkyo.metro.tokyo.jp/data/data01_02_05.html</a&gt;",</p&gt; <p&gt; "<a href="http://www.senkyo.metro.tokyo.jp/data/data03_04.html"&gt;http://www.senkyo.metro.tokyo.jp/data/data03_04.html</a&gt;",</p&gt; <p&gt; "<a href="http://www.senkyo.metro.tokyo.jp/data/data01_05_05.html"&gt;http://www.senkyo.metro.tokyo.jp/data/data01_05_05.html</a&gt;"</p&gt; <p&gt;];</p&gt; <p&gt;var base = "<a href="http://www.senkyo.metro.tokyo.jp/data/tokuhyo_23ku/"&gt;http://www.senkyo.metro.tokyo.jp/data/tokuhyo_23ku/</a&gt;";</p&gt; <p&gt;var file = ["chiyoda","chuou","minato","shinjyuku","bunkyo",</p&gt; <p&gt; "taitho","sumida","koutho","sinagawa","meguro",</p&gt; <p&gt; "ohta","setagaya","shibuya","nakaono","suginami",</p&gt; <p&gt; "toshima","kita","arakawa","itabashi","nerima",</p&gt; <p&gt; "adachi","katushika","edogawa"];</p&gt; <p&gt;for(var i=0; i<23; i++){</p&gt; <p&gt; url.push(base + file[i] + "\.html");</p&gt; <p&gt;}</p&gt; <p&gt;var id = [</p&gt; <p&gt; "2007 参院比", "2005 衆院比", "2005 都議会", "2004 参院比", "2003 衆院比",</p&gt; <p&gt; "2001 参院比", "2001 都議会", "2000 衆院比", "1998 参院比", "1997 都議会"</p&gt; <p&gt;];</p&gt; <p&gt;var ku = [</p&gt; <p&gt; "千代田","中央","港","新宿","文京",</p&gt; <p&gt; "台東","墨田","江東","品川","目黒",</p&gt; <p&gt; "大田","世田谷","渋谷","中野","杉並",</p&gt; <p&gt; "豊島","北","荒川","板橋","練馬",</p&gt; <p&gt; "足立","葛飾","江戸川"</p&gt; <p&gt;];</p&gt; <p&gt;var regexku = new RegExp("(" + ku.join("|") + ")区");</p&gt; <p&gt;var iframe = [];</p&gt; <p&gt;var data = {};</p&gt; <p&gt;var parse = [ function(){</p&gt; <p&gt; var d = iframe[0].contentWindow.document;</p&gt; <p&gt; var td = d.getElementsByTagName("td");</p&gt; <p&gt; for(var i=0, l=td.length; i<l; i++){</p&gt; <p&gt; if(regexku.test(td[i].firstChild.nodeValue)){</p&gt; <p&gt; for(var j=0, e=td[i]; j<10; j++){</p&gt; <p&gt; e = e.nextSibling;</p&gt; <p&gt; }</p&gt; <p&gt; data[RegExp.$1 + "0"] = e.firstChild.firstChild.nodeValue.replace(/\.\d+/,"");</p&gt; <p&gt; }</p&gt; <p&gt; }</p&gt; <p&gt; show();</p&gt; <p&gt;}, function(){</p&gt; <p&gt; var d = iframe[1].contentWindow.document;</p&gt; <p&gt; var nobr = d.getElementsByTagName("nobr");</p&gt; <p&gt; for(var i=0, l=nobr.length; i<l; i++){</p&gt; <p&gt; if(regexku.test(nobr[i].firstChild.nodeValue)){</p&gt; <p&gt; for(var j=0, e=nobr[i].parentNode; j<4; j++){</p&gt; <p&gt; e = e.nextSibling;</p&gt; <p&gt; }</p&gt; <p&gt; data[RegExp.$1 + "1"] = e.firstChild.nodeValue;</p&gt; <p&gt; }</p&gt; <p&gt; }</p&gt; <p&gt; show();</p&gt; <p&gt;}, function(){</p&gt; <p&gt; var d = iframe[2].contentWindow.document;</p&gt; <p&gt; var nobr = d.getElementsByTagName("nobr");</p&gt; <p&gt; for(var i=0, l=nobr.length; i<l; i++){</p&gt; <p&gt; if(regexku.test(nobr[i].firstChild.nodeValue) &amp;&amp; nobr[i].parentNode.tagName == "SPAN"){</p&gt; <p&gt; for(var j=0, e=nobr[i]; j<6; j++){</p&gt; <p&gt; e = e.parentNode;</p&gt; <p&gt; }</p&gt; <p&gt; var e2 = e.nextSibling.nextSibling.firstChild.childNodes[2].firstChild;</p&gt; <p&gt; var k = 0;</p&gt; <p&gt; data[RegExp.$1 + "2"] = 0;</p&gt; <p&gt; while(e2){</p&gt; <p&gt; if(e2.firstChild.firstChild.nodeValue.indexOf("公明党") != -1){</p&gt; <p&gt; data[RegExp.$1 + "2"] += parseInt(e2.parentNode.nextSibling.childNodes[k+2].firstChild.nodeValue.replace(",",""), 10);</p&gt; <p&gt; }</p&gt; <p&gt; e2 = e2.nextSibling;</p&gt; <p&gt; k++;</p&gt; <p&gt; }</p&gt; <p&gt; data[RegExp.$1 + "2"] = int2str(data[RegExp.$1 + "2"]);</p&gt; <p&gt; }</p&gt; <p&gt; }</p&gt; <p&gt; show();</p&gt; <p&gt;}, function(){</p&gt; <p&gt; var d = iframe[3].contentWindow.document;</p&gt; <p&gt; var td = d.getElementsByTagName("td");</p&gt; <p&gt; for(var i=0, l=td.length; i<l; i++){</p&gt; <p&gt; if(regexku.test(td[i].firstChild.nodeValue)){</p&gt; <p&gt; for(var j=0, e=td[i]; j<19; j++){</p&gt; <p&gt; e = e.nextSibling;</p&gt; <p&gt; }</p&gt; <p&gt; data[RegExp.$1 + "3"] = e.firstChild.firstChild.nodeValue.replace(/\.\d+/,"");</p&gt; <p&gt; }</p&gt; <p&gt; }</p&gt; <p&gt; show();</p&gt; <p&gt;}, function(){</p&gt; <p&gt; var d = iframe[4].contentWindow.document;</p&gt; <p&gt; var td = d.getElementsByTagName("td");</p&gt; <p&gt; var regexku2 = /(大田|世田谷|練馬|足立|江戸川)/;</p&gt; <p&gt; for(var i=0, l=td.length; i<l; i++){</p&gt; <p&gt; if(regexku.test(td[i].firstChild.nodeValue)){</p&gt; <p&gt; data[RegExp.$1 + "4"] = td[i].nextSibling.nextSibling.firstChild.nodeValue.replace(/\.\d+/,"");</p&gt; <p&gt; continue;</p&gt; <p&gt; }</p&gt; <p&gt; if(regexku2.test(td[i].firstChild.nodeValue)){</p&gt; <p&gt; data[RegExp.$1 + "4"] = (data[RegExp.$1 + "4"] || 0) </p&gt; <p&gt; + parseInt(td[i].nextSibling.nextSibling.firstChild.nodeValue.replace(",","").replace(/\.\d+/,""));</p&gt; <p&gt; }</p&gt; <p&gt; }</p&gt; <p&gt; for(var j=0; j<5; j++){</p&gt; <p&gt; data[ku[[10,11,19,20,22][j]]+"4"] = int2str(data[ku[[10,11,19,20,22][j]]+"4"]);</p&gt; <p&gt; }</p&gt; <p&gt; show();</p&gt; <p&gt;}, function(){</p&gt; <p&gt; var d = iframe[5].contentWindow.document;</p&gt; <p&gt; var td = d.getElementsByTagName("td");</p&gt; <p&gt; for(var i=0, l=td.length; i<l; i++){</p&gt; <p&gt; if(regexku.test(td[i].firstChild.firstChild.nodeValue)){</p&gt; <p&gt; for(var j=0, e=td[i]; j<10; j++){</p&gt; <p&gt; e = e.nextSibling;</p&gt; <p&gt; }</p&gt; <p&gt; data[RegExp.$1 + "5"] = e.firstChild.firstChild.nodeValue.replace(/\.\d+/,"");</p&gt; <p&gt; }</p&gt; <p&gt; }</p&gt; <p&gt; show();</p&gt; <p&gt;}, function(){</p&gt; <p&gt; var d = iframe[6].contentWindow.document;</p&gt; <p&gt; var td = d.getElementsByTagName("td");</p&gt; <p&gt; for(var i=0, l=td.length; i<l; i++){</p&gt; <p&gt; if(regexku.test(td[i].firstChild.firstChild.nodeValue)){</p&gt; <p&gt; for(var j=0, e=td[i]; j<7; j++){</p&gt; <p&gt; e = e.nextSibling;</p&gt; <p&gt; }</p&gt; <p&gt; data[RegExp.$1 + "6"] = e.firstChild.firstChild.nodeValue.replace(/\.\d+/,"").replace("-","0");</p&gt; <p&gt; }</p&gt; <p&gt; }</p&gt; <p&gt; show();</p&gt; <p&gt;}, function(){</p&gt; <p&gt; var d = iframe[7].contentWindow.document;</p&gt; <p&gt; var td = d.getElementsByTagName("td");</p&gt; <p&gt; for(var i=0, l=td.length; i<l; i++){</p&gt; <p&gt; if(regexku.test(td[i].firstChild.firstChild.nodeValue)){</p&gt; <p&gt; for(var j=0, e=td[i]; j<9; j++){</p&gt; <p&gt; e = e.nextSibling;</p&gt; <p&gt; }</p&gt; <p&gt; data[RegExp.$1 + "7"] = e.firstChild.firstChild.nodeValue;</p&gt; <p&gt; }</p&gt; <p&gt; }</p&gt; <p&gt; show();</p&gt; <p&gt;}, function(){</p&gt; <p&gt; var d = iframe[8].contentWindow.document;</p&gt; <p&gt; var td = d.getElementsByTagName("td");</p&gt; <p&gt; for(var i=0, l=td.length; i<l; i++){</p&gt; <p&gt; if(regexku.test(td[i].firstChild.firstChild.nodeValue)){</p&gt; <p&gt; data[RegExp.$1 + "8"] = int2str(td[i].nextSibling.firstChild.firstChild.firstChild.nodeValue);</p&gt; <p&gt; }</p&gt; <p&gt; }</p&gt; <p&gt; show();</p&gt; <p&gt;}, function(n){ return function(){</p&gt; <p&gt; var d = iframe[n+9].contentWindow.document;</p&gt; <p&gt; var td = d.getElementsByTagName("td");</p&gt; <p&gt; data[ku[n]+"9"] = 0;</p&gt; <p&gt; for(var i=0, l=td.length; i<l; i++){</p&gt; <p&gt; if((((td[i].firstChild || 0).firstChild || 0).nodeValue || "").indexOf("公明") == 0){</p&gt; <p&gt; data[ku[n]+"9"] += parseInt(td[i].parentNode.lastChild.firstChild.firstChild.nodeValue.replace(",",""));</p&gt; <p&gt; }</p&gt; <p&gt; }</p&gt; <p&gt; data[ku[n]+"9"] = int2str(data[ku[n]+"9"]);</p&gt; <p&gt; show();</p&gt; <p&gt;}}];</p&gt; <p&gt;function init(){</p&gt; <p&gt; for(var i=0; i<23; i++){</p&gt; <p&gt; var dl = document.createElement("dl");</p&gt; <p&gt; dl.appendChild(document.createTextNode("\n【" + ku[i] + "区における公明票】\n"));</p&gt; <p&gt; for(var j=0; j<10; j++){</p&gt; <p&gt; var dt = document.createElement("dt");</p&gt; <p&gt; var dd = document.createElement("dd");</p&gt; <p&gt; dt.innerText = id[j];</p&gt; <p&gt; dl.appendChild(dt);</p&gt; <p&gt; dl.appendChild(dd);</p&gt; <p&gt; }</p&gt; <p&gt; document.body.firstChild.appendChild(dl);</p&gt; <p&gt; }</p&gt; <p&gt; for(var i=0; i<32; i++){</p&gt; <p&gt; var e = document.createElement("iframe");</p&gt; <p&gt; iframe[i] = e;</p&gt; <p&gt; e.style.display = "none";</p&gt; <p&gt; if(i<9) var f = parse[i];</p&gt; <p&gt; else var f = parse[9](i-9);</p&gt; <p&gt; e.attachEvent("onload", f);</p&gt; <p&gt; e.src = url[i];</p&gt; <p&gt; document.body.appendChild(e);</p&gt; <p&gt; }</p&gt; <p&gt;}</p&gt; <p&gt;function show(){</p&gt; <p&gt; for(var i=0; i<23; i++){</p&gt; <p&gt; var dl = document.body.firstChild.childNodes[i];</p&gt; <p&gt; for(var j=0; j<10; j++){</p&gt; <p&gt; var dt = dl.childNodes[j*2+1];</p&gt; <p&gt; dt.innerText = id[j] + " " + (data[ku[i]+j] || "");</p&gt; <p&gt; dt.nextSibling.innerText = bar(data[ku[i]+j], j);</p&gt; <p&gt; }</p&gt; <p&gt; }</p&gt; <p&gt;}</p&gt; <p&gt;function int2str(num){</p&gt; <p&gt; return new String(num).split("").reverse().join("").replace(/(\d{3})/g,"$1,").split("").reverse().join("");</p&gt; <p&gt;}</p&gt; <p&gt;function bar(str, flag){</p&gt; <p&gt; str = str || "";</p&gt; <p&gt; if(str == "" || str.length < 5) return "";</p&gt; <p&gt; var num = parseInt(str.match(/\d+/)) + 1;</p&gt; <p&gt; var arrow = (flag == 2 || flag == 6 || flag == 9) ? " ←" : "";</p&gt; <p&gt; var _bar = new Array(num).join("|") + arrow;</p&gt; <p&gt; return _bar;</p&gt; <p&gt;}</p&gt; <p&gt;</script&gt;

</body&gt;

</html&gt;

2009-01-16

面倒くさくなった

// ==UserScript==
// @name           anond
// @namespace      http://anond.hatelabo.jp/
// @include        http://anond.hatelabo.jp/?page=*
// ==/UserScript==
function anond(doc) {
    $X(".//div[@class='section'][.//h3/a[2][starts-with(@href, 'http://anond.hatelabo.jp')]]", doc, Array).forEach(function(node){
        node.style.display = "none";
    });
    $X(".//h3/a[1]", doc, Array).forEach(function(node){
        var a = document.createElement("a");
        a.name = node.pathname;
        a.href = "#" + node.pathname + "/footer";
        a.innerHTML = "V";
        node.parentNode.insertBefore(a, node);
    });
    $X(".//p[@class = 'sectionfooter']/a[1]", doc, Array).forEach(function(node){
        var a = document.createElement("a");
        a.name = node.pathname + "/footer";
        a.href = "#" + node.pathname;
        a.innerHTML = "^";
        node.parentNode.insertBefore(a, node);
        node.parentNode.insertBefore(document.createTextNode(" | "), node);
    });
}

anond(document);
if (AutoPagerize.addDocumentFilter)
    AutoPagerize.addDocumentFilter(anond);


// by http://lowreal.net/blog/2007/11/17/1
// $X(exp);
// $X(exp, context);
// $X(exp, type);
// $X(exp, context, type);
function $X (exp, context, type /* want type */) {
    if (typeof context == "function") {
        type    = context;
        context = null;
    }
    if (!context) context = document;
    var exp = (context.ownerDocument || context).createExpression(exp, function (prefix) {
        var o = document.createNSResolver(context).lookupNamespaceURI(prefix);
        if (o) return o;
        return (document.contentType == "application/xhtml+xml") ? "http://www.w3.org/1999/xhtml" : "";
    });

    switch (type) {
        case String:
            return exp.evaluate(
                context,
                XPathResult.STRING_TYPE,
                null
            ).stringValue;
        case Number:
            return exp.evaluate(
                context,
                XPathResult.NUMBER_TYPE,
                null
            ).numberValue;
        case Boolean:
            return exp.evaluate(
                context,
                XPathResult.BOOLEAN_TYPE,
                null
            ).booleanValue;
        case Array:
            var result = exp.evaluate(
                context,
                XPathResult.ORDERED_NODE_SNAPSHOT_TYPE,
                null
            );
            var ret = [];
            for (var i = 0, len = result.snapshotLength; i < len; i++) {
                ret.push(result.snapshotItem(i));
            }
            return ret;
        case undefined:
            var result = exp.evaluate(context, XPathResult.ANY_TYPE, null);
            switch (result.resultType) {
                case XPathResult.STRING_TYPE : return result.stringValue;
                case XPathResult.NUMBER_TYPE : return result.numberValue;
                case XPathResult.BOOLEAN_TYPE: return result.booleanValue;
                case XPathResult.UNORDERED_NODE_ITERATOR_TYPE: {
                    // not ensure the order.
                    var ret = [];
                    var i = null;
                    while (i = result.iterateNext()) {
                        ret.push(i);
                    }
                    return ret;
                }
            }
            return null;
        default:
            throw(TypeError("$X: specified type is not valid type."));
    }
}

2008-12-26

[]Hatena::Bookmark::24H::Chart

修正:いい加減&が変換されるのを何とかしてほしい

解説:Hatena::Bookmark::24H(http://hatebu24h.ashitano.in/)に、トップエントリの獲得したブックマーク数の推移のチャートを加えます。

// ==UserScript==
// @name           chart of Hatena::Bookmark::24H
// @namespace      http://anond.hatelabo.jp/
// @include        http://hatebu24h.ashitano.in/*
// ==/UserScript==

var url = unescape("http://chart.apis.google.com/chart?chs=160x60%26cht=ls%26chd=t:");
url = url + $X("//div[@class='clocktxt']", Array).map(function(s){return s.firstChild.nodeValue}).join(",");
//var id = $X("//h3/a/@href")[0].nodeValue;
//url = url + $X("//div[@class='entrytitle' or @class='entrytitle2'][.//a[@href='"+id+"']]/../preceding-sibling::div[1]", Array).map(function(s){return s.textContent.match(/\d+/)}).join(",");
var before = makeElements({
    nodeName: "div",
    className: "sidebox",
    childNodes: [{
        nodeName: "div",
        className: "sidetitle",
        innerHTML: "Recent top entry chart"
      },{
        nodeName: "div",
        className: "sidetitle",
        childNodes: {
            nodeName: "img",
            src: url
        }
    }]
});
var after = $X("//div[@class='sidebox']", Array)[0];
after.parentNode.insertBefore(before, after);

// util

// var 0.01
function makeElements(obj) {
    if (typeof obj != "object")
        return document.createTextNode(obj);
    if (obj instanceof Array)
        return obj.map(makeElements);
    var node = document.createElement(obj.nodeName);
    delete obj.nodeName;
    if (obj.childNodes) {
        [].concat(makeElements(obj.childNodes)).forEach(node.appendChild, node);
        delete obj.childNodes;
    }
    function extend(dst, src) {
        for (var i in src) {
            if (typeof src[i] == "object" &amp;&amp; dst[i] &amp;&amp; typeof dst[i] == "object")
                extend(dst[i], src[i]);
            else
                node[i]=obj[i];
        }
    }
    extend(node, obj);
    return node;
}

// by http://lowreal.net/blog/2007/11/17/1
// $X(exp);
// $X(exp, context);
// $X(exp, type);
// $X(exp, context, type);
function $X (exp, context, type /* want type */) {
    if (typeof context == "function") {
        type    = context;
        context = null;
    }
    if (!context) context = document;
    var exp = (context.ownerDocument || context).createExpression(exp, function (prefix) {
        var o = document.createNSResolver(context).lookupNamespaceURI(prefix);
        if (o) return o;
        return (document.contentType == "application/xhtml+xml") ? "http://www.w3.org/1999/xhtml" : "";
    });

    switch (type) {
        case String:
            return exp.evaluate(
                context,
                XPathResult.STRING_TYPE,
                null
            ).stringValue;
        case Number:
            return exp.evaluate(
                context,
                XPathResult.NUMBER_TYPE,
                null
            ).numberValue;
        case Boolean:
            return exp.evaluate(
                context,
                XPathResult.BOOLEAN_TYPE,
                null
            ).booleanValue;
        case Array:
            var result = exp.evaluate(
                context,
                XPathResult.ORDERED_NODE_SNAPSHOT_TYPE,
                null
            );
            var ret = [];
            for (var i = 0, len = result.snapshotLength; i < len; i++) {
                ret.push(result.snapshotItem(i));
            }
            return ret;
        case undefined:
            var result = exp.evaluate(context, XPathResult.ANY_TYPE, null);
            switch (result.resultType) {
                case XPathResult.STRING_TYPE : return result.stringValue;
                case XPathResult.NUMBER_TYPE : return result.numberValue;
                case XPathResult.BOOLEAN_TYPE: return result.booleanValue;
                case XPathResult.UNORDERED_NODE_ITERATOR_TYPE: {
                    // not ensure the order.
                    var ret = [];
                    var i = null;
                    while (i = result.iterateNext()) {
                        ret.push(i);
                    }
                    return ret;
                }
            }
            return null;
        default:
            throw(TypeError("$X: specified type is not valid type."));
    }
}

2008-10-30

http://anond.hatelabo.jp/20081025202001

いまさらだがFizzBuzz

1から100まで、3の倍数5の倍数云々って、全部定数の計算じゃね?

というところに気付き、自称メタプログラマー(略してメタグラマー)俺の血が騒いだ。

定数計算なら、それは実行時ではなくコンパイル時に行なわれるべきだ……。

というわけでC++テンプレートメタプログラミング召喚。

#include <iostream>

const int FIZZ_NUM = 3;
const int BUZZ_NUM = 5;
const int BEGIN_NUM = 1;
const int END_NUM = 101;

template<int N> struct Fizz {
    enum {PRINT = 0, NEXT = N + 1};
    static void print() {}
};

template<int N> struct Buzz {
    enum {PRINT = 0, NEXT = N + 1};
    static void print() {}
};

template<int N, bool ForB> struct Number {static void print() {std::cout << N;}};

template<> struct Fizz<FIZZ_NUM> {
    enum {PRINT = 1, NEXT = 1};
    static void print() {std::cout << "Fizz";}
};

template<> struct Buzz<BUZZ_NUM> {
    enum {PRINT = 1, NEXT = 1};
    static void print() {std::cout << "Buzz";}
};

template<int N> struct Number<N, true> {static void print() {}};

template<int N, int F, int B> struct FizzBuzz {
    static void print() {
        typedef ::Fizz<F> Fizz;
        typedef ::Buzz<B> Buzz;
        
        Fizz::print();
        Buzz::print();
        Number<N, Fizz::PRINT || Buzz::PRINT>::print();
        std::cout << std::endl;
        
        FizzBuzz<N + 1, Fizz::NEXT, Buzz::NEXT>::print();
    }
};

template<int F, int B> struct FizzBuzz<END_NUM, F, B> {static void print() {}};

int main(int argc, char **argv)
{
    FizzBuzz<BEGIN_NUM, 1, 1>::print();
    return 0;
}

ifなし%なしループ系なし、しかも実行時オーバーヘッドなし!(多分)

あ、これを見て理解する人間オーバーヘッドは無視ね。

ああ、久しぶりにC++を触ったけど、やっぱC++テンプレートってダメダメだな。20世紀の遺物といわざるを得ない。

君がもし21世紀モテイケメンメタグラマーなら、21世紀プログラミング言語D言語を使うべきだ!

驚くべきことに、D言語コンパイル時に関数が実行でき、その結果をソースコードとして取り込める!

ただし実行できるのは簡単な関数だけだけど……。

以下、それを使ったD言語によるメタプログラミング的実装。

import std.stdio;

// これでFizzBuzzを全部出力するコードを作るぜ!
string makeFizzBuzzCode() {
    string code;
    for(int i = 1; i <= 100; ++i) {
        // 効率? コンパイル時にそんな配慮は要らん!
        if(i % 3 == 0 &amp;&amp; i % 5 == 0) {
            code ~= "writefln(\"FizzBuzz\");\n";
        } else if(i % 3 == 0) {
            code ~= "writefln(\"Fizz\");\n";
        } else if(i % 5 == 0) {
            code ~= "writefln(\"Buzz\");\n";
        } else {
            code ~= "writefln(" ~ static_itoa(i) ~ ");\n";
        }
    }
    return code;
}

int main(string[] args) {
    // おまけで生成されたコードも見せるよ。
    pragma(msg, makeFizzBuzzCode());
    
    // 生成したコードを埋め込む。コピペみたいな感覚
    mixin(makeFizzBuzzCode);
    return 0;
}

// 以下ユーティリティ。このぐらい標準で欲しいな……。

/// 整数文字列変換(コンパイル時)
string static_itoa(int n) {
    if(n == 0) {
        return "0";
    }
    
    // 10で割りながら余りを文字にして追加。桁が逆転した文字列になる。
    string s;
    for(; n; n /= 10) {
        s ~= ("0123456789")[n % 10];
    }
    
    // 桁位置を正常にする。相変わらず効率無視。
    return static_reverse(s);
}

/// 配列リバースコンパイル時)
/// 実行時ならarray.reverseが使えるんだけどね……。
T[] static_reverse(T)(T[] s) {
    T[] result;
    foreach_reverse(c; s) {
        result ~= c;
    }
    return result;
}

// 心配なので静的ユニットテスト(笑)
unittest {
    static assert(static_itoa(0) == "0");
    static assert(static_itoa(10) == "10");
    static assert(static_itoa(999) == "999");
    static assert(static_itoa(9999) == "9999");
    static assert(static_itoa(12345) == "12345");
    static assert(static_itoa(314159265) == "314159265");
}

コンパイル結果

$ dmd -unittest fizz_buzz.d
writefln(1);
writefln(2);
writefln("Fizz");
writefln(4);
writefln("Buzz");
writefln("Fizz");
writefln(7);
writefln(8);
writefln("Fizz");
writefln("Buzz");
writefln(11);
writefln("Fizz");
writefln(13);
writefln(14);
writefln("FizzBu(ry

出力結果は略。

さすがD言語C++JavaC#にできない事を平然とやってのけるッ

そこにシビれる!あこがれるゥ!

というか、

writefln(1);
writefln(2);
writefln("Fizz");
writefln(4);

もうwritefln(出力関数)要らなくね?

修正。

// これでFizzBuzzを全部出力するぜ!
string makeFizzBuzzCode() {
    string code;
    for(int i = 1; i <= 100; ++i) {
        // 効率? コンパイル時にそんな配慮は要らん!
        if(i % 3 == 0 &amp;&amp; i % 5 == 0) {
            code ~= "FizzBuzz\n";
        } else if(i % 3 == 0) {
            code ~= "Fizz\n";
        } else if(i % 5 == 0) {
            code ~= "Buzz\n";
        } else {
            code ~= static_itoa(i) ~ "\n";
        }
    }
    return code;
}

int main(string[] args) {
    // もうコンパイル時のメッセージしか出さない。(笑)
    pragma(msg, makeFizzBuzzCode());
    return 0;
}

コンパイル結果。

$ dmd -unittest fizz_buzz.d
1
2
Fizz
4
Buzz
Fizz
7
8
Fizz
Buzz
11
Fizz
13
14
FizzBu(ry

実行するまでもなく結果が出力された。つまり実行時間ゼロ、ということは……

世 界 最 速

以上、世界最速なD言語宣伝でした。

みんな使おうD言語

D言語リファレンス日本語

http://www.kmonos.net/alang/d/1.0/index.html(1.0。こっちの方が安定してる?)

http://www.kmonos.net/alang/d/2.0/index.html(もっと凄い2.0)

D言語本家配布元(無料コンパイラが入手できます)

http://www.digitalmars.com/

それにしても、ちゃんとD言語シンタックスハイライトを実装しているはてなは偉い。(笑)

2008-10-20

Key作品タイトル

Kanon

パッヘルベル「3つのヴァイオリン通奏低音のためのカノンジーグ ニ長調

(独: Kanon und Gigue in D-Dur für drei Violinen und Basso Continuo)

1曲目の「Canon in D major」はたぶんクラシックの中で一番有名な曲

AIR

バッハの「G線上のアリア」(Air on the G String)

アリア英語読みするとAir

CLANNAD

アイルランド音楽グループヴォーカルエンヤの姉

名前の由来は「入り江(の村)から来た家族

リトルバスターズ!

the pillowsの6枚目アルバムLITTLE BUSTERS」から。

アニメフリクリ」の挿入歌に使われている曲が多い。

Rewrite

ASIAN KUNG-FU GENERATIONシングル鋼の錬金術師OP

消してえーリライトしてえー

だんだん俗っぽくなってるのは気のせいですか?

2008-10-18

http://anond.hatelabo.jp/20081018072817 の続きだよ

これでおしまいだよ

elisp

sangels.el
(require 'cl)				; for cl-seq

(defvar sangels-movies-dir nil)
(defvar sangels-player "c:/Program Files/GRETECH/GomPlayer/GOM.exe")
(defvar sangels-sort-by 'sangels-sort-by-rate)
(defvar sangels-rate-file "~/.emacs.d/.sangels/rate")
(defvar sangels-buffer "*sangels*")
(defvar sangels-thumbnail "00_thumbnail.jpg")
(defvar sangels-m3u "00_movies.m3u")
(defface sangels-name '((t (:family "fixed" :weight bold :height 3.0)))
  "")
(defface sangels-rate '((t (:family "fixed" :weight bold :height 1.5)))
  "")
(defvar sangels-mode-map
  (let ((map (make-sparse-keymap)))
    (define-key map "n" 'next-line)
    (define-key map "p" 'previous-line)
    (define-key map (kbd "RET") 'sangels-select)
    (define-key map (kbd "SPC") 'sangels-select)
    (define-key map "q" 'sangels-quit)
    (define-key map "+" 'sangels-rate-plus)
    (define-key map "-" 'sangels-rate-minus)
    map))
(defvar sangels-mode-hook nil)
(defvar sangels-highlight-overlay nil)
(defvar sangels-rate-alist nil)

(defconst sangels-rate-max 6)

(defun sangels-insert-movies ()
  (save-excursion
    (let* ((inhibit-read-only t)
           (files (remove-if-not
                   (lambda (x)
                     (and (not (member (file-name-nondirectory x) '("." "..")))
                          (file-directory-p x)
                          (member sangels-thumbnail (directory-files x))))
                   (directory-files sangels-movies-dir t)))
           (ids (mapcar 'file-name-nondirectory files)))
      (erase-buffer)
      (setq ids (sangels-sort-ids ids))
      (dolist (id ids)
        (let ((file (expand-file-name id sangels-movies-dir))
              (pos (point)))
          (insert-image-file (expand-file-name sangels-thumbnail file))
          (end-of-line)
          (insert (propertize (format "%-15s " id)
                              'face 'sangels-name))
          (sangels-insert-rate id)
          (insert "\n")
          (put-text-property pos (point) 'sangels-id id))))))

(defun sangels-sort-by-name (a b)
  (string< a b))

(defun sangels-sort-by-rate (a b)
  (or (> (sangels-rate a) (sangels-rate b))
      (sangels-sort-by-name a b)))

(defun sangels-sort-ids (ids)
  (sort ids
        (or sangels-sort-by
            'sangels-sort-by-name)))
(defun sangels-insert-rate (id)
  (let ((rate (sangels-rate id)))
    (insert (propertize (concat
                         (make-string rate ?★)
                         (make-string (- sangels-rate-max rate) ?☆))
                        'sangels-rate t
                        'face 'sangels-rate))))

(defun sangels-current-id ()
  (get-text-property (point) 'sangels-id))

(defun sangels-play-movie (movie)
  (let ((explicit-shell-file-name "cmdproxy")
        (shell-file-name "cmdproxy"))
    (apply
     'call-process-shell-command
     "start" nil "*tmp*" nil
     (mapcar (lambda (x) (concat "\"" x "\""))
             (list sangels-player
                   (unix-to-dos-filename movie))))))

(defun sangels-select ()
  (interactive)
  (let ((id (sangels-current-id)))
    (when id
      (sangels-play-movie (expand-file-name
                           sangels-m3u
                           (expand-file-name id sangels-movies-dir))))))

(defun sangels-quit ()
  (interactive)
  (kill-buffer sangels-buffer))

(defun sangels-rate (id)
  (or (cdr (assoc id sangels-rate-alist)) (/ sangels-rate-max 2)))

(defun sangels-rate-save ()
  (interactive)
  (let ((dir (file-name-directory sangels-rate-file)))
    (unless (file-exists-p dir)
      (make-directory dir t)))
  (with-temp-file sangels-rate-file
    (insert (pp-to-string sangels-rate-alist))))

(defun sangels-rate-load ()
  (interactive)
  (when (file-exists-p sangels-rate-file)
    (with-temp-buffer
      (insert-file-contents sangels-rate-file)
      (goto-char (point-min))
      (setq sangels-rate-alist (read (current-buffer))))))

(defun sangels-rate-plus (&amp;optional n)
  (interactive "p")
  (setq n (or n 1))
  (let* ((id (sangels-current-id))
         (cell (assoc id sangels-rate-alist)))
    (unless cell
      (setq cell (cons id (sangels-rate id)))
      (setq sangels-rate-alist (cons cell sangels-rate-alist)))
    (setcdr cell (+ (cdr cell) n))
    (save-excursion
      (let ((inhibit-read-only t))
        (beginning-of-line)
        (goto-char (next-single-property-change (point) 'sangels-rate))
        (delete-region (point)
                       (next-single-property-change (point) 'sangels-rate))
        (sangels-insert-rate id)))
    (sangels-rate-save)))

(defun sangels-rate-minus (&amp;optional n)
  (interactive "p")
  (setq n (or n -1))
  (sangels-rate-plus (- n)))

(defun sangels-post-command-hook ()
  (save-excursion
    (move-overlay
     sangels-highlight-overlay
     (progn
       (move-beginning-of-line 1)
       (point))
     (progn
       (move-end-of-line 1)
       (forward-line)
       (point))
     (current-buffer))))

(defun sangels-mode ()
  (interactive)
  (kill-all-local-variables)
  (use-local-map sangels-mode-map)
  (setq sangels-highlight-overlay (make-overlay 0 0))
  (overlay-put sangels-highlight-overlay 'face 'highlight)
  (overlay-put sangels-highlight-overlay 'evaporate t)
  (make-local-variable 'post-command-hook)
  (add-hook 'post-command-hook 'sangels-post-command-hook nil t)
  (setq major-mode 'sangels-mode)
  (setq mode-name "Sangels")
  (run-mode-hooks 'sangels-mode-hook)
  (set-buffer-modified-p nil)
  (setq buffer-read-only t))

(defun sangels (&amp;optional arg)
  (interactive "P")
  (when (or arg (not sangels-movies-dir))
    (setq sangels-movies-dir (read-directory-name "movies dir: ")))
  (sangels-rate-load)
  (switch-to-buffer (get-buffer-create sangels-buffer))
  (sangels-insert-movies)
  (sangels-mode))

(provide 'sangels)

2008-07-22

[]関連エントリーのツリーをたどれるグレモン

結局概要表示機能追加した。unsafeWindow使いまくり大丈夫かいな。

// ==UserScript==
// @name	Hatena Bookmark Tree Expander
// @namespace	http://anond.hatelabo.jp/
// @include	http://b.hatena.ne.jp/entry/*
// ==/UserScript==
// <div class="info">
//   <ul id="similar_entries" class="bookmarklist">
//     <li></li>
//   </ul>
// </div>
// <div class="info">
//   <ul id="referred_entries" class="bookmarklist">
//     <li id="referred-entry-\d+"></li>
//   </ul>
// </div>
// <div class="info">
//   <ul id="relation_diary" class="bookmarklist">
//     <li id="diary-{id}-\d+"></li>
//   </ul>
// </div>
(function() {

function main() {
	loadBookmarkCommentViewer();
	similar.prototype.rootAppend();
	referred.prototype.rootAppend();
}

function HBTM(target) {
	this.target = target;
	this.targetXPath = "//ul[@id='"+target+"']/li";
	this.targetRegExp = new RegExp('<ul id="'+target+'"(.|\\s)*?</ul>');
}
HBTM.prototype = {
	openIcon:
		'<img width="15" height="15" class="icon" style="opacity: 0.6" src="http://anond.hatelabo.jp/images/common/open.gif"/>',
	closeIcon:
		'<img width="15" height="15" class="icon" style="opacity: 0.6" src="http://anond.hatelabo.jp/images/common/close.gif"/>',
	loadingIcon:
		'<img width="13" height="13" class="icon" src="http://anond.hatelabo.jp/images/common/loading.gif"/>',
	commentIcon: function(url) {
		return '<img class="hatena-bcomment-view-icon" src="http://r.hatena.ne.jp/images/popup.gif" onclick="iconImageClickHandler(this, \''+url+'\', event);">'
	},
	create: function() {
		this.comment = document.createElement("span");
		this.comment.innerHTML = this.commentIcon($X("string(descendant::a/@href)", this.node).value());
		this.open = document.createElement("a");
		this.open.href = "javascript:void(0)";
		this.open.innerHTML = this.openIcon;
		this.close = document.createElement("a");
		this.close.href = "javascript:void(0)";
		this.close.innerHTML = this.closeIcon;
		this.close.style.display = "none";
		this.loading = document.createElement("span");
		this.loading.innerHTML = this.loadingIcon;
		this.loading.style.display = "none";
		this.node.appendChild(this.comment);
		this.node.appendChild(document.createTextNode(" "));
		this.node.appendChild(this.open);
		this.node.appendChild(this.close);
		this.node.appendChild(this.loading);
		this.open.addEventListener("click", bind(this.openAct, this), false);
		this.close.addEventListener("click", bind(this.closeAct, this), false);
	},
	openAct: function() {
		this.open.style.display = "none";
		if (this.tree) {
			this.tree.style.display = "block";
			this.close.style.display = "inline";
		} else {
			this.loading.style.display = "inline";
			this.load();
		}
	},
	closeAct: function() {
		if (this.tree) {
			this.tree.style.display = "none";
			this.close.style.display = "none";
			this.open.style.display = "inline";
		}
	},
	load: function() {
		var url = $X("string(descendant::a[starts-with(@href, '/entry/')]/@href)", this.node).value();
		GM_xmlhttpRequest({
			method: "GET",
			url: "http://b.hatena.ne.jp"+url,
			onload: bind(this.loadCallback, this)
		});
	},
	loadCallback: function(result) {
		var match = result.responseText.match(this.targetRegExp);
		if (match) {
			var sandbox = document.createElement("div");
			sandbox.innerHTML = match[0].replace(this.target,"");
			this.tree = sandbox.firstChild;
		} else {
			this.tree = document.createElement("ul");
		}
		this.append();
		this.loading.style.display = "none";
		this.close.style.display = "inline";
	},
	append: function() {
		this.tree.style.backgroundColor = "transparent";
		this.tree.style.listStyleType = "circle";
		this.node.appendChild(this.tree);
		$X("li", this.tree).each(function(n) {
			var a = $X("a",n).node();
			var c = $X("count(//li/a[@href='"+a.href+"'])").value();
			if (c > 1) n.parentNode.removeChild(n);
		});
		$X("li", this.tree).each(bind(function(node){new this.constructor(node)}, this));
	},
	rootAppend: function() {
		$X(this.targetXPath).each(bind(function(node){new this.constructor(node)}, this));
	}
};

function similar(node) {
	this.node = node;
	this.create();
}
similar.prototype = new HBTM("similar_entries");
similar.prototype.constructor = similar;

function referred(node) {
	this.node = node;
	this.create();
}
referred.prototype = new HBTM("referred_entries");
referred.prototype.constructor = referred;

function loadBookmarkCommentViewer() {
	var head = document.getElementsByTagName("head")[0];
	var script = document.createElement("script");
	script.type = "text/javascript";
	script.src = "http://b.hatena.ne.jp/js/BookmarkCommentViewerAllInOne.1.2.js";
	head.appendChild(script);
	var css = document.createElement("link");
	css.rel="stylesheet";
	css.href="http://d.hatena.ne.jp/css/base.css";
	css.type="text/css";
	css.media="all";
	head.insertBefore(css, head.firstChild);
	window.addEventListener("load",function(){
		var BCV = unsafeWindow.BookmarkCommentViewer;
		BCV.options['screenshot'] = true;
		var asyncCommnetView = BCV.asyncCommnetView;
		BCV.asyncCommnetView = function(url, onCompleteCallback) {
			var div = asyncCommnetView(url, function(){
				onCompleteCallback.apply(this, arguments);
				new unsafeWindow.Ten.XHR("http://b.hatena.ne.jp/entry/rss/"+url, {}, function(result) {
					if (! result.responseText.match(/<description>(.*?)<\/description>/))
						return;
					if (! RegExp.$1)
						return;
//					var desc = document.createTextNode("desc: "+RegExp.$1);
					var desc = document.createElement("li");
					desc.appendChild(document.createTextNode("desc: "+RegExp.$1));
					div.lastChild.insertBefore(desc,div.lastChild.getElementsByTagName("li")[0]);
				});
			});
			return div;
		};
		BCV.asyncCommnetView.origin = asyncCommnetView;
	}, false);
}

function bind(f,o) {return function() {return f.apply(o, arguments)}}

function $X(xpath, context) {
	if (!(this instanceof $X))
		return new $X(xpath, context);
	this.xpath = xpath;
	this.context = context || document;
}
$X.prototype = {
	evaluate: function() {
		var result = document.evaluate(this.xpath, this.context, null, this.type, null);
		switch (result.resultType) {
			case XPathResult.STRING_TYPE : return result.stringValue;
			case XPathResult.NUMBER_TYPE : return result.numberValue;
			case XPathResult.BOOLEAN_TYPE: return result.booleanValue;
			case XPathResult.FIRST_ORDERED_NODE_TYPE: return result.singleNodeValue;
		}
		return result;
	},
	node: function() {
		this.type = XPathResult.FIRST_ORDERED_NODE_TYPE;
		return this.evaluate();
	},
	value: function() {
		this.type = XPathResult.ANY_TYPE;
		return this.evaluate();
	},
	each: function(func) {
		this.type = XPathResult.ORDERED_NODE_SNAPSHOT_TYPE;
		var result = this.evaluate();
		for (var i=0; i<result.snapshotLength; i++)
			func(result.snapshotItem(i));
	}
};

main();

})();

2008-06-27

[][][]文字列char*をキーにするのなら、気をつけたいこと

http://www.sgi.com/tech/stl/Map.html

stlmapクラスtree継承してるようなしてないような。

それはともかく、文字列をキーにしている場合、文字列を比較するための処理を定義してやらないといけない。

map<char*, object*, COMPARE> hogehoge;

もし、

map<char*, object*> hogehoge;

としてしまうと、キーは文字列ではなく、文字列アドレスになってしまう。

、、、string使えばいいのか。

ログイン ユーザー登録
ようこそ ゲスト さん