2010年4月26日月曜日

最小の.emacs

viper モードを卒業しつつある今日この頃。
限界まで設定を絞る。

ポイントは、
- vim の * 代わりの C-l
- C-w で単語削除 or リージョン削除(マーク有りの場合)
- TAB でインデント or 補完(前に文字、後ろに文字無しの場合)


(ffap-bindings)

(define-key isearch-mode-map (kbd "C-l") 'my-isearch-yank-symbol)
(defun my-isearch-yank-symbol ()
"*Put symbol at current point into search string."
(interactive)
(let ((sym (symbol-at-point)))
(if sym
(progn
(setq isearch-regexp t
isearch-string (concat "\\_<" (regexp-quote (symbol-name sym)) "\\_>")
isearch-message (mapconcat 'isearch-text-char-description isearch-string "")
isearch-yank-flag t))
(ding)))
(isearch-search-and-update))

(global-set-key (kbd "C-c C-m") 'execute-extended-command)

(global-set-key (kbd "C-w") 'my-kill-word-or-region)
(defun my-kill-word-or-region (arg)
(interactive "p")
(if (use-region-p)
(kill-region (point) (mark))
(backward-kill-word arg)))

(global-set-key (kbd "C-i") 'my-auto-hippie-expand)
(defun my-auto-hippie-expand (&optional arg)
(interactive)
(if (and (not (bolp))
(not (use-region-p))
(string-match "[a-zA-Z0-9-_]"
(char-to-string (char-before)))
(or (not (char-after))
(not (string-match "[a-zA-Z0-9-_]"
(char-to-string (char-after))))))
(hippie-expand arg)
(indent-for-tab-command arg)))

(custom-set-variables
;; custom-set-variables was added by Custom.
;; If you edit it by hand, you could mess it up, so be careful.
;; Your init file should contain only one such instance.
;; If there is more than one, they won't work right.
'(hippie-expand-try-functions-list (quote (try-complete-file-name-partially try-complete-file-name try-expand-all-abbrevs try-expand-dabbrev try-expand-dabbrev-all-buffers try-expand-dabbrev-from-kill try-complete-lisp-symbol-partially try-complete-lisp-symbol)))
'(iswitchb-mode t)
'(kill-whole-line t)
'(partial-completion-mode t)
'(read-file-name-completion-ignore-case t)
'(show-paren-mode t)
'(x-select-enable-clipboard t))
(custom-set-faces
;; custom-set-faces was added by Custom.
;; If you edit it by hand, you could mess it up, so be careful.
;; Your init file should contain only one such instance.
;; If there is more than one, they won't work right.
)

2010年4月4日日曜日

麻雀の待ち判定2

うまい解き方をしてる人がいた。

http://d.hatena.ne.jp/zorio/20100403/1270303319



perl に翻訳して、多少味付け。

アルゴリズムって大切だなぁ。。

use strict;
use warnings;

sub get_mentsu {
my ($is_atama, $is_machi, $req, $tehai, $has_atama, $has_machi, $offset) = @_;
if (@$tehai < @$req || ($is_atama && $has_atama) || ($is_machi && $has_machi)) {
return;
}

my $init = 1;
my $ret = "";
foreach my $i (0..(@$req-1)) {
if ((!defined $tehai->[$i]) || $tehai->[$i] < $req->[$i]) {
return;
} else {
if ($init) {
my @w = @$tehai;
$tehai = \@w;
$init = 0;
}
$tehai->[$i] -= $req->[$i];
foreach (1..$req->[$i]) {
$ret .= $i + $offset;
}
}
}

if ($is_machi) {
$ret = "[$ret]";
} else {
$ret = "($ret)";
}

return $tehai, $ret, $is_atama || $has_atama, $is_machi || $has_machi;
}

my @mentsu_pattern;
# 頭待ち
push @mentsu_pattern, sub { get_mentsu(1, 1, [1], @_) };
# 頭
push @mentsu_pattern, sub { get_mentsu(1, 0, [2], @_) };
# 刻子待ち
push @mentsu_pattern, sub { get_mentsu(0, 1, [2], @_) };
# 刻子
push @mentsu_pattern, sub { get_mentsu(0, 0, [3], @_) };
# カンチャン待ち
push @mentsu_pattern, sub { get_mentsu(0, 1, [1,0,1], @_) };
# 順子待ち
push @mentsu_pattern, sub { get_mentsu(0, 1, [1,1], @_) };
# 順子
push @mentsu_pattern, sub { get_mentsu(0, 0, [1,1,1], @_) };

sub search {
my ($tehai, $index, $offset, $current, $ret, $has_atama, $has_machi) = @_;

my $start = $index;
while (!$tehai->[0]) {
shift @$tehai;
$offset++;
$start = 0;
if (@$tehai == 0) {
push @$ret, $current;
return;
}
}

foreach my $i ($start..$#mentsu_pattern) {
my ($t, $r, $a, $m) = $mentsu_pattern[$i]->($tehai, $has_atama, $has_machi, $offset);
if (defined $t) {
search($t, $i, $offset, $current.$r, $ret, $a, $m);
}
}
}

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

my @values = split //, $input;
my @tehai;
foreach my $v (@values) {
if (defined $tehai[$v]) {
$tehai[$v]++;
} else {
$tehai[$v] = 1;
}
}
shift @tehai;

my @ret;
search(\@tehai, 0, 1, "", \@ret);

foreach my $r (@ret) {
print "$r\n";
}
}

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

麻雀の待ち判定

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");
}