Hatena::ブログ(Diary)

hogeなlog

プロフィール

hogelog

hogelog

小室 直(こむろ すなお)。電気通信大学2003年入学。2010年修士卒業。プログラミングとかしてます。

カレンダー
1984 | 01 |
2006 | 07 | 08 | 09 | 10 | 11 | 12 |
2007 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2008 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2009 | 01 | 02 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 |
2010 | 01 | 06 | 08 | 09 | 10 | 11 | 12 |
2011 | 01 | 02 | 03 | 05 | 08 | 09 | 10 | 12 |
2012 | 01 | 04 | 06 |

November 27(Tue), 2007

[] あなたが一番好きなアルゴリズムを教えてください

http://q.hatena.ne.jp/1195950564

「俺様このアルゴリズムだったらご飯3杯は食えるな!!!」というようなアルゴリズムは無いけど、お題を見て浮かんだのはダイクストラのアルゴリズム。人工無脳を作ろうと試みたときに必要になって学んだ。自発的に必要性を感じ、そして実装した最初のアルゴリズムらしいアルゴリズムだったかもしれない。後に大学のアルゴリズムの講義を受けたときに理解が間違ってたことに気付いたりもした。そんなこんなが、やっぱり楽しかったダイクストラ法かな。

アルゴリズムじゃないけど、同様の理由でN-gramモデルもなんか好き。これは無脳つくるとき「自然言語処理」を読んで理解したもの。あの本は良著。ぶ厚いのは丁寧に書いてるからで、むしろ初心者にはとても良い本だと思う。

岩波講座 ソフトウェア科学〈〔知識〕15〉自然言語処理

岩波講座 ソフトウェア科学〈〔知識〕15〉自然言語処理

CS分野に興味を持ったのは、圧縮技術全般のせいだと思う。ちいさくなるのが、ふしぎでしょうがなかった。

[][] ComSys2007

わすれてた。いってきましたComSys2007初日。わすれるな。

ポスターセッションやってたParier Mobile: les Meilleurs Applications Paris Sportifsがすごく楽しそうだった。ポスターセッションは敷居低く色々聞けて楽しいなあ思った。

なんだか見たことのある人が多かった。意外とこの世界狭いのだろうか。活発な方があちこちに顔を出すってだけかも。ComSysは参加費が高いせいか、俺みたいな一見さんはあんまりいなそうだった。[ほげほげ]研究会あたりだともっと一見さんくさいのが多かった気がする。

帰りは顔見知りの人たちと一緒にだったけど、途中新宿駅にて帰宅ラッシュの人達に揉まれながらぼんやりしてたら普通にはぐれた。もしも待たせたりしてたらすいませんでした。しかもそのときそこが新宿駅だとわかってなかったのでしばらくフラフラしてた。

急にバイト先で食いさしの状態で残してきたレモンマシュマロ食いたくなった。もう生き残っていないでしょうきっと。

snegishisnegishi 2007/11/28 01:45 生き残っているよ。

hogeloghogelog 2007/12/02 20:49 俺が出社するとあわれあっという間に儚い命を散らしたマシュマロさんでした。

November 25(Sun), 2007

[] 私的Twitterたのしみかた

リア充トークをしたがるid:hayamizさん(@hayamizu)に酔っぱらったあろはさん(@alohakun)がクダまいてたりしてておもしろい。

[] 電通大大学祭期間

オープンキャンパスもやってた。あちこちの研究室に首つっこみまくってきた。なんかたまに解説してくれる学生さんとか困らせながら。違う学科とか覗くのも楽しかった。これなら他大の研究室とか覗くのも割と楽しそうだ。チャンスあれば色々見てこよう。なんなら高校生のふりして。それは厳しいかも。

[] さいきん

プログラム書くのはともかく、あんまし読んでないのが良くない。書く方もバイトにかまけて、たぶんちょっと減ってる。ああああコードガリガリ書きたい! けど今はレポートを仕上げなければいけない。にきとか書いてねーで早くレポート仕上げれ。

トラックバック - http://d.hatena.ne.jp/hogelog/20071125

November 23(Fri), 2007

[][] MinIPS*1のアセンブラっぽいなにか

D言語(しかもDMD2.007以降でしかコンパイルできない。それ以降でもコンパイルできるか保証は無い)で書いたMinIPS(電通大情報工学科にて使われてる教育用プロセッサ)のアセンブラとか、範囲限定され過ぎだろと思った。なのでlex/yacc使って書き直してみました。

とりあえずWindowsバイナリこの辺 http://konbu.s13.xrea.com/lib/minika.exe

なんかまあ標準入力で受けて標準出力に吐きます。出力は相変わらず16進数表現のマシン語列です。

