ブラックモンブラン

ブラックモンブランって「九州地区ドンキでMEGAヒット!!」というよりも、九州では昔から非常にポピュラーなアイスで、関東で言えばガリガリ君並にどこにでも売っている。
ばってん荒川がテレビCMに出ていたような気がする。
ばってん荒川とは九州では昔から人気のあるタレントで、関東で言えばマツコ・デラックスのようなもの。

black-mont-branc

古い本の処分 (1)

家の中で邪魔になっていた古い本を処分した。
量が多いので宅配で本を買い取ってくれる業者を利用した。
こうして見ると、こんな本買わなければ良かったって本も多かったと気づかされる。
間違って2冊買ってしまったり。
書店の店頭で「これ面白そう、買っておこう」→家の本棚に置いておく→数か月放置→書店の店頭で「これ面白そう、買っておこう」という。

used-books1

used-books2

used-books3

ドミノ・ピザのクイズ

ドミノ・ピザをネットで注文し終わると、続けてクイズが始まる。
ピザが届くまでに答えを考えて、正解すると割引チケットやサイドメニューのクーポンをもらえる。
いつもイージーやノーマルを選ぶけれども、今日はハードモードに挑戦してみた。

今回の問題は、日本の歴代総理大臣の名前で、
1) 名字が1文字
2) 名前が1文字
3) 名字が3文字
4) 名前が3文字
5) 名字と名前を足して3文字以内
の条件で、多いものから順に答えよ、というもの。
見た瞬間、行ける、ピザ半額チケットはもらったと思った。
データベースに入れてSQL使おうか迷ったけれど、普通にスクリプトで解いた方が早そうだったので、Perlで解く事にした。

まずは歴代総理大臣の一覧データを入手しないといけないが、ウェブを検索しても名字と名前が分かれて書かれたページがなかなか見つからないので焦る。
結構たくさんページを見て回って、ようやく見つけた。
まず、ブラウザに表示されてる名前部分を選択してコピーし、Excelにペーストする。
HTMLのテーブルタグをExcelにペーストするといい感じにExcelの列になってくれるので、名前部分の列をコピーし、今度はvimにペーストする。
この時点で「安倍 晋三(第2次)」みたいに邪魔な文字列が混じってるので、vimの置換機能で「安倍,晋三」に変換する。さらにuniqで重複を取り除く。
ここからPerlで問題を解く。
急いだせいでタイプミスなどあったが5分程で出来た。処理を見直したが問題ない。
Perlを実行して出た答えを、ドミノ・ピザのページに戻って、入力した。

しばらくして、制限時間終了。答え合わせが始まる。
絶対問題ないはず。
問題ないはず。
…問題ないはず。
…だったが、まさかの不正解の判定。
そんな馬鹿なと再度処理を見直すと、しまった、元データが「歴代総理大臣の一覧」ではなく「戦後の歴代総理大臣の一覧」のページだった。
痛恨のミス。
やっと名字と名前が分かれて書かれたページを見つけたので、舞い上がってしまった。よく考えれば総理大臣が少なすぎた。
もうドミノ・ピザは二度と注文しない。

 #!/usr/bin/env perl
 use utf8;
 @list = qw(
     芦田,均
     安倍,晋三
     伊東正義
     宇野,宗佑
     羽田,孜
     海部,俊樹
     岸,信介
     吉田,茂
     宮沢,喜一
     橋本,龍太郎
     佐藤,栄作
     細川,護煕
     三木,武夫
     小泉,純一郎
     小渕,恵三
     森,喜朗
     菅,直人
     石橋,湛山
     村山,富市
     大平,正芳
     池田,勇人
     竹下,登
     中曽根,康弘
     田中,角栄
     東久邇宮,稔彦
     鳩山,一郎
     鳩山,由紀夫
     福田,康夫
     福田,赳夫
     幣原,喜重郎
     片山,哲
     麻生,太郎
     野田,佳彦
     鈴木,貫太郎
     鈴木,善幸
 );
 
 $hit = 0;
 foreach (@list) {
     ($sei, $mei) = split ',', $_;
     if (length($sei) == 1) {
         $hit++;
     }
 }
 print "1: $hit\n";
 $hit = 0;
 foreach (@list) {
     ($sei, $mei) = split ',', $_;
     if (length($mei) == 1) {
         $hit++;
     }
 }
 print "2: $hit\n";
 $hit = 0;
 foreach (@list) {
     ($sei, $mei) = split ',', $_;
     if (length($sei) == 3) {
         $hit++;
     }
 }
 print "3: $hit\n";
 $hit = 0;
 foreach (@list) {
     ($sei, $mei) = split ',', $_;
     if (length($mei) == 3) {
         $hit++;
     }
 }
 print "4: $hit\n";
 $hit = 0;
 foreach (@list) {
     ($sei, $mei) = split ',', $_;
     if (length($mei) + length($sei) <= 3) {
         $hit++;
     }
 }
 print "5: $hit\n";

