2013/03/25

雑なリマインダ その2

以前、こんなものを作った。

こんな雑なbatだけど今でも使っている。でもタスクバーにcmdが出っぱなしなのでうざい。間違って閉じてしまうこともある。ということで、改良というより作りなおしてwindows標準のタスクスケジューラに登録するようなものにした。Windows7だと動くと思います。

タスクは実行されたあとに削除されるようになっている(/Zオプション)。ただ/ZオプションをつけただけだとXMLがどうのこうのというエラーが出るので/V1オプションを付けてある。

エラー: タスク XML に必須の要素または属性が含まれていません。
(41,4):EndBoundary:

タスクスケジューラに登録するID文字列を作るときに日付と時間を使ってるんだけど、そのフォーマット指定がえらいことになってる。

それと、結局使ってないけど、コマンドの結果を変数に保存するのにforを使う必要があるらしく、これもやけに大変だな・・・。勉強になるなぁ(白目

@FOR /F "usebackq tokens=*" %%i in (`DATE /T`) DO @SET TASK_CREATE_DATE=%%i

ついでにメモしておくと、unixでいう cat は type、diff は fc、traceroute は tracert、grep は findstr、ifconfig は ipconfig 辺りで代用できるって認識で良いのかね。more、arp、ping、netstat、nslookup なんかは同じのがあるようで。


2013/03/23

Land of Lisp 10章のシミュレーション

画像は Land of Lisp 10 章で作るシミュレーションの世界にて100万日が経過した状態。

遺伝子とエネルギーを持った動く動物が、草と森がある世界で動きまわって食事をし、無性生殖で繁殖する世界のシミュレーション。動物は遺伝情報に従い特定の動きを見せ、動くことでエネルギーを消費する。草を食べることでエネルギーを補充、繁殖でエネルギーを大幅に消費、エネルギーが足りないと繁殖できない、エネルギーが切れると死ぬ、というもの。

ライフゲームも似たようなもんだよね。

プログラムの大部分は本に載っているCommon Lispのコードと翻訳者であるshiroさんが公開されているGaucheによるコードを基に、少し改造していくつかの条件をパラメータで渡せるコマンドにしてみたもの。

パラメータをいじって30万日くらい動かすと結果が違って楽しい。動作はコマンドを実行してEnterを押すごとに世界が1日進む。300000などの数値を打ち込んでEnterを押すとその分日数が経過する。


さて、読んでいてよくわからなかったのが、P.202の turn 手続きで移動方向を決める部分。説明を読んでもいまいち意味がわからなかった。angle 手続きを呼び出す辺り。angle の定義はこれ。

(define (angle genes x)
  (let1 xnu (- x (car genes))
    (if (< xnu 0)
        0
        (+ 1 (angle (cdr genes) xnu)))))

自分なりに書きなおしてみたのはこれ。

(define (angle genes x)
  (let rec ((genes genes)(x x)(acc 0))
    (let1 xnu (- x (car genes))
      (if (< xnu 0)
          acc
          (rec (cdr genes) xnu (+ acc 1))))))

angle 手続き事態は難しくないけど、これを使って何をやってるのかがわからなかった。

angle の仕事は、引数 x を基に、引数 genes(リスト)から一つ要素を選び、選ばれた要素のインデックスを返すこと。例えば、genes が (1 1 10 5 2 1 1 1) だった場合、合計が22なので x は0〜21のランダムな数値(angle を呼び出す側で決められる)で束縛される。angle の評価結果として出現する頻度が最も高いのが2、次が3、その次が4。

絵に書くとこんな感じか。絵の上の行の数値が x 、下が選択される要素。

今この絵を描いていて思いついたけど、以下のようなリストからランダムに選ぶのと同じってことだな。

(use srfi-27)
(let1 genes '(1 1 10 5 2 1 1 1)
  (apply append
         (map (^(g i)
                (iota g i 0))
              genes
              (iota (length genes)))))
;; => (0 1 2 2 2 2 2 2 2 2 2 2 3 3 3 3 3 4 4 5 6 7)

ということで、angle 手続きは下記のようなものでも良いということか。

(define (angle genes x)
  (~ (apply append
            (map (^(g i)
                   (iota g i 0))
                 genes
                 (iota (length genes))))
     x))

余談

これ、条件をちゃんと考えたら「ライフメーカーの掟」のプロローグ部分(ロボットがバグって進化し始める)のシミュレーション作れるんじゃないの。 (「ロボットがバグって進化し始める」っていう説明ではすごくちゃちなものに聞こえてしまうな。これをホーガン氏が書くとどえらい壮大なことになるんだよなあ。) このシミュレーションプログラムを有性生殖にして工場を作るだけでも近いものになりそうだな、という話。


2013/03/22

tputのサンプル

tputでterminalサイズいっぱいにランダムに背景色を設定し続けるサンプル。わさおKPFのLTでちらっと見せてくれたのを思い出して真似してみた。あれはコレ↓を使ったやつなんだろうけども。

tput colsとlinesでterminalのサイズを取得し、ランダムな座標にランダムな背景色を指定し続ける。

こんな感じ。

スクリプトはGauche。tputの実行はgauche.processモジュールのrun-process、tputの実行結果取得はprocess-output->stringで。

下のはtput colsでterminalの幅を取得してランダムな背景色を指定しつつ行末まで行ったらreturnして行頭に戻ってループ。

まあ、両方ともあんまり意味はない。ヒマだったんだ。

2013/03/21

Re: ターミナルに黒魔道士

昨日の記事に予想外の反響。

ブコメにRubyのワンライナーがあったのでGaucheでもワンライナーで書いてみた。

だいぶ長くなったけどこんな感じ。

2013/03/20

2013/03/20

ターミナルに黒魔道士

こんなの見かけて、楽しそうだったのでやってみた。

ただ単にファイルから読み込んだ色情報を基に半角空白をansi escapeして表示してるだけ。

スクリプトはGaucheで書きました。エスケープの処理は以前クリスマスツリーを飾ったときに作ったものを流用。

Gaucheのバージョンはこれ。

 % gosh -V    
Gauche scheme shell, version 0.9.4_pre3 [utf-8,pthreads], x86_64-unknown-linux-gnu

ソースは以下。


追記

スクリプトを使わずに、ただ表示したければコレ↓をcatすれば表示されるかも。

gnu screenのスクリーンセーバーにしてみようかな。


追記

関係ないけど、ちなみに今は.screenrcに以下のように設定している。以前作った、ふぁぼった中からランダムに表示させるコマンド。

blankerprg favrand valvallow

追記

ワンライナー書いてみた。


追記