% make
yacc -d -y minika.y
lex -I minika.l
mv y.tab.c minika.c
cc lex.yy.c minika.c optable.h -ll -o minika
% cat hoge.s
add $1, $2, $3
sub $1, $2, $3
nop
bne $1, $0, 10h
beq $1, $0, -2
% ./minika <hoge.s
00430820
00430822
00000000
14010010
1001FFFE

ねむい。以下コード。

続きを読む

トラックバック - http://d.hatena.ne.jp/hogelog/20071123

November 22(Thu), 2007

[][] 整数を2進数表示。桁数も指定で。

なんか必要になる度に書いてるのでメモ。真が1になるのって、規格で決まってたかなあ。後でJIS X 3010ながめる。

void printBin(unsigned int val, int len)
{
  for(;len>0;--len){
    int x = (val&((1<<len-1))) != 0;
    putchar('0'+x);
  }
}

[][][] lex/yaccなソレ使ってMinIPS*1アセンブラぽいの

lex/yacc使ってアセンブラぽいの書けそう。とりあえずアセンブリプログラムを入力として、MinIPSマシン語を2進数で吐かせてみた。

% flex -I asm.l
% bison -d -y asm.y
% gcc lex.yy.c y.tab.c -lfl -o minasm
% ./minasm
add $1, $2, $3; add instruction
sub $2, $2, $3; hoge hoge hoge
j 10h
jr $5
00000000010000110000100000100000
00000000010000110001000000100010
00001000000000000000000000010000
00000000101000000000000000001000

lex/yaccなインターフェース、慣れるとわりと楽かも。

続きを読む

トラックバック - http://d.hatena.ne.jp/hogelog/20071122

November 19(Mon), 2007

[] flex/bison テスト

構文解析って、手書きかnotavaCCでしかやったこと無い。なので一度lex/yaccなものをいじるべきだと思った。

とりあえず電卓づくり。

flexドキュメントの例ほぼそのまま。 http://www.asahi-net.or.jp/~wg5k-ickw/html/online/flex-2.5.4/flex_6.html#SEC32

整数だけの計算のときは整数演算するようにしてみた。そんだけ。

% flex -I expr.l
% bison -d -y expr.y
% gcc y.tab.c lex.yy.c -lfl
% ./a.out
3.
3.000000
% ./a.out
3+3*2-1
8
3+3*2-0.1
8.900000
1+2+(3.0+4.0)-5
5.000000
/**
* expr.l
**/
%{
#include "y.tab.h"
%}

%%

[0-9]+     {
             yylval.ival = atof(yytext);
             return(INTEGER);
           }
[0-9]+\.[0-9]* {
             sscanf(yytext,"%f",&yylval.fval);
             return(FLOAT);
           }
"+"        return(PLUS);
"-"        return(MINUS);
"*"        return(MULT);
"/"        return(DIV);
"("        return(LB);
")"        return(RB);
\n         return(EOL);
.          {
             yyerror("Illegal character");
             return(EOL);
           }
%%
/**
* expr.y
**/
%{
#include <stdio.h>
%}

%union {
   int ival;
   float fval;
}

%token INTEGER FLOAT
%token PLUS MINUS MULT DIV
%token EOL
%token LB RB

%left  MINUS PLUS
%left  MULT DIV

%type  <ival> ival INTEGER
%type  <fval> fval FLOAT

%%
input   :
        | input line
        ;

line    : EOL
        | ival EOL { printf("%d\n",$1);}
        | fval EOL { printf("%f\n",$1);}
        ;

fval    : FLOAT { $$ = $1;}
        | fval PLUS fval { $$ = $1 + $3;}
        | fval PLUS ival { $$ = $1 + $3;}
        | ival PLUS fval { $$ = $1 + $3;}
        | fval MINUS fval { $$ = $1 - $3;}
        | fval MINUS ival { $$ = $1 - $3;}
        | ival MINUS fval { $$ = $1 - $3;}
        | fval MULT fval { $$ = $1 * $3;}
        | fval MULT ival { $$ = $1 * $3;}
        | ival MULT fval { $$ = $1 * $3;}
        | fval DIV fval { $$ = $1 / $3;}
        | fval DIV ival { $$ = $1 / $3;}
        | ival DIV fval { $$ = $1 / $3;}
        | MINUS fval %prec MINUS { $$ = -$2;}
        | LB fval RB              { $$ = $2;}
        ;
ival    : INTEGER { $$ = $1;}
        | ival PLUS ival { $$ = $1 + $3;}
        | ival MINUS ival { $$ = $1 - $3;}
        | ival MULT ival { $$ = $1 * $3;}
        | ival DIV ival { $$ = $1 / $3;}
        | MINUS ival %prec MINUS { $$ = -$2;}
        | LB ival RB              { $$ = $2;}
        ;