Markdownの記法について

Pukiwikiで公開している技術メモをブログのWordPressにまとめてしまおうかと検討している。
そこで問題なのがWiki記法。
WordPressにはPukiwki記法のプラグインはあまり良い物が存在しない。
Markdown記法プラグインは幾つかあるけれど、PukiwkiとMarkdownを比較して、Pukiwikiが優れた記法に思える。
Markdownで特に嫌なのがWikipediaに書いてある、

* 順序無しリストのアイテム
  * サブアイテムは4つのスペースでインデントする
* 順序無しリストの別のアイテム

<!– dummy comment line for breaking list –>

1. 順序付きリストのアイテム
2. 順序付きリストの別のアイテム

のように、リストの次に別のリスト(または段落)を続ける場合はコメントタグを挿入する必要がある、という仕様。
これは本当にイケてないと思う。
Pukiwikiは改行を入れるだけでリストは終了したと見なされる。
また、リストのサブアイテムにはスペースを4つも入力する必要があり面倒。Pukiwikiはインデントの深さに応じて-を重ねるだけで良い。
順序付きリストはいちいち、1. 2. 3.と連番を振る必要があるので、後からリストにアイテムを追加・削除すると順番が狂う。連番でなく、1. 1. 1.と同じ番号で続けても良いのだけれど(ウェブで見る場合は連番に変換される)、プレーンテキストで見る場合は奇妙な見た目になりスッキリしない。
Pukiwkiはマーカーが+ならウェブで見る場合は連番に変換される。
他にも、リンクはPukiwkiのようにhttp://から始まる文字列を書けば勝手にURLに解釈してくれる方が楽だと思う。

Markdown記法はRedmineやTracのWiki記法に比べればマシだと思うし、プレーンテキストで見るなら良いと思うけれども、ウェブで見るのが前提ならPukiwiki記法の方が優れてると思う。

技術情報 / Perl / アルゴリズム / ルーレット選択

  • ある集合の要素はそれぞれ重みを持っている。
  • 例えばそれぞれの重みが @rate = (60,30,10) だとして、それぞれに対して累計 @total = (60,90,100) を求める。
  • それぞれの累計の値は、それぞれの要素の数直線上の値を表すと考えると良い。
  • 次に累計の範囲内でランダムな値を決め、それぞれの累計の値と比較すれば、対応する要素が求まる。
  • 以下のroulette1()/roulette2()はその実装。

#!/usr/local/bin/perl

use strict;
use warnings;
use Data::Dumper;

my @rate = (60,30,10);

my @result1;
foreach ( 1 .. 100000 ) {
 my $idx = roulette1(@rate);
 $result1[$idx]++;
}
print Dumper \@result1;

my @result2;
foreach ( 1 .. 100000 ) {
 my $idx = roulette2(@rate);
 $result2[$idx]++;
}
print Dumper \@result2;

sub roulette1 {
 my @rate = @_;
 my @total;
 $total[0] = $rate[0];
 for ( my $i = 1 ; $i < @rate ; $i++ ) {
     $total[$i] = $total[ $i - 1 ] + $rate[$i];
 }
 my $rand = int( rand( $total[ @total - 1 ] ) ) + 1;
 my $idx  = 0;
 while ( $rand > $total[$idx] ) {
     $idx++;
 }
 return $idx;
}

sub roulette2 {
 my @rate = @_;
 my $total;
 foreach my $n (@rate) {
     $total += $n;
 }
 my $rand = int( rand($total) ) + 1;
 my $idx = 0;
 for ( ; $idx < @rate ; $idx++ ) {
     $rand -= $rate[$idx];
     if ( $rand <= 0 ) {
         last;
     }
 }
 return $idx;
}

技術情報 / Perl / アルゴリズム / ビット演算による権限制御

#!/usr/bin/env perl

use strict;
use warnings;
use 5.012;

# 権限を設定
my $none    = 0x0;
my $read    = 0x1 << 0;
my $write   = 0x1 << 1;
my $execute = 0x1 << 2;
my $extra   = 0x1 << 3;

