2010年4月4日日曜日

麻雀の待ち判定

http://www.itmedia.co.jp/enterprise/articles/1004/03/news002.html


泥臭い解き方。。これで2時間近くかかった。。。





use strict;
use warnings;

my %ret;

sub maj_splice {
my ($ps, $len) = @_;
my @w = @$ps;
my @cup = splice(@w, 0, $len);
my $cup = join "", @cup;
return (\@w, $cup);
}

sub search {
my ($p, $machi, $atama, $syun, $kou) = @_;

if (@$p) {
if (!$atama) {
if (!$machi) {
# 頭待ち
my ($w, $cup) = maj_splice($p, 1);
search($w, "[$cup]", 1, $syun, $kou);
}

if (1 < @$p && $p->[0] == $p->[1]) {
# 頭
my ($w, $cup) = maj_splice($p, 2);
search($w, $machi, 1, $syun, $kou."($cup)");
}
}

if (!$machi) {
if (1 < @$p && $p->[0] == $p->[1]) {
# 刻子待ち
my ($w, $cup) = maj_splice($p, 2);
search($w, "[$cup]", 0, $syun, $kou);
}

my @w = @$p;
my $top = shift @w;

for my $i (0..$#w) {
if ($w[$i] == $top + 2) {
# カンチャン待ち
splice @w, $i, 1;
search(\@w, "[".$top.($top+2)."]", $atama, $syun, $kou);
last;
}
}
}

if (2 < @$p) {
if ($p->[0] == $p->[1] && $p->[1] == $p->[2]) {
# 刻子
my ($w, $cup) = maj_splice($p, 3);
search($w, $machi, $atama, $syun, $kou."($cup)");
}
}

if (1 < @$p) {
my @w = @$p;
my $top = shift @w;
my $n = 1;
for my $i (0..$#w) {
$i -= ($n - 1);
if ($w[$i] == $top + $n) {
$n++;
splice @w, $i, 1;
if (!$machi && $n == 2) {
# 順子待ち
my @ww = @w;
search(\@ww, "[".$top.($top+1)."]", $atama, $syun, $kou);
}
if ($n == 3) {
# 順子
my @ww = @w;
search(\@ww, $machi, $atama, $syun."(".$top.($top+1).($top+2).")", $kou);
}
}
}
}
} else {
$ret{$syun.$kou.$machi} = 1;
}
}

sub main {
my $input = shift;
print $input, "\n";

my @pai_list = split //, $input;
if (@pai_list != 13) {
print "please input 13 chars\n";
exit -1;
}
@pai_list = sort {$a <=> $b} @pai_list;

%ret = ();
search(\@pai_list, 0, 0, "", "");

for my $r (keys %ret) {
print $r, "\n";
}
}

if (@ARGV) {
main($ARGV[0]);
} else {
main("1112224588899");
main("1122335556799");
main("1112223335559");
main("1223344888999");
main("1112345678999");
}

2010年1月31日日曜日

.pkg のアンインストール(Snow Leopard)

Bazaar を導入する際に .pkg を使ったんだけど、
今後のバージョンアップとかを考えて MacPorts に切り替えたくなった。

で、.pkg をアンインストールしようと思ったら
結構手間取った。

なんと.pkg にはアンインストール機能はなく、
手作業で消す必要があるのだ。

一応まとめておく。


インストール履歴の確認

$ vim /Library/Receipts/InstallHistory.plist

Bazaar で検索。array タグに囲まれた .pkg のリストを確認。
全て "org.bazaar-vcs.bazaar.*" で始まっていた。


インストールファイルのリスト作成

$ cd /private/var/db/receipts
$ ls | less

"org.bazaar" で特定できることを確認。

$ find . -name org.bazaar\*bom -exec lsbom -pf {} \; > /tmp/list.txt

.bom からインストールしたファイルのリストを作成する。


ファイルを削除する

リストにはディレクトリもあるので注意。
ファイルがディレクトリにまとまっていたので、
自分は念のため手作業で消したけど、
機械的に消しても問題なさそう。

$ cd /
$ for f in `cat /tmp/list.txt`; do if [ -f $f ]; then sudo rm $f; fi; done


2009年10月14日水曜日

MVCへの考察

最近、気になるエントリがあった。

Ruby on Railsの「えせMVC」の弊害
http://satoshi.blogs.com/life/2009/10/rails_mvc.html

えせMVCについてそろそろ一言言っておくか

Skinny Controller, Fat Model

あんまり他のブログについて言及することはないんだけど、
今回については感じることが多いので書き散らす。


私は Model の実装を多くするのが良いと考えている。

表現が少し挑発的だけど、
@Satoshi さんの主張に共感する。
しかし、何故か実際の反響としては
思ったより多くの人が反論の立場をとっている。