%%

int yyerror(const char *s)
{
  fprintf(stderr, "%s\n", s);
}

int main()
{
  yyparse();
}
トラックバック - http://d.hatena.ne.jp/hogelog/20071119

November 17(Sat), 2007

[] 休日

いつぞ書いたあほhttpdのコードを縮めていた。

ちゃんと終了しない悪い人。127.0.0.1:9999とかで繋げる。

use IO::Socket;$SIG{CHLD}=sub{wait};for($s=new IO::Socket::INET(
LocalPort,9999,Listen,5,Reuse,1);$c=$s->accept;){if(!($p=fork)){while(
<$c>){if(/GET \/(\S+\.(\S+))/){open F,$1;read F,$d,-s$1;print$c
"HTTP/1.0 200 OK\nContent-Type: ",$2=="html"?"text":"image","/$2\n\n";
print$c $d}}}}

どうかくorgに投稿した

先日、いいかげんに書いたMinIPSアセンブラをlex/yaccあたり使って書こうと思ってたところにちょうどいいお題があったので。

brainf*ck -> Cコンパイラをlexで書いた http://ja.doukaku.org/comment/4154/

コメント欄間違えた。

OCamlとたわむれてた

# let rec (^) a b = match b with 0 -> 1 | _ -> a * (a ^ (b-1));;
val ( ^ ) : int -> int -> int = <fun>
# 2^10;;
- : int = 1024

これは楽しい。たぶんあんまし使わんけど。

そんな日。なんか最近は割と本当に「趣味: プログラミング」な人になってきた。最近小説もあんまし読んでねえし。プログラミングとかの本読んでることのが多いくらいだ。

俺に足りないものがわかった!

趣味グラマならば、一度はゲームを自作しなくちゃいけない!!

トラックバック - http://d.hatena.ne.jp/hogelog/20071117

November 14(Wed), 2007

[] Parrotとたわむれる(2)くらい

すっかり忘れてましたけど、Parrotで遊びたかったのです。とりあえずよく覚えてないので復習。

PASMはParrotのアセンブリ言語。Parrotの命令と一対一で対応する。PIRはParrotの中間表現。低レイヤーのPASMと上位レイヤーの言語の間に位置する。PASMよりいくらか人間向け。

というわけでPIRでcatプログラム書いてみる。引数無しで標準入力を、引数があればそうして渡されたファイルを標準出力に。

% parrot cat.pir cat.pir
.sub main
  .local int argnum
  .local pmc args, input
  .local string file, line
  get_params '(0)', args
  argnum = 1
  file = args[argnum]
  if file goto OPENFILE
STDIN:
  getstdin input
LOOP1:
  readline line, input
  print line
  if line goto LOOP1
  close input
  inc argnum
  file = args[argnum]
  unless file goto END
OPENFILE:
  open input, file, "<"
  if input goto LOOP1
  print "can't open "
  print file
  print "\n"
END:
.end

このようにparrotコマンドからごく普通のスクリプトであるかのように呼ぶこともできる。また、バイトコンパイルもできる。

% parrot -o cat.pbc cat.pir
% parrot cat.pbc cat.pir
.sub main
  .local int argnum
  .local pmc args, input
...

アセンブルもできます。何故かぶっこわれたPASMを出力するらしいですが。

% parrot -o cat.pasm cat.pir
% parrot cat.pir cat.pasm
# IMCC does produce b0rken PASM files
# see http://guest@rt.perl.org/rt3/Ticket/Display.html?id=32392
main:
        get_params
        set I0, 1
        set S1, P1[I0]
        if S1, OPENFILE
STDIN:
        getstdin P0
LOOP1:
        readline S0, P0
        print S0
        if S0, LOOP1
        close P0
        inc I0
        set S1, P1[I0]
        unless S1, END
OPENFILE:
        open P0, S1, "<"
        if P0, LOOP1
        print "can't open "
        print S1
        print "\n"
END:
        set_returns
        returncc

ネイティブコードまで落として、JITがどうこうなこともできるらしいけど、よくわからん。バイトコードからELFコードを吐ける。

% parrot -o cat.o cat.pbc
% objdump -S cat.o
cat.o:     file format elf32-i386

Disassembly of section .text:

00000000 <run_compiled>:
   0:   55                      push   %ebp
   1:   89 e5                   mov    %esp,%ebp
   3:   d9 2d 00 34 ef b7       fldcw  0xb7ef3400
   9:   53                      push   %ebx
   a:   56                      push   %esi
   b:   57                      push   %edi
   c:   8b 45 08                mov    0x8(%ebp),%eax
