2014年5月18日日曜日

[bash] sed だけで 1 次元セルオートマトンを作る

sed コマンドだけで 1 次元セルオートマトンを作るアイデアを
思いついたので、実装してみました。

メインループの中は実質的に sed コマンドしか使っていません。
また、スクリプト全体でも、コマンドは sed, expr, echo の
3 種類だけしか使っていません(for, while などの構文は使っていますが)。

1次元セルオートマトンとは何か、については
セル・オートマトン - Wikipedia の「1次元セル・オートマトン」の項目
をご覧ください。

スクリプト本体と実行方法


スクリプトを示します。
前準備が少し長いですが、
本質は最後のほうの while ループ内です。

#!/bin/bash
# 1D cellular automaton

# rule number
NRULE=90
#NRULE=30
#NRULE=110

# number of generation
NSTEP=300

# half size of width (width = HALFSIZE * 2 + 1)
HALFSIZE=300

# function to repeat string $2 $1 times
rep(){
  n=$1
  s=$2
  ss=""
  i=0
  while [ "$i" != "$n" ]; do
    ss=${ss}${s}
    i=`expr $i + 1`
  done
  echo -n $ss
}

# initial state
zeros=`rep $HALFSIZE 0`
str=$zeros"1"$zeros

next=()
tmp=$NRULE
i=7
while [ "$i" != "-1" ]; do
  next[$i]=`expr 2 + $tmp % 2`
  tmp=`expr $tmp / 2`
  i=`expr $i - 1`
done

# PBM header
echo "P1"
echo `expr $HALFSIZE \* 2 + 1` $NSTEP

# main
istep=0
while [ "$istep" != "$NSTEP" ]; do

  # output PBM
  echo $str | sed -e "s/\([01]\)/\1 /g"

  # calculate next generation
  str=0${str}0   # 0 is boundary
  for i in 1 2 3; do
    str=`echo $str | sed \
      -e "s/111/11${next[0]}11/g" \
      -e "s/110/11${next[1]}10/g" \
      -e "s/101/10${next[2]}01/g" \
      -e "s/100/10${next[3]}00/g" \
      -e "s/011/01${next[4]}11/g" \
      -e "s/010/01${next[5]}10/g" \
      -e "s/001/00${next[6]}01/g" \
      -e "s/000/00${next[7]}00/g"`
  done
  str=`echo $str | sed -e "s/[01]//g"`
  str=`echo $str | sed -e "s/2/0/g" -e "s/3/1/g"`

  istep=`expr $istep + 1`
done

実行方法ですが、
上記をたとえば cellular_automaton.sh という名前で保存して

    $ ./cellular_automaton.sh > rule090.pbm

と実行します。
私の手元 (CPU: Intel Core i7-3770 @ 3.40GHz, OS: Debian wheezy) では
5 秒弱かかりました。

得られた結果を、pbm 形式をサポートしているビューアで開くと
以下のような絵が見えるはずです。
時間は上から下に流れています。



スクリプト内のルール番号 NRULE を変更すると違う絵が描けます。
ルール番号の数字の意味は最初に示した参考文献のとおりです。

縦の長さは NSTEP、横の長さは HALFSIZE で調節できます。

アルゴリズム解説