自分の言葉に置き直すと、@Satoshi さんの主張は
「テストしやすく、堅牢に設計すべき」である。
この主張には反対する人は少なそうなのに、
微妙に(結構?) RoR の批判が入っているためか、
受け入れない人が多い。

また、@higayasuo さんは「Controllerも徹底的にテストしろよ」
という主張。正しい。でも、Model のほうがテストし易いのは、
きっと誰にとっても明白ではないだろうか。

#まぁスタブの必要な Model はテストし辛いけどね。
#でもそれは設計ミスかも。

そもそも Web Application を開発することはない、
組み込みエンジニアの私がコメントするのは
立場を間違えている気もするけど。

それでもドライバ以外にも UI のあるアプリを最近実装したり、
MVC は基本的に有益なアーキテクチャなのは実感しているつもり。

自分の言葉で MVC を簡単に且つ乱暴に且つ独りよがりに表現すると次の内容になる。
  • Model: 末端でテストが楽なレイヤ。他モジュール関連度は低い(データ依存なし)。UI 以外の全てのロジックが理想。Controller の小間使い。永続化データの管理が多く堅牢にしたいレイヤ。
  • View: UI 配置がメイン。最近は表示ロジックも多い?(Javascript, Flash)。変更が多く、柔軟にしたいレイヤ。
  • Controller: View と Model を繋げるのが責務。モジュール依存度が高いので、ロジックは少ないのがベスト(実装量が増えるとシステムの複雑度が跳ね上がる)。
基本的には試験し易く堅牢な Model をいかに増やすかが
設計のキモだと思う。Fat ではない Smart な Model。
理想論だけどね。

実際の開発現場ではスピードを求めて、
可能な限り Model を薄くする場合もあると思う。
何が正しいのではなく、何が最適なのか。
それを提案できるエンジニアを目指したい。

2009年5月17日日曜日

bookmarklet

よく使う bookmarklet をメモしておく。

■ google bookmark に追加
javascript:location.href='http://www.google.com/bookmarks/mark?op=add&bkmk='+encodeURIComponent(location.href)+'&title='+encodeURIComponent(document.title)

■ はてなのブクマを確認
javascript:location.href='http://b.hatena.ne.jp/entry/'+location.href

■ livedoor reader に登録
javascript:location.href='http://reader.livedoor.com/subscribe/'+location.href

URL に '#' とか含まれているとおかしくなることがあるけど、
まぁ、愛嬌ってことで。

2009年5月15日金曜日

vimをviper-modeに近づける

本当に emacs 生活が長かったので、
いつのまにか手癖が完全に viper-mode に最適化されていた。

おかげで vim を触るとイライラするように。。。

これまでとは逆のアプローチで vim を viper-mode に近づける
設定をメモしておく。

~/.vimrcに以下を追記
===
nnoremap g<C-x> <C-x>
nnoremap <C-x>o <C-w><C-w>
nnoremap <C-x>b :b #
nnoremap <C-x><C-f> :e
nnoremap <C-x>1 <C-w>o
nnoremap <C-x>2 :sp<cr>
nnoremap <C-x>3 :vs<cr>
nnoremap <C-x>0 :q<cr>
nnoremap <C-x>k :q
nnoremap <C-g> <esc>
cnoremap <C-g> <C-c>
===

2009年5月6日水曜日

vimの小技

開発環境が linux で emacs が便利だったことから
vim から少し離れていた。

そうなると当然、小技を忘れてくる。
久々に触ってみて忘れ具合に少し焦ってきたので、
今のうちに最も忘れそうで、
最も使いそうな(?)忘れるには惜しい小技をまとめておく。

1. ファイル内の tab をスペースに

:set expandtab
:retab

※逆バージョン(space -> tab)

:set noexpandtab
:retab!

2. 文字コードを指定して開き直し

ex) 文字コードを euc-jp にする場合

:e! ++enc=euc-jp

3. ヘルプの引き方

- オプション(:set xxx)
:he 'xxx

- コマンド (:yyy)
:he :yyy

- 全モードの操作コマンドリスト
:he index

- vim script の書き方
:he 41.1

- vim script の関数一覧
:he functions

4. バージョン情報をヤンクバッファ(" register)に出力

:redir @"
:version
:redir end

※この後、normal mode で "p" を実行すると出力結果が張り付けられる。


5. コピー(ヤンク)したコマンドを実行

:@"


###また、思い出し次第追記予定。。。


2009年3月7日土曜日

Android に emacs でデバッガ接続

ddms を経由して emacs からデバッガ接続できる。
やり方は簡単。

1. ddms のプロセスリストからデバッグしたいプロセスのポート番号を調べる
(プロセスが並んでいるリストの右端にある 86xx という番号)

2. M-x jdb を実行
jdb -sourcepath/xxx/xxx/src -attach localhost:86xx

これで接続できる。
後は C-x SPC でブレイク張ったり。
普段使わないけどデバッガの時はツールバーが便利かも。