...
トラックバック - http://d.hatena.ne.jp/hogelog/20071114

November 13(Tue), 2007

[] 留年系男子の取扱

てきとうに「なんで留年するの? 死ぬの?」とか言ってやればいいと思います。人によっては「なんで留年しないの?」などと意味不明なことを聞きかえしてきたりするかもしれません。一部には「俺にとってこの頃の挫折とその副次的な結果としての留年は無駄にはなってないよ」などと開きなおる人もいるかもしれません。それ俺。

別に注意して取り扱う必要とか無いんじゃないですかね。

俺は

大学入学以前の、せーせきトップクラスにいたプライド(笑)なんて、そういやそんなもんあったっけか程度の話だな。そもそもおれせーせきトップクラスだったけか? たぶん微妙に違うな。

てゆーか、順位を付ければそりゃ1番からビリまでいるのは当たり前のことで。しかも競ってるのが教育課程に定められたお勉強の点数がとか別に、なあ。と思っていたような。

高校までの勉強は、実際使うときってのが遠く感じてきつかったな。「勉強やったからってなんの役にたつの?」などとスポンジのようなことはもちろん思ってなかったけど。楽しくなかったわけではないが、どうもパズル的な楽しみ程度しかなかった気がする。

大学でやる勉強、特に専門性が増してきた最近はとても楽しい。そこで得る知見がどう役にたつか簡単に想像できたりする。むしろそれらの知識は必須だと実感できたりもする。留年スパイラルから抜け出てからこっち、そんなこんなで大学で学ぶことがとても楽しい。

でなんで留年するの?

まあまわりの留年生とか見てると、大学に来る理由を馬鹿正直に「学ぶこと」と捉えてる人が多い気がする。なんか「卒業すること」じゃないんだよね。「単位」のために教官に頭下げに行くとか、知り合いのレポート丸写しするとか、そういうことをせずにいさぎよく留年していったりする。チャラチャラ遊びまくりで「留年確定してサーセン」な人はまわりにいないから知んない。

なんか

はてなに自分語り書いたの久しぶりじゃないかな。まあ別に書かんでいいことだったな。何を言いたいんだか俺にもわからん。

プライドの破壊

そういえばプライドというか、妙ちきりんな自意識の塊はあったな。それがぶっとんだのは留年しまくってる頃か。俺は個人的にはレッドゾーンにつっこむのは大学生がいいと思う。色々とちょうどいい頃な気がすんだよなー。たぶん留年はしちゃうだろうけど。「もう卒業とか絶対無理だから早くやめなきゃ」とか思うかもしれませんけど。そこは踏みとどまって休学にしておくと、もしかするとそのうち「大学うめぇwww」ってなるかもしれません。保証とかはありません。

トラックバック - http://d.hatena.ne.jp/hogelog/20071113

November 12(Mon), 2007

[] みにかできた

正式名称「MinIPSアセンブラもどき以前の何か」。こういう名前つけるの好きな自分再確認。ついでにpre alpha 1とかいうバージョン情報付けといたら、いいかげんにしろって感じですね。

まあ実際その程度のことしかせんけど←こういう言い訳良くないね。

一応ディスアセンブルもできるようになったので一段落。次の実験までに作っときたかったからできて良かった。「OCamlとかもしくはC++で書きてえかも」との思いをぐっと押さえて、早くできそうな言語でやったのが良かったかな。Schemeあたりは悪くなかったかもしれんけど、実験に使うWindowsPCで動かすの面倒だし。

http://konbu.s13.xrea.com/lib/minika.exe

使い方は

minika.exe (asm|dsm) [input [output] ]

asmだとアセンブラ、dsmだとディスアセンブラっぽい動作。入力ファイルと出力ファイルは省略できます。その時はそれぞれ標準入力と標準出力に。

なんかアセンブルしてみる。

C:\hoge>cat hoge.s
lui $10, 65535
ori $1, $0, 1
ori $2, $0, 2
ori $3, $0, 3
sll $4, $1, 1
srl $4, $4, 1
beq $1, $4, 32
nop
srl $4, $2, 1
sll $4, $4, 1
beq $2, $4, 31

C:\hoge>minika asm hoge.s hoge.hex

C:\hoge>cat hoge.hex
3C0AFFFF
34010001
34020002
34030003
00012040
00042042
10810020
00000000
00022042
00042040
1082001F

なんか妙な32ビットデータの16進表記が吐かれてますね。

ちょうどいいのでディスアセンブルしてみます。

C:\hoge>minika dsm hoge.hex
lui $10, 65535
ori $1, $0, 1
ori $2, $0, 2
ori $3, $0, 3
sll $4, $1, 1
srl $4, $4, 1
beq $1, $4, 32
nop
srl $4, $2, 1
sll $4, $4, 1
beq $2, $4, 31

