日本野望の会 » software http://yabooo.org いずれにせよITで世界征服をたくらむ悪の組織です。 Mon, 28 Dec 2009 14:30:41 +0000 http://wordpress.org/?v=2.8.3 ja hourly 1 プログラマのための英文法(笑) http://yabooo.org/archives/61 http://yabooo.org/archives/61#comments Sun, 03 Feb 2008 19:17:36 +0000 http://www.yabooo.org/archives/61
再びちょっとしたネタ記事。

皆さん英語は好きですか?僕は嫌いです。
英語の勉強は覚えるとかばっかりで理解を促してくれません。

こんな英文があります。

Reading is to the mind what food is to the body.
(たべものが体にとって大事なように読書も精神にとって大事である。)

いわゆる、A is to B what C is to D.の構文なんですが、
これをそのまま覚えるのって苦行ですよね。

苦行は嫌いなので、論理的に覚えたいと思います。

SVCM構文のルール:(例外はあるけど暫定的に)
1.SVCMを名詞相当句にするにはS|Cのうち、欠けている物を関係詞whatで補い前置する。
2.CとMはCが長くなると逆転しSVMCにしてもよい。
3.Cには名詞相当句が入る

ここで、
a is ** to b(bにとってaは**だ。)---(1)
c is ** to d(dにとってcは**だ。)---(2)
を考える。

ルール1により、(2)を名詞相当句にする。
what c is to d ---(3)
ルール3により、(1)のCに(3)を代入。
a is what c is to d to b. ---(4)
ルール2に(4)を変形
a is to b what c is to d.

とこんな感じのルールで動いています。

これをJavaScriptのプログラムにしてみると、

var SVCM=function(obj){
    this.S=(obj.S)?obj.S:"**";
    this.V=(obj.V)?obj.V:"**";
    this.C=(obj.C)?obj.C:"**";
    this.M=(obj.M)?obj.M:"";
    this.order=["S","V","C","M"];
    this.sentence=true;
};

SVCM.prototype={
    nominalize:function(where){
		this[where]="what";
		this.sentence=false;
		var ord=[where];
		for(var i=0;this.order.length-i>0;i++){
			var e=this.order[i];
			if(e!=where)ord.push(e);
		}
		this.order=ord;
		return this;
    },
    toString:function(){
		var ret=[];
		for(var i=0;this.order.length-i>0;i++){
			ret.push(this[this.order[i]]);
		}
		return ret.join(" ")+((this.sentence)?".":"");
    },
    inverse:function(){
    	var posC,posM;
		for(var i=0;this.order.length-i>0;i++){
			var e=this.order[i];
			if(e=="C"){	posC=i;}
			if(e=="M"){	posM=i;}
		}
		this.order[posC]="M";
		this.order[posM]="C";
		return this;
    }
}

var s1=new SVCM({S:"A",V:"is",M:"to B"});
log(s1);
var s2=new SVCM({S:"C",V:"is",M:"to D"});
log(s2);
s1.C=s2.nominalize("C");
log(s1);
log(s1.inverse());
	

これを少し、発展させて新ルールを追加しましょう。

SVCM構文のルール:(例外はあるけど暫定的に)
4.SVMC文を修飾語相当句にするにはwith SCMとする。

というルールを追加してみましょう。

SVCM.prototype.modifier=function(){
	if(this.sentence){
		this.sentence=false;
		this.P="with";
		var ord=["P"];
		for(var i=0;this.order.length-i>0;i++){
			var e=this.order[i];
			if(e!="V")ord.push(e);
		}
		this.order=ord;
		return this;
	}
	return false;
}
	

このルールによって、文全体を修飾語として扱うことができます。
すこし実験をして見ましょう。

log("--簡易テスト--");
var sen1=new SVCM({S:"A",V:"is",C:"happy"});
log(sen1);
log(sen1.modifier());
log("--He can't be alive with the earth what it is.--");

var e1=new SVCM({S:"it",V:"is"});
var e2=new SVCM({S:"He",V:"can't be",C:"alive"});
var e3=new SVCM({S:"the earth",V:"is"});
log(e1);log(e2);log(e3);
log(e1.nominalize("C"));
e3.C=e1;
log(e3);
log(e3.modifier());
e2.M=e3;
log(e2);
log("-(地球がこのような有様では、彼は生きてはいないだろう)-")
	

どうでしょうか。
3つの文が、要素を変形させて1つの文になっていくさまがわかると思います。

