2020年3月10日火曜日

数独プログラム

 「 あらゆる数独パズルを解く」はPeter Norvigなのに、Pythonで書かれている。
 じゃあというわけでelispで書いてみた。

(2) ある値に対し、ユニットの中で置ける場所が1つしかないなら、その値をそこに置く。

 は、うまく動かなかったのでコメントアウトしているけど。
 それでも「 あらゆる数独パズルを解く」のページの問題はいちおう解けたからだいじょうぶだと思うけど。
 まぁ、よいか。

( defun  test ()
  ( progn (sudoku-init)
(sudoku-set  "
 . . 5 |3 . . |. . . 
 8 . . |. . . |. 2 . 
 . 7 . |. 1 . |5 . . 
 ------+------+------
 4 . . |. . 5 |3 . . 
 . 1 . |. 7 . |. . 6 
 . . 3 |2 . . |. 8 . 
 ------+------+------
 . 6 . |5 . . |. . 9 
 . . 4 |. . . |. 3 . 
 . . . |. . 9 |7 . . 
 ")
       (sudoku-solve)
       (sudoku-print)))

(benchmark 1 '(test))
| 1 4 5 | 3 2 7 | 6 9 8 |
| 8 3 9 | 6 5 4 | 1 2 7 |
| 6 7 2 | 9 1 8 | 5 4 3 |
|-------+-------+-------|
| 4 9 6 | 1 8 5 | 3 7 2 |
| 2 1 8 | 4 7 3 | 9 5 6 |
| 7 5 3 | 2 9 6 | 4 8 1 |
|-------+-------+-------|
| 3 6 7 | 5 4 2 | 8 1 9 |
| 9 8 4 | 7 6 1 | 2 3 5 |
| 5 2 1 | 8 3 9 | 7 6 4 |
 "Elapsed time: 0.179490s (0.093774s in 1 GCs)"

 ベンチマークもそこそこ。

2020年3月6日金曜日

dash.el(2)

 たとえば、(1 2 3)と(4 5 6)を組み合わせたい。

((1 . 4) (2 . 4) (3 . 4) (1 . 5) (2 . 5) (3 . 5) (1 . 6) (2 . 6) (3 . 6))

 みたいな感じに。
 そこで

( defun  y-combination-of-list (list1 list2)
   "list1の要素とlist2の要素を組み合わせた結果をconsして出力する。"
  ( loop for x in list1
        collect ( loop for y in list2
                      collect (cons x y))))

 というのをでっちあげた。でもこれだと結果は

(((1 . 4) (1 . 5) (1 . 6)) ((2 . 4) (2 . 5) (2 . 6)) ((3 . 4) (3 . 5) (3 . 6)))

 という風になってしまう。
 これを入れ子のリストではなく、フラットなリストにしたい。
 それで「 dash.el」の「-flatten」が必要だったのだけど。

(-flatten '(((1 . 4) (1 . 5) (1 . 6)) ((2 . 4) (2 . 5) (2 . 6)) ((3 . 4) (3 . 5) (3 . 6))))
((1 . 4) (1 . 5) (1 . 6) (2 . 4) (2 . 5) (2 . 6) (3 . 4) (3 . 5) (3 . 6))

 よくよく考えたら「dash.el」に、そもそもそんな関数があるんじゃないか? つらつら「 https://github.com/magnars/dash.el#functions」を見ていたら。

(-table-flat 'cons '(1 2 3) '(4 5 6))
((1 . 4) (2 . 4) (3 . 4) (1 . 5) (2 . 5) (3 . 5) (1 . 6) (2 . 6) (3 . 6))

 あった。

2020年3月5日木曜日

dash.el

 どのパッケージがきっかけでインストールされたのか、わからないけれど、「dash.el」がインストールされている。

;;; dash.el --- A modern list library for Emacs

 だそうだ。
 「-flatten」というのがあってお気に入り。

(-flatten '((1 2 3)(4 5 6)))
(1 2 3 4 5 6)

 で、素の ABCLを使っていて「flatten」が必要になった。
 「alexandria」をインストールすれば、いいんだろうが、諸事情というものがある。
 「dash.el」の「-flatten」が使えないもんだろうか。
 「–map」「–mapcat」「-mapcat」「-flatten」を喰わせてみたところ。

(-flatten '((1 2 3)(4 5 6)))
(1 2 3 4 5 6)

 動いた。

2020年3月3日火曜日

async.el

 helmをインストールすると、もれなくasync.elがついてくる。
 Emacsの非同期ライブラリである。
 バックグラウンドでEmacsをもうひとつ、立ち上げてそちらで処理させる、というもの。

( setq wrk (async-start
           ( lambda ()
             222)))
-- 割愛 --

(async-get wrk)
222

 システムモニタを立ち上げておくと、Emacsがもうひとつ、起動されるのがわかる。
 100個とか、無理だろうけど 1。

( setq wrk ( loop for x from 1 to 10
                collect (async-start
                         `( lambda ()
                            ,x))))
-- 割愛 --

( loop for x in wrk
      collect (async-get x))
(1 2 3 4 5 6 7 8 9 10)

 カンマを使えば、変数の中身を展開できるけど、さすがにクロージャーでデータを渡すのは無理だろうなぁ。別プロセスだもんなぁ。スレッドならできるのだろうけど。
 ——と思ったけれど、やってみたらできた。
 驚いた。

( setq lexical-binding t)
t

( defun  wrk (x)
  ( lambda()
    x))
wrk

( setq wrk ( loop for x from 1 to 10
                collect (async-start (wrk x))))
-- 割愛 --

( loop for x in wrk
      collect (async-get x))
(1 2 3 4 5 6 7 8 9 10)

 なんで?

(wrk 1)
(closure ((x . 1) t) nil x)

 ああ、クロージャーはリストに展開されるんだ。
 なるほど。それならpipe渡しでも可能だ。あれ? ということはelispだからできるってこと?
 ほえぇ。elispはあなどれない。

Footnotes:

1

Emacs for Windowsでは10個でエラーになった。

2020年2月28日金曜日

slime-transpose-lists

 たとえば

((1 2 3)
 (4 5 6)
 (7 8 9))

 を

((1 4 7)
 (2 5 8)
 (3 6 9))

 という風に縦横を変換したい。
 パッと考えて二重ループで……とごちゃごちゃ考えたのだけれど、面倒臭い。きっとどこかにありそうだ。elisp、CommonLisp関連でググってもなかなか、見つからず、きっと名前に「tranpose」が入っているにちがいない、と考えてEmacsの「describe-function」で見つけた。

(slime-transpose-lists LIST-OF-LISTS)

Not documented.

 まさにこれ。ソースを見たら

( defun  slime-transpose-lists (list-of-lists)
  ( let ((ncols (length (car list-of-lists))))
    ( cl-loop for col-index below ncols
             collect ( cl-loop for row in list-of-lists
                              collect (elt row col-index)))))

 やはり二重ループ。
 それでもLispだとたったこれだけの行数で書ける。
 というか、簡単に書けてしまうから標準でなかったのかも。

2020年2月27日木曜日

(file-expand-wildcards "**/*.*")

 ああ、知らなかっただよ。

(file-expand-wildcards  "**/*.*")

 で、カレントディレクトリの下のファイルが全部、取得できるとは。
 eshellの「**/*.*」はこれは使っているんだろうなぁ。
 今さら気づくおれ。

2020年2月24日月曜日

2020年2月22日(土):検見川浜:晴れ

1 Sail:CORE 5.7(NEIL PRYDE) Board:NG ACP 260 Fin:9.5inch

-No- 時刻 時間 帆走距離 最高速 平均時速 P%
1 11:49-11:57 8分 1.1km 29.59km/h 8.23km/h 25.62
2 12:28-12:36 8分 1.0km 34.76km/h 7.73km/h 14.77
3 12:46-12:56 9分 1.1km 16.94km/h 6.84km/h 0.56
4 13:22-13:35 13分 1.3km 22.09km/h 5.73km/h 3.24

total 39分 4.5km 6.9km/h

 夜中のうちにきちんとカメラの充電をしておいたのにハウジングを忘れてしまった。
 何をやっておるのか。
 海ほたる16m/sなのに、検見川は思ったよりも風が入っていない。沖合いに白波が見えるのだが。これでは最大サイズのセイルをだしても走らなそうだ。ここはやはり南総まで下るべきだったのだろうか。
 しかし、午後には風があがるだろうし、昨年に引き続き、いきなり4.7コンディションかぁ。
 とりあえず、目の前のコンディションにあわせて最大サイズのセイルをチョイスした。5.7である。
 体力がない自覚はあるのでかなり緊張して海へ出た。死なないように、と。
 毎年、体力の心配をしているけれど、今年は今までで一番、体力がない——三ヶ月絶対安静で入院していたときよりもない。あのときは退院して1週間ぐらいにそれなりに体力は回復した。今年はだめだ。
 案の定、一往復しただけで突っ伏して喉が痛くなるほど、ゼーハーしてしまった。
 たまたま、風に当たったらしく、プレーニングしたけれど。
 大休止して二本目。
 これもプレーニングできた。沈したけれど。
 三本目はほとんど、走らず。沖で沈して溺れかける。水面に浮かんでいる状態で深呼吸できず、酸欠になりかける。気を失なうか、と思った。去年も同じだったなぁ。
 ふたたび、風が上がってきたような気がしたけれど、出艇してみると、そんなことはなく、ふたたび、溺れかける。いかんじゃないか。
 なんか、午前中よりも風がない。
 夕方、吹き上がるパターンかな?
 でもまぁ、今日は終わりでいいか。

2020年2月12日水曜日

城平京/片瀬茶柴「虚構推理」(1)〜(6)

 読みはじめたらきっと一気に読んでしまうんだろうな。
 案の定で、ひと区切りの6巻まで買い進めながら読了してしまった。

2020年2月10日月曜日

elispでqueueもどき

 もしかしたら。
 threadとmutexの組み合わせたらキューっぽいことができるんじゃないだろうか?

( let ((lexical-binding t)
      (w (make-mutex)))
  (mutex-lock w)
  ( loop for x from 1 to  10
        collect
        (make-thread
         ( let ((y x))
           ( lambda()
             ( with-mutex w
               (insert (number-to-string y) " \n"))))))
    (mutex-unlock w))
nil
3 
4 
5 
6 
7 
8 
9 
10 
1 
2 

 処理順序は保証されていないけど、キューっぽいよな、これ。
 うん。

2020年2月4日火曜日

Ubuntuでの「ssh -Y」

  正月にUbuntuをいじっているときに気づいたのだけれど。

ssh -Y

 が使えた。
 きっとUbuntu Serverだからだろう、と思っていたのだけど、「Ubuntu 18.04.3 LTS」で試してみたら使えるようになっていた。以前、使えなかったのは何だったんだろう。
 とても助かるけれど、それなら 机の上にBeelinkS1をもってくることはなかったなぁ。

2020年1月31日金曜日

CD/DVD

 終活、というわけではないのだけど、CD/DVDを処分しはじめた。
 かつてハードディスクにはいり切らなくなったデータをCD/DVDへ焼きだしていたのである。当時のハードディスクは1Gとか、2Gとかそんなものでいい気になって保存していた。二十枚近くある。
 それでもこれだけのデータが今の——一世代前のだけど——、ハードディスクに納まってしまう。いったいあの日々はなんだったんだろう。
 しかも今はそもそもハードディスクに保存すること自体、なくなった。
 ネットがあるから。

 考えてみれば、かつてはフロッピィディスクが山ほどあったんだよな。処分してしまったけれど。DOS時代の遺物だ。データをフロッピィディスクへ吐き出していた。ハードディスクの容量が20Mで、むちゃくちゃ、大容量だと思っていた時代。

 そういえば、山ほどあったカセットテープも捨ててしまった。
 引っ越しで捨てざろう得なかったのだけど。
 かつてレンタルレコード店というものがあったのだ。まだ、CDもなく、ビデオテープも存在しなかったころ。ウォークマンが時代をつくった時代。
 そのあとに買い集めたビデオテープもすでに手元にはない。音楽CDもそうだ。iPhoneにいれてしまったので手元にもっておく意味がなくなってしまった……。

 思えば、あの日々はなんだったんだろう。
 それぞれの日々ではそれなりに一生懸命だったはずなのに。
 いろんなものを手元に残そうとしていたのに。
 今や何も残っていない。

2020年1月30日木曜日

128Gがふっ飛んで右往左往

 不安はもろもろあったのだけれど、BeelinkS1の 内蔵ディスクを128Gにした。
 それでようやく重い腰をあげて 本格的に使おうか、と26Gもあるファイルをscpでコピーしていたら突然、動かなくなった。sudoも効かない。何? 何? 何が起きたの?
 何が起きているのか、さっぱりわからず、いろいろやってみていたら——あれ? ホームディレクトリが空っぽになっている。
 ZFSがまた、ぶっ壊れた。

 ところが翌日になると、うまく動いた。
 また、熱ダレだったか、と思って使っていると、ふたたび、おかしくなった。
 やはりだめだ。
 とりあえずBeelinkS1はWindows10として使うか。
 でもhome editionなのでRDPが使えない。
 クライアントとして使うしかない。しかたないのでマシン本体を机の上にもってきた。これがほんとのデスクトップ。なんちゃって。でももしかしたら使えるかもしれないので、FreeBSDをいれていたSSDにフォーマットをかけた。
 20GのDドライブができた。
 ——?
 128Gじゃない。
 何度、見直してみても20G。やりなおしても20G。ほんとうに壊れてしまっていたらしい。
 しかたがない。

 問題はWindows10とMacのやりとりだ。
 もちろんネット的にはつながる。けれど、26Gなんて馬鹿でかいファイルの転送はさすがに時間がかかりすぎるので外部記憶装置が必要だ。
 昔、使っていたお立ち台をひっぱりだす。
 160Gのハードディスクを突っ込んでNTFSでフォーマット。
 これでMacとWindows10でやりとりできるはずだ。
 Macにつなげて試した——ところがreadonlyだった。書きこめない。昔、読み書きができたように思っていたのだけど。どうやらかんちがいだったらしい。うーん、これはこまった。これじゃ、Windows10からMacへの一方通行しかできないじゃないか。今、やりたいのは逆方向のMacからWindows10なのだが。
 なのでexFATでフォーマットしなおした。
 これなら両方で読み書きできる。

 FreeBSDのSSDを納めていたスロットにはもうひとつ余っている128GのSSDをいれた。
 これはNTFSでフォーマットしてDドライブとして使うことにした。
 ほか、いろいろと設定をしているうちに、Macから操作ができないことに嫌になって、思わず、以前いれた Ubuntuをインストールしてしまった。128GのSSDに。
  UbuntuならVNCでMac上に表示できるからMacから操作できる。
 いちいちディスプレイをスイッチする必要がなくなる。
 いい考えだと思ったのだけれど、UbuntuはexFATを認識してくれなかった…… 1。
 それで頭に来てお立ち台のハードディスクをNTFSでフォーマットしなおしてしまった。
 UbuntuはNTFSを読み書きできるけど、Macはreadonlyなんだから、元の黙阿弥ではないか。
 ——なんでおれは後戻りのできない性格なんだろう……。
 でも勝算はなくもなかった。
 Windows10はできないけれど、UbuntuはHFS+を読めるのである。readonlyだとしても。
 当然、MacはHFS+を読み書きできる。
 実はお立ち台はもう一台あってそれは現役でMac用に使用中。フォーマットはHFS+。
 2台あるお立ち台はいずれもMac、Ubuntu間では一方通行だけど、互い違いなのでデータの往復が可能なのである。
 ちょっと面倒ではあるけれど。

Footnotes:

1

きっと方法はあるのだろうけど、FreeBSDなら一生懸命探すのにUbuntuだと、見当らない、というだけであきらめてしまう。よくない傾向だ。

2020年1月29日水曜日

めも VirtualBox

 BeelinkS1のFreeBSDにVirtualBoxを「pkg install」した。
 installしたときに、設定方法が表示されたのでその通りにやれば、よかったのだけど、ゲストOSにメモリが1Gしか、割り当てることができなくて死んだ。

Message from virtualbox-ose-5.2.34:

–
VirtualBox was installed.

You need to load the vboxdrv kernel module via /boot/loader.conf:

vboxdrv_load="YES"

You also have to add all users to your vboxusers group in order to use vbox.

% pw groupmod vboxusers -m jerry

Reboot the machine to load the needed kernel modules.

Bridging Support:
===============

For bridged networking please add the following line to your /etc/rc.conf:

vboxnet_enable="YES"

USB Support:
==========

For USB support your user needs to be in the operator group and needs read
and write permissions to the USB device.

% pw groupmod operator -m jerry

Add the following to /etc/devfs.rules (create if it doesn't exist):

[system=10]
add path 'usb/*' mode 0660 group operator

To load these new rule add the following to /etc/rc.conf:

devfs_system_ruleset="system"

Then restart devfs to load the new rules:

% /etc/rc.d/devfs restart

Troubleshooting:
==============

Running VirtualBox as non-root user may fail with a fatal error
NS_ERROR_FACTORY_NOT_REGISTERED. In this case delete tmp.vbox-*-ipc file.

If you experience "Network: write Failed: Cannot allocate memory" errors
try to increase net.graph.maxdata in /boot/loader.conf

If you are using AIO, then increase these limits (PR#168298):
vfs.aio.max_buf_aio=8192
vfs.aio.max_aio_queue_per_proc=65536
vfs.aio.max_aio_per_proc=8192
vfs.aio.max_aio_queue=65536
To check if AIO is used use: kldstat -v | grep aio

Check wiki page for known issues and troubleshooting:
http://wiki.freebsd.org/VirtualBox

Please report any problems to emulation@. Thanks!
$

2020年1月28日火曜日

flet(2)

 cl-fletがあれば、レキシカルスコープとあわせてコードを分離できるじゃないか。「use」できないけれど、簡単なパッケージみたいなもんだよなぁ。よろこんで多用していたら——。
 あれ? 再帰呼び出しができない。ふうん、「cl-labels」を使え、ということらしいな。

FUNC is defined only within FORM, not BODY, so you can’t write
recursive function definitions. Use ‘cl-labels’ for that. See
info node ‘(cl) Function Bindings’ for details.

 ふむ。

2020年1月27日月曜日

Org-mode:(org-element-context)

 Org-modeでカレント行のTAGを取得したいことがあって自前でいろいろやっていたんだけれど。

(org-element-context)

 で取得できることに気づいた。
 こりゃあ、いい。

2020年1月24日金曜日

Org-mode:(org-edit-special)

 Org-modeは高機能だということは知っていたけど——だから知らない機能がけっこうあって。
 たとえば、よくソースの断片をメモしているのだけれど。

#+BEGIN_SRC elisp
(messge "ERROR")
#+END_SRC

 Org-modeの中だと、メジャーモードの機能が使えないので、別のところで修正してカット&ペーストでもってきたりしていた。
 ところが「Ctrl+'」とやると、別バッファで開いてくれる。そのうえ、指定したモードにしてくれる。上の例だと「elisp-mode」 1になる。

 これの何がいいのか、というと、SRCで指定しているモードは、Emacsのメジャーモードならなんでもいいはずなので、picture-modeとか、指定できるのだ。SRCの外だと、書いたpictureは勝手に整形されてしまうからこれは重宝する。
 SRCの中に置いておいて修正するときは「Ctrl+'」とやるわけ。

#+BEGIN_SRC picture
  -------+
         |
   <=====+
#+END_SRC

 もちろん、Org-modeも指定できるわけで無意味だけど、それはそれでおもしろい。

Footnotes:

1

正確には(emacs-lisp-mode)。

2020年1月23日木曜日

helm (2)

  helmが好きだ。
 これがあるだけでEmacsから離れられない。最近は自前のものまでカスタマイズする始末。

 たとえば、業務系のプログラム開発の現場だと、設計書はExcelで書かれていたりする。ファイル名にプログラムIDと機能名をつけたりしてね。プログラムIDは8桁のコードだったりして、けっこう泣ける。
 今時? とか、思うのだけれど、下っ端がいってもかわるものではなく——。
 プログラムIDがでてくるたびに一覧を探し出して、検索して機能名を調べたりするわけだ。
 ——めんどくさっ。
 なのでhelmにぶち込んだ。

 Emacsを立ち上げるときに設計書のフォルダを検索して生成したファイル一覧をhelmの「:sources」にする。ファイル一覧をプログラムIDと機能名の一覧にするわけだ。それをhelm検索する。
 これでプログラムIDをいれるだけで(中途半端でも可) 1、機能名がわかる。逆に機能名からプログラムIDも引ける。
 それをプロジェクトごとにつくってやると、なんと簡単な自前のデータベースができあがった。
 一覧をメンテナンスする必要がないところが、これのいいところ。
 「:preselect」でExcelで表示するようにしておけば、必要なときに設計書の参照もできる 2。

 そうやってつくった複数の 3helmのデータベースをひとつのhelmのコマンドにまとめておけば、横断的に検索することもできる 4。すばらしい。

 でもおかげでプログラムIDを全然、覚え切れない。

Footnotes:

1

カーソルのある位置の単語でまず、絞りこむこともできる。

2

「:select」だと、つねにExcelが立ち上がるので。それはそれでわずらわしい。

3

テーブル一覧とか。これは裏でjava——正確には ABCL——をつかってExcelから抽出した。

4

複数のsourceは「Ctrl-o」で渡り歩くことができる。

2020年1月22日水曜日

loopマクロ

 たとえば、あるlistの中から奇数だけを抽出したい、というとき。

wrk
(1 2 3 4 5 6 7 8 9 10)
(loop for x in wrk
      collect
      (when (oddp x)
        x))
(1 nil 3 nil 5 nil 7 nil 9 nil)

 こうやると、nilがまじってしまう。このケースだと、remove-ifを使えば、いいのだけの話なのだけど——loopマクロでこんな風にしていた。

(loop for x in wrk
      append
      (when (oddp x)
        (list x)))
(1 3 5 7 9)

 なんかいまいちだなぁ。
 なんとこうできるのだった。

(loop for x in wrk
      when (oddp x)
        collect x)
(1 3 5 7 9)

 すげえな、loopマクロ。