もとに戻せました。やったー。

なんで吐くのが文字列かと言うと、16進文字列のデータを大学のMinIPSプロセッサ実験で使うからです。TAの人が「こーやってこーやって命令表からこーしてあーして、16進文字列を計算して、プログラム書けるよー」と教えてくれたのですが、俺はそんなの手計算したくないです。

以下コード。やっぱりけっこうひどいコードだと思う。あきらかに設計とか何も考えずに書いてます。ちなみに完全DMD2.007より前ではコンパイルできないコードになりました。クロージャはよいですね。クロージャさえあればご飯三杯はいける。

続きを読む

トラックバック - http://d.hatena.ne.jp/hogelog/20071112

November 11(Sun), 2007

[] WindowsManager

すばらしい。困ったな、どんどんWindowsの居心地が良くなってくる。

[] クロージャてすと

import std.stdio;

int fill()
{
  int[100] x;
}
int delegate() mkcounter(int i)
{
  return {return i++;};
}
int main()
{
  int delegate() c1 = mkcounter(1);
  int delegate() c2 = mkcounter(3);
  writefln("%d", c1()); fill();
  writefln("%d", c2()); fill();
  writefln("%d", c1()); fill();
  writefln("%d", c2()); fill();
  writefln("%d", c1());
  return 0;
}

でコンパイルして、

C:\hoge\prg\WindowsManager>counter
1
3
2
4
3

あ、これありなら色々超楽になりそうな。

ヲルさまによる色々なテストコード http://www.digitalmars.com/webnews/newsgroups.php?art_group=digitalmars.D&article_id=61016

[] みにか

微調整。機能追加はしてない。

http://konbu.s13.xrea.com/lib/minipsm.exe

プログラムとかソースコードとかNYSL。

とかどうでもいいんだけど、あれだな。クロージャはやっぱりいいな。2.007を体験したらそれ以前のD言語には戻れない。(割と本気)

以下コード。だいぶましになった気がしたけど、今見るとそうでもなかった。変換テーブルを外部定義ファイルとか参照して色々できるようにするのが、カッコイイかな。

続きを読む

トラックバック - http://d.hatena.ne.jp/hogelog/20071111

November 10(Sat), 2007

[] フロッピーディスクドライブは大事だなあ

ノートPCを持ってるのですが、入ってるOSがWindows XPだったのです。そこはもうなんかLinuxか*BSDあたり入れたいですね。しかしこのPC、CDドライブぶっこわれてる。現代の若者らしく、もちろんFDDなぞありません。なのであきらめてWindows XPを使っていました。そしたらなんぞ、WindowsからDebian/Linuxをインストールできるというじゃないですか。これは良かね、と入れてみました。

が、まあなんかうまくいかんかった。なんか色々入らなかったりよくわからん反応をしたので、まず最小インストール。aptで入れてきゃよかろと、apt-getで適当に入れてたら駄目になった。xserver-xorgのpostinstallがほげほげとか。そこまではまあまだ良かったのですが。あれこれ試してるうちに、なんとsudoを削除してしまった。

えーと、rootユーザ作ってなかったんだけど。どうしろと。

幸いネットブートはできそうなんで、なんかTFTP鯖たててほげほげすれば、なんとかならんこともないのかなあ。あー、めどい。

[] MinIPSのアセンブラもどき以前の何か

「MinIPS(電気通信大学にてCPU教育用に用いられてるMIPSもどきプロセッサ)のアセンブラもどき以前の何か」略して「みか」を書きました。嘘です略しません。

http://konbu.s13.xrea.com/lib/minipsm.exe

何に使うかと言うと、たぶん電気通信大学電気通信学部情報工学科の情報工学実験プロセッサ課題をやるときです。使い方はこんな感じ。アセンブリプログラムを入力すると、16進数にアセンブルします。

C:\hoge>cat hoge.s
addi $1, $0, 100
add $1, $1, $1
sub $1,$2, $3
j 32

C:\hoge>minipsm asm hoge.s hoge.out

C:\hoge>cat hoge.out
20010064
00210820
00430822
08000020

C:\hoge>

あとまあ存在意味のわからん2<->16進数変換モードとかあります。Windowsの電卓とか使えばいいです。というかPerlだったらpack使ってワンライナーにできます。

C:\hoge>minipsm b2h
0000 1000 1100 1111
08CF
^Z

C:\hoge>minipsm h2b
ab10
1010 1011 0001 0000
^Z

C:\hoge>

引数与えずに呼びだすとusageじみたメッセージを出力します。