# 権限を付与
my $all = $none | $read | $write | $execute;

# 権限をはく奪
my $not_all = $all & ~$read;

my %actions = (
 +read    => $read,
 +write   => $write,
 +execute => $execute,
 +extra   => $extra,
);

# 権限を2進数で確認
printf( "%- 10s%04bn", "none",    $none );     # none      0000
printf( "%- 10s%04bn", "read",    $read );     # read      0001
printf( "%- 10s%04bn", "write",   $write );    # write     0010
printf( "%- 10s%04bn", "execute", $execute );  # execute   0100
printf( "%- 10s%04bn", "extra",   $extra );    # extra     1000
printf( "%- 10s%04bn", "all",     $all );      # all       0111
printf( "%- 10s%04bn", "not_all", $not_all );  # not_all   0110

say '';

# 各権限の内容を確認
if (($all & $read) != 0) {           
 say "all can read ? => OK";                 # all can read ? => OK
} else {                             
 say "all can read ? => NG";      
}                                    

if (($write & $read) != 0) {         
 say "write can read ? => OK";               # write can read ? => NG
} else {                             
 say "write can read ? => NG";    
}                                    

if (($not_all & $read) != 0) {       
 say "not_all can read ? => OK";             # not_all can read ? => NG
} else {                             
 say "not_all can read ? => NG";  
}

if (($not_all & $write) != 0) {       
 say "not_all can write ? => OK";             # not_all can write ? => OK
} else {                             
 say "not_all can write ? => NG";  
}

say '';

while ( my ( $k, $v ) = each %actions ) {       # all can execute ? => OK
 if ( ( $all & $v ) != 0 ) {                 # all can read ? => OK
     say "all can $k ? => OK";               # all can extra ? => NG
 }                                           # all can write ? => OK
 else {                                
     say "all can $k ? => NG";         
 }                                     
}                                         

say '';

while ( my ( $k, $v ) = each %actions ) {       # extra can execute ? => NG
 if ( ( $extra & $v ) != 0 ) {               # extra can read ? => NG
     say "extra can $k ? => OK";             # extra can extra ? => OK
 }                                           # extra can write ? => NG
 else {
     say "extra can $k ? => NG";
 }
}

技術情報 / Perl / アルゴリズム / ビット演算

左にシフト

say 3<<1; # 6
say 3<<2; # 12
say 3<<3; # 24

1ビット、左にシフトすると、数は2倍になる。

右にシフト

say 24>>1; # 12
say 24>>2; # 6
say 24>>3; # 3
say 24>>4; # 1
say 3 / 2; # 1.5

1ビット、右にシフトすると、数は半分になる。

あるビット列について、特定のビットだけ取り出す

my $num = 25;
my $pos = 3;
my $bit_mask = 1<<$pos;

printf "%b\n", $num;       # 11001
printf "%b\n", $bit_mask;  #  1000

say $num & $bit_mask;      # 8
say 25 & (1<<3);           # 8
  • 特定のビットは1<<nで表せる。これをビットマスクと呼ぶ。
  • あるビット列について、ビットマスクと論理積(&)を取ると、特定のビットを取り出せる。
  • 上の例では、あるビット列(11001/25)の3番目(一番下の桁を0番目とする)のビットを取り出してる。

あるビット列について、特定のビットをセットする

my $num = 25;
my $pos = 2;
my $bit_mask = 1<<$pos;

printf "%b\n", $num;           # 11001
printf "%b\n", $bit_mask;      #   100

say $num | $bit_mask;          # 29
say 25 | (1<<2);               # 29
printf "%b\n", (25 | (1<<2));  # 11101

* あるビット列について、ビットマスクと論理和(|)を取ると、特定のビットをセットできる。
* 上の例では、あるビット列(11001/25)の2番目のビットをセットしてる。

あるビット列について、特定のビットをクリアする

my $num = 25;
my $pos = 3;
my $bit_mask = 1<<$pos;

printf "%b\n", $num;           # 11001
printf "%b\n", ~$bit_mask;     # 11111111111111111111111111110111

say $num & ~$bit_mask;         # 17
say 25 & ~(1<<3);              # 17
printf "%b\n", (25 & ~(1<<3)); # 10001
  • あるビット列について、論理否定(~)したビットマスクと論理積(&)を取ると、特定のビットをクリアできる。
  • 上の例では、あるビット列(11001/25)の3番目のビットをクリアしてる。

n進数を10進数に変換