このように教えてくれれば、英語に苦手意識を持つ必要がなかったのに・・・><

]]>
http://yabooo.org/archives/61/feed 0
FizzBuzzはもう古い!世界のナベアツ問題。 http://yabooo.org/archives/60 http://yabooo.org/archives/60#comments Fri, 01 Feb 2008 16:13:50 +0000 http://www.yabooo.org/archives/60
ネタ記事ですが、いろいろな実装が見たいので。

有名なプログラムでの問題にFizz Buzz問題というのがあります。
これは、

最初のプレイヤーは「1」と数字を発言する。次のプレイヤーは直前のプレイヤーの次の数字を発言していく。ただし、3で割り切れる場合は 「Fizz」(Bizz Buzz の場合は 「Bizz」)、5で割り切れる場合は 「Buzz」、両者で割り切れる場合は 「Fizz Buzz」 (Bizz Buzz の場合は 「Bizz Buzz」)を数の代わりに発言しなければならない。発言を間違えた者やためらった者は脱落となる。

という、牛タンゲームの簡単なやつみたいなものです。

これに似たことをする芸人さんがいます。

それが「世界のナベアツ」ことジャリズムの渡辺鐘(わたなべあつむ)です。
彼のネタの中で。

「3の倍数と3の付く数字だけアホになり、8の倍数だけ気持ち良くなります」

という天才としか言いようの無いネタがあります。これをプログラムにしてみましょう。

まずはFizzBuzz問題のほうから、

var i=0;
var comments=["","Buzz","Fizz"];
comments.push(comments[2]+comments[1]);
var id=setInterval(function(){
	var flag=0;
	flag|=(i%3==0);
	flag*=2;
	flag|=(i%5==0);
	log((flag>0)?comments[flag]:i);
	i++;
	if(i>100){clearInterval(id);}
},10);

こんな感じです。
ここでは2、3分でやれ

と書いてあるので最初に思いついたやりかたをしてみました。

これをナベアツ問題のほうに書き直すとこんな感じ。

var i=0;
var suffix=["","ぅぅういえぇえあ","~~~"];
suffix.push(suffix[2]+suffix[1]);
var id=setInterval(function(){

	var flag=0;
	flag|=i.toString().match(/3/)?1:(i%3==0);
	flag*=2;
	flag|=(i%8==0);
	log(i+suffix[flag]);
	i++;
	if(i>40){clearInterval(id);}
},10);

だいたい同じような問題です。
ですが、気持ちよくなる方法やアホになる方法などを工夫してみたり、
toStringのような文字列処理を無しでやってみるなど条件設定の付け概のある問題だとおもいます。

みなさんのいろんな実装お待ちしてますw

]]>
http://yabooo.org/archives/60/feed 6
コンピュータって0と1だけなんだよね。 http://yabooo.org/archives/58 http://yabooo.org/archives/58#comments Thu, 31 Jan 2008 06:23:32 +0000 http://www.yabooo.org/archives/58 どうも、野望ブログを書いてくれる人がいなくて寂しいひろきのだいちです。
誰か手伝って><

えっと情報系の学部に入るとなにやらC言語というプログラム言語をいじらされることがあるかと思います。
そんで、なんかccなりgccなりとかをコマンドとしてうたされて、「a.outってやるといいよ。」みたいなことをいろんな人から言われ、そんなもんなのかーって思ってよくわかんねーなって、感じになってしまい、プログラム怖いみたいなことになってしまうこともあるように思います。

なので、映画とかなんとなくの情報で、コンピュータって0と1だけで動くんだぜ、みたいな知識はあるのに、
C言語は0と1じゃないし、よくわからんって人のためにコンピュータって0と1だけなんだなぁということをわかってもらうための記事を書きます。

たとえば、C言語でこんなプログラムを書いたとします。

  #include<stdio.h>
    void main(){
        int b;
        b=10
        printf("%d",b);
    }

これは「人間が理解できるように」「人間がプログラムを書きやすいように。」ということを目的に作られたプログラム言語ってやつなんですが、
これを「コンパイル」(ぷよぷよの会社じゃないよ)という動作で「機械がよめる01のデータ」に直します。

人間が読めなくなってしまったデータはバイナリといいます。
コロスケがコロッケが2個から4個に増えて喜んだときにも「バイナリ~♪」といいますが
それとは関係なく「2進数の」という意味です。

これを16進数に置き換えて中身をみてみると

    00 B8 CC CC CC CC F3 AB C7 45 FC 0A 00 00
    00 C7 45 F8 14 00 00 00 8B 45 FC 03 45 F8・・・・・・

こんなかんじになっています。
まぁ、なんだかわかりませんよねw

なんだかわからないけど、もしこの中身を適当に書き換えちゃうと機械が読めなくなるので動作しなくなっちゃうわけです。