C:\hoge>minipsm
C:\hoge\minipsm.exe (asm|dsm|b2h|h2b) [input [output]]

「dsm」とか、いかにもディスアセンブルしそうですけど嘘です。つくってないからありません。

以下コード。無意味にD言語で書きました。しかもたぶん、DMD2.007じゃないと動かんような気もします。そうでもなかったかもしれません。

続きを読む

h_sakuraih_sakurai 2007/11/11 09:19 x86もこのくらい簡単な構成だといいのになぁ、思いました。
文字列操作でやると分かりやすいんですね。

hogeloghogelog 2007/11/11 20:03 命令がすごく少なくなってますけど、たぶん本物のMIPSでもこんなかんじにやってけると思います。大学のアセンブリの授業でもx86はやりませんね。アセンブリ言語はMIPSしか見たこと無かった頃、x86のcmp命令とかびっくりしました。

トラックバック - http://d.hatena.ne.jp/hogelog/20071110

November 09(Fri), 2007

[][] いろんな言語で簡単なプログラムを書いてみるテスト(1)

とりあえずC言語、D言語、Java、Scheme、Perl、OCaml、Rubyでcatプログラムを。引数で与えられたファイルを順番に標準出力に出力するやつ。仲間外れ一人。

訂正

コメントにも書きましたけど。本当はPerl以外は本来のcatとは違って、引数無かったときは即終了する子を書こうとしてました。でもDがdinをほげっててほげ。あとまあそれぞれのコードに色々ひどいところがあるのは、せっかくなので残しておきます。いちばんひどいのはRubyの子で、なんと開いたファイルを閉じていません。コメントで気付きました。ありがとうございます。

C

#include <stdio.h>
void cat(FILE *input)
{
  int c;
  while((c=fgetc(input))!=EOF){
    putchar(c);
  }
}
int main(int argc, char *argv[])
{
  if(argc>0){
    int i;
    for(i=1;i<argc;++i){
      FILE *input;
      if((input=fopen(argv[i], "r"))==NULL){
        perror("fopen");
        return 1;
      }
      cat(input);
      fclose(input);
    }
  }
  return 0;
}

D

import std.stream;
import std.cstream;
void cat(Stream input)
{
  char c;
  while((c=input.getc())!=char.init){
    dout.write(c);
  }
}
int main(string[] argv)
{
  if(argv.length == 1){
    cat(din);
  }
  else{
    for(int i=1;i<argv.length;++i){
      try{
        auto input = new BufferedFile(argv[i]);
        cat(input);
        input.close();
      }
      catch(StreamException){
        dout.writeLine("cannot read " ~ argv[i]);
        return 1;
      }
    }
  }
  return 0;
}

Java

import java.io.InputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;

class cat{
  public static void main(String[] args)
  {
    if(args.length > 0){
      for(String arg : args){
        try{
          InputStream is = new FileInputStream(arg);
          cat(is);
          is.close();
        }
        catch(FileNotFoundException fe){
          System.err.println("cannot find "+arg);
          System.exit(1);
        }
        catch(IOException ie){
          System.err.println("cannot read "+arg);
          System.exit(1);
        }
      }
    }
  }
  public static void cat(InputStream input) throws IOException
  {
    int c;
    while((c=input.read())!=-1){
      System.out.write(c);
    }
    System.out.flush();
  }
}

Scheme

(define (cat input)
  (letrec
    ((loop
       (lambda (c)
         (cond
           ((eof-object? c) 0)
           (else (write-char c) (loop (read-char input)))))))
    (loop (read-char input))))
(define (main args)
  (letrec
    ((loop
       (lambda (args)
         (cond
           ((null? args) 0)
           (else (call-with-input-file (car args) cat) (loop (cdr args)))))))
    (loop (cdr args))))

Perl

print<>

OCaml

open Pervasives
let cat file =
  let ic = open_in file in
  let rec iter () =
    begin
      try
        output_char stdout (input_char ic);
        iter ()
      with End_of_file ->
        flush stdout;
        close_in ic
    end
  in
  iter ();;
let _ =
  let rec iter n =
    if n = Array.length Sys.argv
    then ()
    else begin (cat Sys.argv.(n)); iter (n + 1) end in
  iter 1;;

Ruby

def cat(name)
  file = File.new(name, "r")
  while(c=file.getc)
    putc c
  end
end
ARGV.each{|f| cat f}

けっこう前に、ほんのちょっと触ったことあるだけだけど、調べつつ上のコード書いてみてRubyちょっといいかもなーと思った。

uskzuskz 2007/11/09 10:19 C++で書いてみましたが,特に面白いことは出来ませんでした・・・
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <functional>
#include <algorithm>
#include <boost/utility.hpp>