say oct("011");    # 8進数→10進数 「9」
say oct("0xA1");   # 16進数→10進数 「161」
say oct("0b101");  # 2進数→10進数 「5」
say oct("11");     # 8進数→10進数 「9」

技術情報 / Perl / ackコマンド

ackコマンド

インストール

  • CPANモジュールとしてインストールするか、シングルファイル(Perlスクリプトファイル)をダウンロードしてパスを通すか。
  • beyondgrep.com/install/

ファイル構成

.
|-- 1.csv
|-- 1.pl
|-- 1.rb
|-- dir_a
|   |-- 1.csv
|   `-- 1.pl
`-- dir_b
    `-- 1.pl

2 directories, 6 files

文字列を検索する

$ ack 'perl' .
1.pl
1:#!/usr/bin/perl

dir_b/1.pl
1:#!/usr/bin/perl

dir_a/1.pl
1:#!/usr/bin/perl

すべてのファイルタイプを対象にする

$ ack -a perl .
1.pl
1:#!/usr/bin/perl

1.csv
1:perl,ruby,bash

dir_b/1.pl
1:#!/usr/bin/perl

dir_a/1.pl
1:#!/usr/bin/perl

dir_a/1.csv
1:perl,ruby,bash

ファイルタイプを指定する

$ ack --type=ruby usr .
1.rb
1:#!/usr/bin/ruby

ファイルタイプを除外指定する

$ ack --type=noruby usr
1.pl
1:#!/usr/bin/perl

dir_b/1.pl
1:#!/usr/bin/perl

dir_a/1.pl
1:#!/usr/bin/perl

ファイルパスに条件を付ける

$ ack -G _a perl .
dir_a/1.pl
1:#!/usr/bin/perl

マッチしたファイルのファイル名のみを表示する

$ ack -l perl .
1.pl
dir_b/1.pl
dir_a/1.pl

マッチしなかったファイルのファイル名のみを表示する

$ ack -L perl .
1.rb

ファイル名一覧の区切りを(改行ではなく)ヌル文字にする

ack -l --print0 perl . | xargs -0 rm -rf {}

参考

search.cpan.org/perldoc?ack

PuTTY 0.63

PuTTY 0.63がリリースされたので、自分のWindowsマシンのPuTTYを入れ替えました。
PuTTYのようなSSHターミナルソフトは脆弱性を放置すると重大な被害を受けうるので、常に最新版を使用するべきでしょう。
(マルウェアが常駐しているpagent.exeを勝手に利用したら?)
PuTTYはいろんな派生版が存在しますが、いくつかはメンテナンスされてなく、そのようなソフトの利用は止めた方良いでしょう。
WinSCPやTortoiseSVN等のSSHプロトコルの処理に内部でPuTTYファミリを使っているソフトも同様に最新版を使った方が良いです。

個人的にPuTTYは派生版のiceiv+puttyのDirectWrite版を使ってますが、こまめにメンテナンスされ素早く本家PuTTYに追随してくれてます。
このPuTTYはDirectWriteを採用しているので、フォントが綺麗で行間の微調整が出来、非常に重宝します。
とても良いソフトで、有り難いです。

putty063

APPキー

先日、Windowsのコンソールソフト、ConEmuのマニュアルを読んでいると、キーボード設定の項に

Apps+F | Search text in the console

と書いてあった。Apps+FのAppsって何だろう?
調べてみると、通常はキーボードの右下にある、右クリックをする為のキーをAPPキーと呼ぶようだ。
知らなかった。
ConEmuはショートカットキー設定が大量にあり、CTRLキー、ALTキー、WINキーでは足りず、APPキーも利用しているようだ。
実際、私もWindows上ではAutoHotKeyやその他ユーティリティソフトで多くのショートカットキー設定をしていて、キーコンビネーションが重複してしまう事が良くある。
キーボード中心の操作体系を目指すと、キーの種類って多ければ多い程いいなと思う。

appkey

リトル・チャロ

リトル・チャロ1をまとめてDVDで見ている。
テレビで放送していた頃は、ドレッドが死んだあたりまではリアルタイムで見ていたのだけれど、録画はしつつも何となく面倒になり、最後の方は未見のままだった。

テレビの連続ドラマは途中でどうでも良くなる事が多い。
今年春から放送していた「惡の華」も最初は毎週凄く楽しく見ていたけれど、主人公の二人が深夜の教室で暴れた回が個人的に大満足で、不思議ともうこれ以上見なくてもいいかなという気持ちになって、以後の回は見てない。
惡の華、いつかDVDが安く借りられたらまとめて見るかもしれない。

little-charo