ときどきの雑記帖 RE* (新南口)
10月はたそがれの国
今週のしずえさん
ドイツでは釣りをするのに国家資格が必要
海中電柱
とある本を読んでいたら、三浦(海岸、半島)に「海中電柱」があると読める部分があったのだけど、 あれって木更津の方じゃなかったっけ?(そしてそれもなくなりつつある)
excel
以前こういうことを書いていた のだけど
みんな大好き(?) Excelで、セルの高さや幅を大きくしてやたらと文字を詰め込みたがる人が わりといるじゃないですか(いない?)。 アレ、スクロールするときに「セル単位」に表示が切り替わるので あまり大きくされると見づらくなっていやなんだよねえ。 以前、セルに写真を直接貼り付けて(当然高さも幅もそれなり)作られた「データベース」を 押し付けられて往生したことが。
ついにピクセル単位のスクロールができるようになるらしい。
Windows版のMicrosoft Excelにスムーズスクロール導入へ | TECH+
Microsoftは現地時間2021年10月7日、Windows版のMicrosoft Excel(以下、Excel)にスムーズスクロールを導入する予定があることを明らかにした。 Office Insiderのベータチャネル、および最新チャネル(プレビュー)で配信済みのバージョン2109(ビルド14430.20000)から段階的に利用可能になる。 公式ブログによれば、マウスのホイールボタンやタッチパッドのジェスチャーを利用すると、数行ごとではなく1ピクセル単位でスクロールできる。
嬉しいことではあるんだけど、これでセル結合拒否の理由が一つ減ってしまう?
紀伊國屋書店 新宿本店
【8階PC】三宅陽一郎先生待望の新刊!
— 紀伊國屋書店 新宿本店 (@KinoShinjuku) October 13, 2021
『戦略ゲームA I解体新書』(税込2980円、翔泳社)入荷しております!
コンピュータ書売場は9月30日から4階から8階へ移動して参りました。ゲームプログラミングの棚はD01はこんな棚・・・エレベーター前のワゴンでもオススメ新刊として展開中です!HRD pic.twitter.com/zkCQnve4DI
今週かなり久しぶりにこの紀伊國屋書店 新宿本店に行ってきたのだけど、 コンピュータ関係や数学、理工学の本の売り場が移動しているのを知らずに いつものように4Fに行ってびっくりしたのであった。
エレガントな解答もとむ
バイト&ワードの風にのって のつづき。
の中にこの種の文字列を求めるものがありました。 家のどこかにこの本まだあるはずなんですが、すぐに出せそうにないので確認できません。
古い本なので図書館にもないだろうなと思いつつも検索してみると、 国会図書館と都立中央図書館(の多摩の方)にはあるようです。
国会図書館
ということで利用者登録もしていたので国会図書館に行こうかと考えつつも、 緊急事態宣言で事前予約が必要になっていたのでどうしたものかと 迷っていたところ、 10/4からは事前予約なしでも入館可(ただし時間帯に制限あり) になったと聞いたので じゃあととある用事で有給休暇を取った日についでに行ってきました。
利用者登録していた。と書きましたが、前回の利用から時間が開きすぎていて なんと expire されていました(そんなに長いこと(3年以上)行ってなかったとは思わなかったw) ので、再登録をしてから入館。
コロナの影響で食堂が閉店してしまったのは知っていましたが、 他にも色々と変わっていて(以前通れたはずの通路が通れなくなっているとか) かなり面食らいました。
という余談はこれくらいで。
エレガントなコンバータ
さて、問題の記事はP.60からの「エレガントなコンバータ」にありました。
以下に文章も適当に引用しつつプログラムを紹介します。
いま、文字形(ママ)で表された16進数を同じく文字型の2進数に変換するプログラムを考える。 たとえば「A」が「1010」に変換されるというコンバータである。 このプログラム例は次のようになる。
10 '*** HEX to BIN conversion *** 20 H$ = "0---1---2---3---4---5---6---7---8---9---A---B---C---D---E---F---" 30 B$ = "0000000100100011010001010110011110001001101010111100110111101111 40 INPUT HX$ 50 PTR = INSTR(H$, HX$) 60 IF PTR<>0 THEN PRINT MID$(B$, PTR, 4) 70 GOTO 40
たとえば、40行で「2」が入力されたとする。50行のINSTR文にて、その 文字がH$という文字列の何番目にあるかを調べると、9番目である。そこ で60行により、文字列B$ の9番目からの連続する4文字を取り出せる。そ れが2進数となる、"-“は0~Fの文字位置を調整するためのダミーである。
むろん、このプログラムは完全に動作する。しかし考えてみると”-“は無 駄な文字である。これを少なくし、H$とB$をもっと短くできないだろうか。 つまり、もう少しエレガントなコンバータにできないだろうかというわけだ。
と、以前書いたように最初は16進のデータも2進のデータも 4*16で64文字分あります。
ところでH$の文字列はなにも0123…と順序良くならんでいなければならない ことはないから、効率よく順番を入れ替えると、次のようにすることもできる。
20 H$="01248-36C9-5A-B7FED" 30 B$="000100011001010111101"
これでH$は19文字になった。 さて、完全に無駄のない、H$が16文字の形はできないだろうか。 ここまで解がにつまってくると、もう試行錯誤では難しいが、その解は 次のようになる。
20 H$="0137FEDA5B6C9248" 30 B$="0000111101011001000"
このほかにも解はある。
20 H$="0124936DA5B6FEC8" 30 B$="0000100110101111000"
を例にとり、どのように文字列B$を得たかを説明しよう。
まずはじめに、すべてが0ではない4ビットのパターン、たとえば0001を設定する。 そして、最初の2ビットのexclusive OR(排他的論理和)をとって、 その結果を第5ビットとする。次は第2ビット目と第3ビット目のexclusive OR を とって、第6ビットとする。以下、同様の操作を繰り返していく。 すなわち、下図のようになる。
0 0 0 1 0 0 1 1 0 1 0 1 1 1 1 0 0 0 1
ここで最後の4ビットに注目してもらいたい。 その文字列は0001となっており、これははじめに設定した4ビット0001と 同じである。だから、このあとはこれまでの15ビット周期のパターンが繰り返される ことになる。この15ビットのパターンには0000以外の4ビットの2進パターンが すべて含まれる。
これに対して、5番目の解はちょっと見方を変え、1ビット目と4ビット目の exclusive OR をとって第5ビットとしたものである。
XORを使っていたという記憶は間違っていませんでした😄
なお、ここでいう「5番目の解」というのは
0137FEDA5B6C9248
のことです。
「最初の2ビット」(1ビット目と2ビット目)と 「1ビット目と4ビット目」を使った例が出ていたのですが、 4ビットから任意の2つのビットをとる組み合わせは6個あるから ほかのものはどうなるのだろうかと Rubyスクリプトを書いて確かめてみたところ…
def make_sequence(seed, pos1, pos2)
result = Array.new(15+3)
seed.each_with_index do |n, i|
result[i] = n
end
4.upto(14+3) do |n|
result[n] = result[n-5+pos1] ^ result[n-5+pos2]
#result[n] = result[n-4] ^ result[n-3]
#result[n] = result[n-4] ^ result[n-1]
#result[n] = result[n-4] ^ result[n-2]
#result[n] = result[n-3] ^ result[n-2]
#result[n] = result[n-3] ^ result[n-1]
#result[n] = result[n-2] ^ result[n-1]
end
result
end
seed = [0,0,0,1]
[1,2,3,4].combination(2) do |n1, n2|
seq = make_sequence(seed, n1, n2)
hexs = seq.each_cons(4).collect{|bits| bits.join.to_i(2).to_s(16) }
printf "[#{n1},#{n2}] %s %s %s\n", seq.join, hexs.join, hexs.sort.join
end
[1,2] 000100110101111000 124936da5b7fec8 123456789abcdef
[1,3] 000101000101000101 125a48125a48125 1112224455588aa
[1,4] 000111101011001000 137feda5b6c9248 123456789abcdef
[2,3] 000101110010111001 125b7ec925b7ec9 122557799bbccee
[2,4] 000111010011101001 137eda4937eda49 133447799aaddee
[3,4] 000110110110110110 136db6db6db6db6 1366666bbbbdddd
…あれ?
で
残念ながら(エッセイという体裁のせいもあってか) 記事には参考文献などの情報もなく、 どこからこのアイデアが出てきたのだろうか という問題は残ったままなのですが…(続く)
sed
sedで複数行を置換、挿入したいとき【sed, Shell】 - Qiita
という記事に
やりたいこと
次の2つのファイル(文字列)がある
source
hogehoge hugahuga hogahoga hugehuge
target
AAAAAA BBBBBB CCCCCC FLAG DDDDDD EEEEEE
このときにtargetのFLAGの部分をsourceの内容で置き換えたい。 つまり、
result
AAAAAA BBBBBB CCCCCC hogehoge hugahuga hogahoga hugehuge DDDDDD EEEEEE
こんな感じ。 これが少し面倒で、詰まったので書き残す。
というのがあって、↓のようなスクリプトがあったのだけど
str=`cat source | # 挿入する文字列を読み込み
sed -r 's/$/\\\\n/' | # 各行の末端に改行文字を入れる
sed -r '$s/\\\\n//' | # 最終行の改行文字に関しては必要ないので取り除く
while IFS= read -r line # 1行ずつ読み込み
do
echo -n "$line" # echo -nで各行を改行しないで出力->1行にまとめる
done`
cat target |
sed -r "/^FLAG$/s/.+/$str/" # sedで必要な部分に挿入(置換)
これ、rコマンド使えば短く書けるんじゃなかろうか。
r filename
Reads file filename.
kbk@toybox4:/mnt/c/Users/kbk$ cat i.txt
1
2
3
kbk@toybox4:/mnt/c/Users/kbk$ cat t.txt
aaa
XXX
ccc
というのを用意しておいてからこうすると
kbk@toybox4:/mnt/c/Users/kbk$ sed -e '/XXX/{
> r i.txt
> D
> }' t.txt
aaa
1
2
3
ccc
実は最初、クォート中で改行せずに書いたところエラーになってしまい しばらく悩んだ。
kbk@toybox4:/mnt/c/Users/kbk$ sed -e '/XXX/{ r i.txt ; D}' t.txt
sed: -e expression #1, char 0: unmatched `{'
これ、どうもGNU sed (バージョンを確かめたら4.4だった)のバグらしい?
というのも、まずエラーメッセージがソースコードの どこにあるのかを確かめて
compile.c:117: "unmatched `{'\0"
compile.c:150:#define EXCESS_CLOSE_BRACE (EXCESS_OPEN_BRACE + sizeof (N_("unmatched `{'")))
sed.compile.c
/* Various error messages we may want to print */
static const char errors[] =
"multiple `!'s\0"
"unexpected `,'\0"
"invalid usage of +N or ~N as first address\0"
"unmatched `{'\0"
"unexpected `}'\0"
省略
#define BAD_BANG (errors)
#define BAD_COMMA (BAD_BANG + sizeof (N_("multiple `!'s")))
#define BAD_STEP (BAD_COMMA + sizeof (N_("unexpected `,'")))
#define EXCESS_OPEN_BRACE (BAD_STEP \
+ sizeof (N_("invalid usage of +N or ~N as first address")))
#define EXCESS_CLOSE_BRACE (EXCESS_OPEN_BRACE + sizeof (N_("unmatched `{'")))
省略
それを使っているところを探し
/* Make any checks which require the whole program to have been read.
In particular: this backpatches the jump targets.
Any cleanup which can be done after these checks is done here also. */
void
check_final_program (struct vector *program)
{
struct sed_label *go;
struct sed_label *lbl;
/* do all "{"s have a corresponding "}"? */
if (blocks)
{
/* update info for error reporting: */
memcpy (&cur_input, &blocks->err_info, sizeof (cur_input));
bad_prog (_(EXCESS_OPEN_BRACE));
}
特に変なところはないがblocksという変数がちょっと引っかかる。 これを追いかけて行ってもいいのだけど 先にrコマンドの処理部分を確かめてみる。 すると
case 'r':
b = read_filename ();
if (strlen (get_buffer (b)) == 0)
bad_prog (_(MISSING_FILENAME));
cur_cmd->x.fname = xstrdup (get_buffer (b));
free_buffer (b);
break;
/* Read in a filename for a `r', `w', or `s///w' command. */
static struct buffer *
read_filename (void)
{
struct buffer *b;
int ch;
if (sandbox)
bad_prog (_(DISALLOWED_CMD));
b = init_buffer ();
ch = in_nonblank ();
while (ch != EOF && ch != '\n')
{
#if 0 /*XXX ZZZ 1998-09-12 kpp: added, then had second thoughts*/
if (posixicity == POSIXLY_EXTENDED)
if (ch == ';' || ch == '#')
{
savchar (ch);
break;
}
#endif
ch = add_then_next (b, ch);
}
add1_buffer (b, '\0');
return b;
}
なんじゃこれ。
z
GNU sedのドキュメントを読み返していて気がついたのだけど zコマンドなんてのがあったのね。
z
(zap) This command empties the content of pattern space.
ドキュメントの他の部分にはこう書かれているので GNU による拡張っぽい。
s/.*// does not clear pattern space
This happens if your input stream includes invalid multibyte sequences. POSIX mandates that such sequences are not matched by ‘.’, so that ‘s/.*//’ will not clear pattern space as you would expect. In fact, there is no way to clear sed’s buffers in the middle of the script in most multibyte locales (including UTF-8 locales). For this reason, GNU sed provides a ‘z’ command (for ‘zap’) as an extension.
To work around these problems, which may cause bugs in shell scripts, set the LC_COLLATE and LC_CTYPE environment variables to ‘C’.
追記
rコマンドの動作はきちんとドキュメントに書かれていた。
3.8.1 Commands Requiring a newline - sed, a stream editor
The following commands cannot be separated by a semicolon and require a newline:
r,R,w,W (reading and writing files)
The r,R,w,W commands parse the filename until end of the line. If whitespace, comments or semicolons are found, they will be included in the filename, leading to unexpected results:
$ seq 2 | sed '1w hello.txt ; 2d' 1 2 $ ls -log total 4 -rw-rw-r-- 1 2 Jan 23 23:03 hello.txt ; 2d $ cat 'hello.txt ; 2d' 1
sourceforge はなぜ github になれなかったのか問題、色んな所にある気はするな
— (Ǝ)ɐsıɥıɥso⅄ ouɐɓnS (@koshian) October 4, 2021
これは世界で自分一人しか書けない内容だろうな。最初から最後まで付き合ったの自分だけだから。
— Shuji Sado (佐渡 秀治) (@shujisado) October 8, 2021
で、根本は単なるオープンソース支援のサービスでしかないものを経営の都合で収益を出せという話になったことと、株主が文句言う度に体制が変わって前時代を全否定することを何度も繰り返したことだな。 https://t.co/AwSsVXB8YP
ジョから始まるファミレスと問いかけてジョナサンが出てくるかジョイフルが出てくるかを予想する遊び。
— yoh2 (@yoh2_sdj) April 25, 2021