void cat(std::string const& filename)
{
 std::ifstream ifs(filename.c_str());
 if (ifs.good())
  std::cout << ifs.rdbuf();
}

int main(int argc, char* argv[])
{
 std::vector<std::string> args(argv, argv + argc);
 std::for_each(boost::next(args.begin()), args.end(), ::cat);
}

arikui1911arikui1911 2007/11/09 16:06 Ruby版にツッコミさせていただきます。

*fileがcloseされてない
リファレンスのTrap::IO非推奨とされています。そもそもFile.new自体あんまり使われなくて
File.open() do ... end
の形式で、ブロックでファイルのようなリソースを管理するのが一般的です。

*ARGF
そもそもRubyでも
print ARGF.read
の一行でおっけーです。ARGFはフィルタを書くのに便利ですよ。

hogeloghogelog 2007/11/09 19:16 >uskzさん
なんか頭のインクルードを見ると、このくらいでもスムーズに書けるようになるには割と時間かかりそうに見えます。
あとforeachとかそういうかっこよさげなパーツを忘却の彼方にやりまくってる自分にショックを受けました。

>arikuiさん
あー、眠くて駆け足でやったので忘れてました。File.newとかはたぶん、適当にぐぐって一番上にあったファイルの開き方を使ったのだと思います。
Rubyの落とし穴いいっすね。http://www.ruby-lang.org/ja/man/?cmd=view;name=Ruby%A4%CE%CD%EE%A4%C8%A4%B7%B7%EA
ARGFは良い情報感謝です。日常的なスクリプト書くとき、すごい楽になります。


本来のcatとは違う、引数に与えられたファイルだけ出力するコード書いたつもりだったのに、今見ると全然違うのが多数はいっててすいませんみたいな感じでした。(Perlだけは意図してましたけど)

そんなことをふまえて自己レスをすると
> C
> if(argc>0)
いみふめー

> D
if ... elseいらない。あとforeach(string arg; argv[1..$])のがカッコよくね!!?

> Java
ifいらない。

November 05(Mon), 2007

[][] D2.007でクロージャがやってきたよ

いたるところで話題になってますけどD2.007にしてようやくクロージャきたですよ。ダウンロードはChange Logから。

http://www.digitalmars.com/d/changelog.html

でまあクロージャ使ってBrainfuckインタプリタ書いてみました。前にクラスとか使ってそれっぽく書いたときよりずっとスッキリしました。

「クロージャ」とやらに対する俺の認識

「使えるとBrainfuckのインタプリタが楽に書けるよね!」

import std.stdio;
import std.string;

alias void delegate() Exp;
Exp[char] exptable;

Exp readblock(FILE* input)
{
  Exp[] block;
  int c;
  while((c=fgetc(input))!=EOF){
    if(c in exptable){
      block ~= exptable[c];
    }
    else if(c=='['){
      block ~= readblock(input);
    }
    else if(c==']'){
      return {while(mem[pt]){foreach(op ; block){op();}}};
    }
  }
  return {foreach(op ; block){op();}};
}

byte mem[30000];
int pt = 0;
int main(string[] args)
{
  exptable['+'] = {++mem[pt];};
  exptable['-'] = {--mem[pt];};
  exptable['>'] = {++pt;};
  exptable['<'] = {--pt;};
  exptable[','] = {mem[pt] = cast(byte)getchar();};
  exptable['.'] = {putchar(mem[pt]);};

  if(args.length!=2){
    writefln("%s input", args[0]);
    return 1;
  }
  FILE* input = fopen(args[1], "r");
  if(input is null){
    writefln("cannot open %s", args[1]);
    return 1;
  }
  Exp main = readblock(input);
  main();

  return 0;
}

ほんでC言語で色々書き方での速度比較してみたときのコードより速いという。

% dmd bfi_closure.d
gcc bfi_closure.o -o bfi_closure -m32 -Xlinker -L/mnt/data/dmd/bin/../lib -lphobos2 -lpthread -lm
% time (repeat 10 ./bfi_closure quine2.b >/dev/null)
0.632 user 0.024 system 0.657 total
% dmd -O bfi_closure.d
gcc bfi_closure.o -o bfi_closure -m32 -Xlinker -L/mnt/data/dmd/bin/../lib -lphobos2 -lpthread -lm
% time (repeat 10 ./bfi_closure quine2.b >/dev/null)
0.476 user 0.024 system 0.502 total

[][] ComSys2007 - SIGOS(jump)すげーいきてー

けど平日のそんな時間。ぐぎゃる。火曜だけなら行けなくもないけど。参加費\8000と、そんなに安くもないし半分だけ参加すんのもなー。学生会員なら\2000? 衝動的に情報処理学会会員申し込みしてしまったじゃないか。これには間に合わねーけど。