「機械が読めるように書き換えたら?」

そうしたら、C言語という人間がわかる言語を介さなくてもコンピュータに計算を動作させることができるようになるわけです。
というわけでやってみましょう。

    void main(){
        int a;
        int b;
        a=10;
        b=20;
        b=a+b;
        b=a-b;//ココを
        printf("%d",b);
    }

このようなプログラムを、

    void main(){
        int a;
        int b;
        a=10;
        b=20;
        b=a+b;
        b=a+b;//こうする
        printf("%d",b);
    }

このようにしたいと思ったときに、バイナリを書き換えて変更することを考えて見ましょう。

自力で、main関数があるところを探してもいいのですが面倒なので、
目印を入れておきましょう。

    void main(){
        int a;
        int b;
        a=10;
        b=20;
        b=a+b;
        b=a-b;
	//ここに目印を入れておく。
        __asm{
            nop;
            nop;
            nop;
            nop;
            nop;
            nop;
        }
	//何もしない命令をいっぱい入れておく
        printf("%d",b);
    }

__asmから始まるなんかわからない部分が追加されてますが、
気にしないでください・・・・

とはいえ、気になるので説明します。
僕は、プログラムを書くときに「これはおまじない」といわれるのが嫌いなんです。

学校の先生が「おまじないだよ。」というのを耳にしたら、それは半分は職務怠慢だと思ってください。

CPUというコンピュータの内部で計算をしている一番えらい(熱い)機械は、01の塊になったプログラムを渡されるとそれを数個ずつ塊で持ってきて、塊ごとにきまった動作をしてくれる熱いやつです。

この決まった動作ごとに割り当てられた命令を機械語といいます。
機械語にはニーモニックという名前が付いていて、それを「アセンブリ」といいます。(ちょっと違うかもしれないけどこんなかんじ。)

C言語はそれよりももっと複雑に人間にわかるような書き方に変えているので「高級言語」といいます。

__asm{}というブロックの中にはこのアセンブリ言語をそのままかいていいですよ。というふうにコンパイラにお願いする部分です。

そのなかにnopという「何もしないでね」という命令を書き込んでおいたわけです。

nopというニーモニックは、機械語としては16進数で90というのに書き換えられます。これはCPUごとに違うのですが今回の場合はそうでした。

ということは__asmの中身はコンパイルすると

    nop :90
    nop :90
    nop :90
    nop :90
    nop :90
    nop :90

と展開されるということです。

と言うことは・・・・コンパイルされた実行ファイルの中にも
90 90 90 90 90 90という列が存在するはず。

そしてそのあたりがよくわからんけど、
実行ファイルの中のmain関数の最後あたりなんだろーなぁー。

というあたりがつきます。

なので、
バイナリエディタから検索してその位置を確認します。

そして、この90 90 90 90 90 90の直前に

b=b-aが
機械語として展開されているはず!!

そしてその動作がどのようになるかというと、

    1.レジスタにbを入れる
    2.レジスタとaを引き算する
    3.bにレジスタを写す。

こんな感じになります。

いきなり出てきたけど、レジスタってなんだ!!バカ野郎!いい加減にしやがれ!このFXXXやろうが!

と思われるかもしれないので、説明すると
普通プログラムと言うのは、最初作られたときには
ハードディスクという機械の中に入っています。
これは大容量ですが、ちょっとよく使うデータにとっては遅いです。

これを実行するときにメモリという機械にこのプログラムを入れておきます。
メモリは比較的早く読み書きできるので便利です。

ところがCPUっていう熱い機械は、メモリのデータを直接計算することができないのです。

そのかわりレジスタというメモリよりももっと早く読み書きできてしかも計算できるところをちょっとだけ持ってます。

なので、計算するときは一度レジスタに入れてから計算します。

そしてそれぞれが、16進数で2桁(この単位をバイトといいます)×3ずつの命令の長さを持っていて、

    1.(レジスタに入れろ)[Bを]
    2.(レジスタと引き算しろ)[Aを]
    3.(レジスタをメモリに戻せ)[Bに]。

という感じになっていて、

    (**)[** **](sub)[ ** **]
    (**)[** **]90 90 90 90 90 90

こんな風に分けられているので、
このsubという引き算の部分をadd(03)に書き換えて足し算にかえてしまえば
いいということがわかります。

書き換えた結果が
これ↓
binary.gif
そして、
実行してみると・・・

    %assembly1 -20
    %assembly2 40

わお。

ちゃんと書き換えられてますね。

やっぱりコンピュータって01で動いているんだなぁということが
わかりました。

それじゃ、また。

]]>
http://yabooo.org/archives/58/feed 0