本質的な部分だけを再掲します。
入力となる str にはセルの状態を表す文字(ここでは 1 または 0)
がセルの数だけ入っています。

  for i in 1 2 3; do
    str=`echo $str | sed \
      -e "s/111/11${next[0]}11/g" \
      (略)
  done
  str=`echo $str | sed -e "s/[01]//g"`
  str=`echo $str | sed -e "s/2/0/g" -e "s/3/1/g"`

3 行目で 111 を 11${next[0]}11 の 5 文字に変換しています。
${next[0]} には 111 の次の世代の文字が入っています。
本来なら

    s/111/${next[0]}/g

と置換したいところですが、
"111" のいずれの文字もあとから隣のセルが
参照するかもしれないので消せません。

これはどういうことかというと、
例えば ...01110... の並びの場合は
左から 011, 111, 110 の次の世代を計算する必要がありますが、
先に 111 を置換してしまうと、その結果は

    ...0(111 の次の世代の文字)0...

となってしまい,
両脇の 011, 110 の計算ができなくなります。

そこで、両脇のセルが参照できるように
上記のように 5 文字に置換しています。
変換後の 5 文字の意味はそれぞれ

    1 文字目、2 文字目、次の世代の文字、2 文字目、3 文字目

となっています。

このように置換した結果だと

    ...011(111 の次の世代の文字)110...

となるので、011, 110 の計算ができます。

別の変数を用意して、次の世代の文字はそこに格納しておけば
こんな複雑なことはしなくていいのですが、
それだとすっきりと書けない気がしたのでやりませんでした。

for ループを 3 周回しているのは、
sed は 1 回のコマンド内で変換した文字列は再変換しない
仕様になっているためです(でないと無限ループが起こりうる)。

これはたとえば

    $ echo 0000 | sed -e "s/00/0/g"
    00

という結果から確認できます。

先ほど示した
...011(111 の次の世代の文字)110... の結果は、
真ん中の 5 文字が変換済なので、
011, 110 の変換はできません。
ということで、3 文字から 1 文字を計算する
1 次元セルオートマトンを 1 ステップ回すためには
3 周回す必要があります。

このとき、変換前の世代と変換後の世代の文字を混ぜないため、
変換後の文字は 2 または 3 になっています。
これはスクリプト中間あたりの

    next[$i]=`expr 2 + $tmp % 2`

がそれに対応しています。

ループ 3 周を抜けたあとは、
もとが ...01110... の場合だと

    ...01311211310...

となります。新旧世代を塗り分けると

    ...01311211310...

となります。
旧世代が 3 文字続く場所がなくなったので、変換は終わりです
(端付近はこの限りではありません。
なので 4 周以上回すと文字数が保存されないことがあります)。

上記のままだと次の変換ができなくなるので

    str=`echo $str | sed -e "s/[01]//g"`

で旧世代の文字を削除し、

    str=`echo $str | sed -e "s/2/0/g" -e "s/3/1/g"`

で 2 を 0 に、3 を 1 に戻します。

2014年5月17日土曜日

SyntaxHighlighter でブログにコードを綺麗に表示

ブログにプログラムソースを載せることがあるのですが、
もう少し綺麗に見せたいと思ったので
を参考に SyntaxHighlighter を導入してみました。

テストも兼ねて使ってみたのが以下です。

#!/bin/bash
i=0
while [ $i != 10 ]; do
  i=`expr $i + 1`
  echo $i
done

2014年5月15日木曜日

[雑感] 第一印象が良すぎると、長期的には損をする?

人間には、第一印象が良い相手を信用するようなバイアスがあるように思えます。
そのようなバイアスを利用してお金を巻き上げるのが詐欺でしょう。

第一印象で人を信じてしまう人に、第一印象がとても良い人が出会うと、
高い評価を得ることができるでしょう。
短期的には得をします。

けれども、第一印象に比べて実力のレベルがとても低い人は、
長期的には損をするかもしれません。

前者が顧客で後者がサービス提供者の場合
(仕事に限るつもりはないですが、例えとして)、
信じ込んでしまった顧客は、提供者の仕事のチェックをしなくなるかもしれません。
提供者がミスをしても、それが致命的な状況に拡大するまでなかなか気づきません。

そして、その顧客は「なんて酷いことをするんだ、裏切られた」と言って、
第一印象の良いサービス提供者を逆恨みするかもしれません。

このような事態を避けるには、
自分が顧客側に立つ場合は、
相手の見た目と内容(仕事)のレベルは一致しないと思うようにし、
サービス提供側に立つ場合は、
見た目のレベルが内容のそれを卓越しすぎないように、
内容に強化していくことになるでしょう。

実際には上記の事態はあまり起こらなくて、
内容を活かすような見た目を作れなくてうまくアピールできない、
というのがほとんどなのでしょうけど。

2014年5月11日日曜日

[雑感] スルー力をつける他に、怒りをシフトさせるという提案

巷で「スルー力がほしい」「スルー力をつけたい」とよく聞きます。

私も最近、ある考え方(後日書きます)をするようになってから
少しスルー力がついた気がしますが、
手放しに喜べないと危惧しています。

年をとって、怒る元気がなくなっただけの可能性もあるので。

「ある考え方」だって、怒らない言い訳として、
自分を説得するためにでっち上げただけかもしれません。

細かいことにしょっちゅう腹を立てるのは馬鹿らしいことですが、
「細かいけれども、実は重要なこと」をスルーしてしまうまでに
神経が鈍感になってしまうのもまずいです。

そこで、「腹立たしいこと」を下手に全部なんとかしようとせず、
全体の怒る量を保存しながら、「重要なことには全力で怒る」ほうに
シフトするように仕向ける考え方もありだと思います。

実際に行う場合は、
予め「こういう件は重要なので怒ってよし」と決めておくとよいでしょう。
怒ってから考えると判断基準が揺らぐためです。

ダイエットに例えるなら、食べる量を減らしてひもじい思いをする方法よりも、
糖分や脂肪は制限するけど野菜は無制限、みたいな方法のほうが
本人の精神衛生にもよくて、定着しやすいと思うのです。

2014年5月10日土曜日

xargs コマンドを用いたお手軽並列化

カレントディレクトリにある複数の ps ファイルを eps に変換する場合、
これまでは

    for f in *.ps; do
      name=`basename ${f} .ps`
      convert -rotate 90 ${name}.ps ${name}.eps
    done

という感じでやっていました(bash の場合)。

ですがファイル数が万単位になってくるととても時間がかかるので、
xargs を使って並列化したのがこちらです。

    $ ls *.ps | xargs -I{} basename {} .ps | xargs -P2 -I{} convert -rotate 90 {}.ps {}.eps

拡張子の前の文字列が変換前後で同じであってほしい
(たとえば hoge.ps を変換したものは hoge.eps になってほしい)
ので、basename を挟んでいます。

実行して別窓で top してみると、convert が 2 本走っていることが分かります。

2014年4月28日月曜日

Let's note MX3 で画面を閉じずにバッテリ交換をやってみた

先月から Let's note MX3 を使っています。

MX3 を選んだ理由のひとつが
バッテリが「ホットスワップ」に対応していることでした。

今日は出張中で電源が確保できなかったので、
初めてやってみました。

ところで、やる前にちょっと気になっていたのが
「ホットスワップをするときに画面を開いたままにするとどうなるか」
でした。

一応、
を見る限りでは画面を開いたままでもできるようです。

画面を開いたままの交換はやりづらいので
普通はやらないですが、興味本位でやってみました。

で、結果としては、電源が落ちることはなかった(当たり前)のですが、
交換後の短時間、バッテリの残量表示がおかしくなりました。

まず外したときですが、これは問題ありませんでした。
「残り 99 % 」が表示されていました。
内蔵バッテリだけで駆動していると認識しているようです。

次に、新しい電池(充電済み)をつけた直後は、
電池の残りが以下のように, 「31 %」と表示されてしまいました。


合計を計算するときに、
新しい電池の容量が 0 % としてカウントされているようです。

この症状は1分くらい待つと直ったので、実用上は問題ありません。

2014年4月27日日曜日

連合が GW 中の大会開催を決めた経緯と、それをもとに想像した 2016 年大会の行方 #JpGU #JpGU2014

2014 年の日本地球惑星科学連合大会 (JpGU2014) は
4/28(月)~5/2(金) に開催されます。

これは GW 中ですし、欧州の類似の学会である EGU とかぶってしまっています。
EGU とかぶったことについては会員からクレームがついたそうです
(日本地球惑星科学連合メールニュース 5月号 No.168  2013/05/10 より)。

この日程設定は運営の失策だと言わざるを得ません。

ですが、運営を批判するだけでは始まりません。
個人的には、どうしてこのような決定に至ったのか興味をもったので、
ネットで入手できる範囲で調べてみました。

なお、以下では GW 中開催に至った経緯のみを調べており、
他の学会との連携については触れていません。

2014 年大会の日程・場所決定までの経緯


連合理事会の議事録を時間を追って見ることにします。
ちなみに議事録一覧はこちらから見ることができます。

2012 年の 9 月の時点では

      2014 年以降講演会場を増やすことができるよう、追加になる会場の見積りをとってい
      ることも説明された。年内にはある程度の見通しを立てる予定である。
     
      (2012/09/28 平成24年度理事会(第5回)の議事録 p. 2 より引用)

とあります。
連合大会は例年幕張メッセの国際会議場で開催されているのですが、
この時点では幕張メッセ周辺で会場を拡張する方向で検討していたようです。

次の、年末の理事会で具体案が出ます。

      第 7 号議案 2014 年大会開催方針の件(会費・参加費等値上げ検討 WG 立上)(浜野理事)
       資料 P94-112
       2014 年以降に関しては、現在幕張メッセの国際会議場はすでに一杯であり、参加者増加
      を目指すならば会場を広げるしかない状況である。その為、以下の案が提案された。
      1) 幕張メッセの国際会議場と展示場の半分を使用(国際会議場:5 日/展示場:3 日)
      2) 幕張メッセの国際会議場と APA ホテルの 2 階の宴会場を使用
      (国際会議場:5 日/APA 宴会場:3 日)
      3) 国際フォーラムのガラス棟を使用
      4) 2015 年度以降パシフィコ横浜を使用することとし、2014 年度は幕張メッセで開催する
      5) 新宿の京王プラザホテルを使用
      これらを基に議論がなされ、値上げWGを立ち上げ、値上げの件も併せ以下の案をベース
      に早期に方針を決定することが確認された。
      1) 今まで通り幕張メッセ国際会議場で6日間開催
      2) 6 日から 5 日に会期を短縮し、APA ホテルの宴会場か幕張メッセの展示場を使い開催
      3) 2014 年は何も変えず、2015 年にパシフィコ横浜を借りて開催する
     
      (2012/12/26 平成24年度理事会(第6回)の議事録 p. 5 より引用)

ここでも 2014 年は幕張メッセ+別会場の方向で検討されています。
また、後半の 案 3 では 2015 年にパシフィコ横浜で開催する可能性を模索していました。

検討の結果、次の理事会で「2014 年は幕張メッセ開催」がひっくり返りました。

      第 2 号議案 2014 年大会の会場、および 2015 年以降の会場および大会参加料、投稿料の
      値上げについて(浜野理事)資料 P17-32
       投稿数は年々5%程度づつ増加しており、近年は 4000 件程度である。この数を幕張メッ
      セの 18 会場でやるのはかなり難しく、今年は1コマを 7 講演とし、一日の開催時間が長く
      設定されている。投稿を増やす為には会場を増やすことが必須である。幕張で会場を増や
      そうとすると、1000 万円程度、会場費が膨らむことになる。連合大会を一か所でやれると
      ころはパシフィコ横浜しかない。メッセより広いが人気があるので通常連合大会を開催し
      ている日程では借りられないが、2014 年は 4 月 28 日から 5 月 2 日までは空いている。
      22 会場 5 日間で 2400 万円程度で開催できる見込みである。2014 年は AOGS が札幌で 7
      月末から 8 月初旬に開催が決まっている為、少しでも会期を離す必要もある。2015 年は連
      休以外はパシフィコ横浜は空いていないので、2014 年はパシフィコ横浜で 5 日間、2015
      年は幕張メッセで例年通り 6 日間開催をして、それ以降についてはアンケートをとって開
      催場所を決定することが全会一致で承認された。
     
      (2013/03/07 平成24年度理事会(第7回)の議事録 p. 3-4 より引用)

要するに、前回の案 3 (2014 年は幕張メッセ、2015 年はパシフィコ横浜)で
行こうとしたが、2015 年のパシフィコ横浜は連休以外では既に空きがなかったため、
2014 年と 2015 年の場所を入れ替えた。
で、2014 年のパシフィコ横浜は、
別の大きな学会 (AOGS) と離れた日程では 4/28-5/2 しか開いていないので、
その日程にした、ということなのでしょう。

当初予定を覆して 2014 年にパシフィコ横浜にしたのが個人的には分かりかねます。
会場費が膨らむから幕張を見送った旨がありますが、2015 年は幕張で行うわけですし。
2014, 2015 年両方とも幕張とし、パシフィコ横浜は 2016 年以降開催に
考えなおす案はなかったのでしょうか。
「連合大会を一か所でやれるところはパシフィコ横浜しかない」あたりから
パシフィコ横浜での開催にこだわっているように感じられます。

2年以上先のパシフィコ横浜が予約でいっぱいになっていた
(2013 年 3 月の時点で 2015 年の初夏が埋まっていた)
という事実は、想定外のものだった(厳しく言えば、見積もりが甘かった)と思われます。
結果論ではありますが、初動が遅かったと言えるでしょう。
ここから教訓として「万人規模が参加するような大きなイベントを開催する場合は、
2年前からの準備では遅いかもしれない」を得ることができます
(ちなみに、パシフィコ横浜は施設によっては3年前から予約可能のようです)。

また議事録の「2015 年は連休以外はパシフィコ横浜は空いていない」より、
2015 年のパシフィコ横浜開催を見送ったことから、
連休開催を避けようとしていることがわかります。
にもかかわらず 2014 年に 4/28-5/2 を選択したということは、
この日程は連休中ではないと認識しているのでしょうか。
もしくは、この日程も連休中なので良くない、と
苦言を呈した人がいたかもしれませんが、
議事録に残っていないだけかもしれません。

2016 年大会の日程・場所決定に関する「悪い」シナリオ


ここから話を少し変えます。
上記を踏まえた上で、考えを未来に向けてみます。
2016 年の連合大会のことです。

今のところ「アンケートをとって開催場所を決定する」ことになっています。
アンケートはまだ実施されていません。
今回の横浜の大会を経験しないと幕張と比べることはできないので、
早くとも今回の大会の後でしょう。

さて、私は先ほど、初夏に限れば
「2年以上先のパシフィコ横浜が予約でいっぱいになっていた」と書きました。

これは 2013 年の実績ですが、今年もその可能性が高いのではないでしょうか。
つまり 2016 年初夏のパシフィコ横浜はもう埋まっているかもしれません。
初夏以外の季節の空き具合は分かりませんが、
運営は日程を確保できるかどうか調べているのでしょうか。
もしかするとアンケートの結果を待つなんて悠長なことを
やっている暇なんかないのでは、と心配になります。

2016 年大会の「悪い」シナリオを考えてみます。

仮に、アンケートの結果、2016 年はパシフィコ横浜の開催に決まったとします。
この場合、2016 年初夏のパシフィコ横浜は
2015 年の場合同様、初夏は埋まっている可能性が高いでしょう。
そうすると、他の季節に開催することになります。
アンケート実施が遅い場合、つまり会場予約が遅い場合、
人気のない季節しか残っておらず、参加しづらい日程になる恐れがあります。

最悪のケースは、パシフィコ横浜でどの季節も日程を確保できず、
アンケート結果が覆されることです。
その場合は 2016 年は幕張開催になるでしょう。
しかも、先述の通り幕張では会場費が高く、
パシフィコ横浜に比べて参加費などの値上げが実施されます
(2015 年は幕張なので、据え置きという形になるでしょうが)。
学会員にとっては、意見が通らず、負担も大きくなる事態に不満が募るでしょう。

以上、悪い方向に考えましたが、
上記は私がぱっと考えただけのものであり、
実際には杞憂に終わるかもしれません。
また、アイデアが出て、問題は回避されるかもしれません。

私も末端ではありますが会員なので、
ただブログで文句をいうだけでなく、
窓口に意見のメールくらいはしようと思います。
おせっかいかもしれませんが。