バイト始めたのでお金に超余裕あるつもりで使ってたけど、まだ給料出てねーからあっという間に金欠になってしまったんだよ今月は。阿呆め。誰か参加費ください。

うーん。どうしよう。水曜の午後は実験だから、流石に飛ばすわけにもいかねーんだよなー。

あれ? ちょっと待てよ。11/28(水)の実験?

第3ラウンド 11/28(水) 12/03(月) 12/10(月) 12/12(水) 12/17(月) 12/19(水) 01/07(月)

担当教員 課題内容

岩田 15パズルの解法

鈴木 Webアプリケーションの構築実習

大山 スプリプト言語プログラミング

...

http://jikken.cs.uec.ac.jp/jikken-a2.html

俺の割り当てはスプリプト言語プログラミング。そして

シンポジウム幹事:大山 恵弘(電気通信大学)

http://www.ipsj.or.jp/sig/os/ComSys2007

おんや? てことは11/28の実験は休講じゃん。っていうか担当教員がシンポジウムの方におられるではないですか。うわびっくりした。普通に日記書いてて気付いた。ってことは火曜も水曜もわりと行けそうだなあ。いいかも。バイト代も入ることだし、顔つっこんでみか。

(こうしてまだバイト代も発生してないのに強気になって金欠に)

トラックバック - http://d.hatena.ne.jp/hogelog/20071105

November 04(Sun), 2007

[] Vine Linux すてて Debian/Linux にしてみた

インストールディスクを1枚に収めるとか、普通にやってりゃ日本語設定になるとことか便利だったけど、パッケージの少なさとかアレだったのでDebianにしてみた。まあ、最近しばらくずっとVineだったこともあるし。

で、まあ変わってみたけどそんな変わらんかな。evilwmとscreenと日本語表示できる端末ありゃだいたいそりゃま。んなこと言うとUnix系だいたいおなじになるけど。パッケージ管理はVineと(ガワは)同じaptだし。ただこっちの本家aptにはapt-shellが無い。debianでも使いたいなー思ってぐぐってみりゃ、なんだこの結果。

http://www.google.com/search?q=apt-shell

え、もしかして誰も使ってないの?

あと今思ったけど、インストール直後からの使えっぷりはWindowsをとっくに凌駕してるな。この前バイト先でWindows XPいれたときなんて、やれドライバのインストールだWindows Updateだなんだ、再起動再起動再起動、「よし終わった!」思ったら「Windows XP SP2にしなさい」ほぎゃーUpdateじんわり再起動Windows Updateほげほげほげ。なんだ君はアレか。えーとまあうまい例えは思いつかなかったけどまあアレだアレ。

parrotだのsml/njだのなんだもaptから簡単に入れれるのは楽だなー思った。でもまあparrotとかその辺は結局後々手動で入れたりするような気もする。

トラックバック - http://d.hatena.ne.jp/hogelog/20071104

November 02(Fri), 2007

[] 割線法の実装

先週同様、数値計算な講義中にOCamlでの実装を書いた。

# let secant f x1 x2 stop =
  let delta xn1 xn2 = (f xn2) *. (xn2 -. xn1) /. ((f xn2) -. (f xn1)) in
  let stopcond = stop f delta in
  let rec iter xn1 xn2 = if (stopcond xn1 xn2) then xn2 else (iter xn2 (delta xn1 xn2)) in
  iter x1 x2;;
val secant :
  (float -> float) ->
  float ->
  float ->
  ((float -> float) -> (float -> float -> float) -> float -> float -> bool) ->
  float = <fun>
# secant (fun x -> x *. x -. 1.0) 0.0 2.0 (fun f delta x1 x2 -> (abs_float (delta x1 x2)) < 0.00001);;
- : float = 0.99999855887482747

やあ、なんだかこういうのは自然に書けていいかも。

[] 末尾再帰は?

% cat tail.php
<?php
  function loop(){
    static $count = 0;
    echo "loop ", ++$count, "\n";
    if($count<10000) loop();
  }
  loop();
?>
% php tail.php
loop 1
loop 2
...
loop 6155
loop zsh: segmentation fault  php tail.php

ですよねー。

% cat tail.pl
our $count = 0;
sub loop{
  print ++$count, "\n";
  loop();
}
loop();
% perl tail.pl
1
2
3
...
135752
135753
135754
...

perlさんはわりとやってくれるんだなあ。

[] ledit*1べんりだなあ

% ledit >hoge.pl
while(<>){
printf "%5d  $_", ++$i;
}
%

エディタとしてもわりと使える。

トラックバック - http://d.hatena.ne.jp/hogelog/20071102
最近のコメント
Connection: close