kdoo

書いてる人: ょゎ
hatena:id:yowa, Twitter/yowa, Gmail:yowaken
«前月 最新 翌月» 追記

2007-09-01 [長年日記]

>> yowaken.dip.jp このエントリを含むはてなブックマーク

saronpasu さんとこに コメントできなかったのでここに。

  • 平均一日一回ペースくらいの不定期で回線が途切れる
  • 一回切れると最低一時間くらい不通になる

というとほほな環境なので、つながらない時は気長にお待ち下さい。 まあ、無期限停止の可能性もありますが……。

本日のツッコミ(全1件) [ツッコミを入れる]

>> saronpasu [なるほど!そういう事情だったンディスカー!]


2007-09-02 [長年日記]

>> [チラシの裏] やっぱ DS 欲しい このエントリを含むはてなブックマーク

テトリスオンラインも十分楽しいゲームだが入力落ちでストレスがたまる。 テトリス DS やりたい。

とゆーかテトリスオンラインに限らず、パソ用ネット対戦ゲーをやっては 「マシンのスペックのせいで上手く動かせない」的な言い訳をしてる 自分にムカつくので、さっさと対等な条件の下で叩きのめされるべきだと思う。

>> ゴルフ このエントリを含むはてなブックマーク

あなた…また休日はゴルフなの。。。私よりゴルフの方が大事なのね会にお声をかけていただいたものの、

  • 引きこもりだから。(今年こそは外出回数を一ケタに収めるぞ!(外出回数ゴルフ))
  • 最近ゴルフやってないから。(千数百連休中なのにゴルフってないだなんて、ゴルフより休日の方が大事なのね!)
  • というか東京は無理。(行動範囲はがんばって福岡−熊本間)

という理由で不参加表明。

>> [Memo] さしえショー このエントリを含むはてなブックマーク

さしえショーとは,入力した文章に勝手に挿絵をして紙芝居を作るものです.

さしえショー

この発想はなかった。素晴らしい。


文章を入力すると、

  • 文章を区切って
  • 形態素解析してキーワードを抽出
  • 「Yahoo!検索」の画像検索のAPIを使って
  • マッチする画像を表示

ということらしい。


「形態素解析」「キーワード抽出」「画像検索」という三段重ね構造で、 各要素とも精度が(そこそこ高いけど)それほど高いわけではないので、 三つ掛けるとびみょーな結果*1 になるというのが残念なところ。

ボケと言えば、画像がボケてるのは API の制約として仕方ないか。


まあ一番のキモは、画像検索(キーワードから画像へのマッピング)だろうな。

形態素解析は(キーワードになりそうな)名詞を拾うには十分な精度があるだろうし、 キーワード抽出はピントのずれた抽出結果でも 「そこを拾ったのかよ!」的なツッコミを想起するボケとして機能する。 ただキーワードと画像の関連が不明瞭だと「……へ?」となる、と。


違ったアプローチとして。

「画像を自前で用意しつつ(とりあえず100種もあれば万々歳)、 ユーザによるタグ付けで何とかする」というのもアリそうだ(ボケ用途としては)。

「入力されるキーワードが何種類あると思ってんだ。 ユーザによるタグ付けだなんて実用に足るわけないだろ!」という (至極もっともな)指摘があるわけだが、 少なくとも私は「いや、意外と何とかなると思うよ?」と答えますよ、 自動学習型人工無脳の作者として。

あーこのネタは、スライドショーというより 4 コマ漫画的に使うのがいいかな。

みたいな雰囲気で。


画像でなくて、AA を使うという手もある。


だれかがんばれ。

続き(?): 2007-09-04#p02

*1 まともさという視点でも、ボケという視点でも


2007-09-03 [長年日記]

>> 穴ゴル参戦 このエントリを含むはてなブックマーク

してみよっかな。


Ring worldをやってみた。


2007-09-04 [長年日記]

>> [チラシの裏] いろんな言語に手を出してみよー! このエントリを含むはてなブックマーク

せっかく穴ゴルをやるなら、Ruby 以外の言語にも挑戦しなきゃもったいない (気がする)。

「正直 Brainfuck でのプログラミングって煩雑なだけで面白さはないよねー」 という認識なのだけども、そんなこと言えるほど Brainfuck を使ってないので 強化月間(週間になる可能性もあります)。

あとUnlambdaKEMURI に触ってみる。KEMURI は穴ゴルには無いけど(入力を扱えないし)。

k16's note の一連の記事 (1, 2, 3) を読んでから PostScript が気になってたんだけど、 仕様が(上に書いた言語より)大きすぎてなかなか手が出ない。


まずは Brainfuck で "Hello, world!" をやってる。 なんとか 114B まできたけど、 あと 20B も削れる だなんて信じられないお。

>> [Memo] おまもりんごさん このエントリを含むはてなブックマーク

はてブ経由で「おまもりんごさん」というソフトを知る。

ビジュアライザでこういうのは思いつかなかった。


こないだメモったさしえショーと通ずるものがある。 さしえショーもある意味ビジュアライザだよな。


間を取ると、入力したテキストに応じてキャラが動くソフトというのが考えられる。

「命令するとその通りに動く」や 「話しかけるとそれに合ったリアクションをする」ではなく、 もっとユルい関連性で。

「ブラウザでいま見てるページのテキストに応じて」だと (いわゆる)ビジュアライザっぽさが増すな。

>> [チラシの裏] 『オンナノコになりたい!』 このエントリを含むはてなブックマーク

表紙を見てひねもすのたりっぽいなあと思ったら、合ってたらしい。


2007-09-05 [長年日記]

>> [チラシの裏] 小学校の出席番号は誕生日順だった @ 熊本県 このエントリを含むはてなブックマーク

男女別々なので「男子の1番」「女子の1番」があった。


2007-09-06 [長年日記]

>> [穴ゴル] Brainfuck やってると横道にそれる このエントリを含むはてなブックマーク

Brainfuck のコードを書くんじゃなくて、 Brainfuck のコードを(半)自動生成するコードを書きたい欲望にかられる。


欲望に負けた。

>> [穴ゴル] 100 このエントリを含むはてなブックマーク

英語で0から100まで数えましょう問題 ができてた。

Ruby で暫定一位とれたよー。209B。

flaたんに抜かれた。抜き返した。203B。

前flaたんと alnum が 9B 違うのが気になる。

201Bきたこれ。

199B。


2007-09-07 [長年日記]

>> 純粋関数型言語 Unlambda このエントリを含むはてなブックマーク

前に書いたように Unlambda に手を出してみる。

公式から unlambda-2.0.0.tar.gz をダウンロードして、cygwin で

$ tar zxvf unlambda-2.0.0.tar.gz
$ cd unlambda-2.0.0/c-refcnt/
$ gcc -o unlambda unlambda.c

して処理系のでき上がり。 c-refcnt/ じゃなくて c/ の方は Boehm GC が必要。


日本語解説サイトの チュートリアル を読……むと負けなのでできるだけ読まないようにしつつ、 関数リファレンスを見ながら試行錯誤。


(知識としては知っていた)SKK = Iってこういうことだったのか!


リファレンスが分かりにくい(| とか)ので公式の方を見る。


(いつもどおり) continuation でわけわかんなくなってきたので、 Hello, world! に挑戦。

39B はできたけど、 そっから先が見当もつかない。

あーいや見当はついてんだけどどう実現するのかが見えない。


2007-09-08 [長年日記]

>> [チラシの裏][Unlambda] 時間感覚がおかしい このエントリを含むはてなブックマーク

昨日の日記に書いてるってことは、Unlambda 始めたのは 24 時間以内ってことか?  「やる気なくして←→ちょこっとやって」のサイクル数から考えると 二、三日経ってる感じ。

>> [Tetris] TGM3 認定モードに挑戦ムービ このエントリを含むはてなブックマーク

以前の予告どおり、 アリカのサイトに公式動画が うpされてる。

速いのはもちろんなんだけど、その積みの綺麗さに見入ってしまう。 そして消えロール速すぎ。


最近うpされた(公式でない)動画のまとめ記事。ありがたやありがたや。

>> [Unlambda] 負け このエントリを含むはてなブックマーク

サンプルコードを見て解読することにした。

>> [Ruby] これ → [*a] このエントリを含むはてなブックマーク

a=[]
[*a]<<1
p a    #=> [1]

[*a]を破壊したら a まで変わるのはバグなんじゃないかと思う。

a=[]
p a.object_id == [*a].object_id  #=> true

同じオブジェクトとな。

>> [Ruby] "string"[/str/] = :not_string このエントリを含むはてなブックマーク

1.9で落ちた。

$ ./ruby -e '"string"[/str/]=:not_string'
-e:1: -- control frame ----------
c:0004 p:---- s:0011 b:0011 l:000010 d:000010 CFUNC  :[]=
c:0003 p:0015 s:0006 b:0005 l:000004 d:000004 TOP    -e:1
c:0002 p:---- s:0003 b:0003 l:000002 d:000002 FINISH :inherited
c:0001 p:---- s:0001 b:-001 l:000000 d:000000 ------ 
---------------------------
DBG> : "-e:1:in `<main>'"
[BUG] Segmentation fault
ruby 1.9.0 (2007-09-08) [i386-cygwin]

>> [穴ゴル] いろいろ このエントリを含むはてなブックマーク

Unlamda がちんぷんかんぷんなので、Ruby で過去問をてきとーに。

トップタイ多数に並ぶだけなので submit せず。

いまこれ。

謎のバイナリ1Bが入ってると思ったら、改行が\r\nになってた><

72B まで来たけどあと 1B が……。

73B → 72B は、初めて思いついたテクを使った。 これを使えば CodeGolf も何問か削れる気がする、けど確認 & submit がめんどい。

今日は 19 時からゴ会らしいので、その時間には 穴ゴル場に引きこもろう

すなーおな方法しか思いつかない。74B。

小手先で 68B。 ゴルフで初めて #! を使って 67B。

あー、すなーおだけど遠回りしてた。57B。

おっけートップに並んだ。55B。

それ以上削る気力はない。

92B。どうやったら50Bを切れるのか見当もつかない。

74B まできたけど。アルゴリズムを見直さないとダメなんだろうな。

あいはぶのーあいでぃあ。寝るる。

>> [穴ゴル] いろいろ(2) このエントリを含むはてなブックマーク

19:40。寝すごした。

palindromize 続き。

50B ができた! ……と思ったら鯖では動かず。 入力の最終行は改行が入ってないのか。 対応したら 63B に。

57B → 53B → 52B → 50B 。

気分転換に Brainfuck で 100。

入力の構造を利用せずに(「one は何回も出てくるから取っておこう」とかせずに) 4250B とか。入力が 1042B だから一字当たり 4B 弱で作れてる計算に。

こちら第二会場でも発泡酒とか飲んでます。

さて、単純ループ以上の構造を持ったプログラムって書いたことないんだが(えー)。

ループやジャンプの効率的な書き方が分からない。 このままでは 4B/char 以上のパフォーマンスが出ない気がしてきたので pending。

encode するスクリプトの効率を上げることにする。

本日のツッコミ(全1件) [ツッコミを入れる]

>> ささだ [ぜひ-devに>SEGV]


2007-09-09 [長年日記]

>> [穴ゴル] Minus このエントリを含むはてなブックマーク

-= な言語。

Hello, world! で みんな 30B 切ってるけど、13×4文字(o123)かかるんじゃないの??

あー Input Separator を見落としてた。!以降に生文字列を埋め込めるのか。

26B きた。

24B な御二方はバイナリが入ってるのが気になる……。

はっ! もしや……。

やっぱりそういうことか。24B。

>> [穴ゴル] いろいろ このエントリを含むはてなブックマーク

何やってたか忘れた。

recent entries を grep したら、 09/09 付けのは

100               Brainfuck
The Golden Ratio  Brainfuck
e                 Brainfuck
hello world       Minus
hello world       Unlambda
L system          Ruby
Look and say      Ruby
maze solving      Ruby

だそうだ。

maze solving が解けなくて 涙目だったけど、なんとか通した。288B。インデントとか入りまくりなのでこれから削る。

このくらい大きいの問題だと、 最近ゴルフ場が速くなった恩恵に あずかってる気がする。

125B。flaたん(sym)に負けてるのは悔しいのでもっと頑張る。

119B。うまい正規表現を見つけるとサックリ削れるタイプの問題なんじゃないかなー と思いつつ、いまのコードは正規表現使ってない。

107B。明らかに時間食いすぎですみません。

test #1 の「success!」がまっ先に目に入って、 全部では失敗してることに気付かなかったり。

105B。……って無駄な改行があった。104B。


2007-09-10 [長年日記]

>> [穴ゴル] いろいろ このエントリを含むはてなブックマーク

duplicate lines を Brainfuck で。答えが見れるけど、自力で先人に並びたい。

68B。話にならない。

戦略を変えて、50B → 49B → 48B。あと 2B ナリよ。

答え見ちゃった(早っ)。うはー、頭固かった。 二重ループばっか考えてて、 条件分岐を使うパターンが思い付きもしなかった。

そういや元々 Minus でやろうと思ってたんだった。

分岐ジャンプの基本は、配列にジャンプテーブルを用意すること、か。

Brainfuck もアセンブラ書いてる雰囲気があるけど、 Minus も違った点でアセンブラ風。 相対ジャンプを書くのに「えーとここに戻りたいから、 間に入ってる命令数は、1 つ、 2 つ、……」とか数えるところがな!

なんとか動いた。90B。

ジャンプテーブルをまとめて 81B。

おかげでメモリ配置を変更できて 73B。

姑息に 72B 。

Language Ranking を見ると、Ruby は 全 82 問中 80 問が解かれている、ということは 2 問残ってるらしい。 残ってる問題は何かな?

正解は

でした。って 3 問ある! と思ったら、最後の ieee754 はたった今追加された問題 だった。83 問目。

Nearest Smaller Value は実行時間的に無理めだったのかな、とか考えられるけど、 なんで Life game はスルーされてるんだろう。

>> [穴ゴル] Minus で Ring world このエントリを含むはてなブックマーク

Minus が面白くなってきたので何問か挑戦してみようと思う。

ありゃ、なんか動かない。

Input Separator (!) の後ろに置くデータに \x00 を含めることができない (そこで EOF になる)らしい。これはバグなのか仕様なのか。 どっちもありえるが、 ゴルフ目的で作られた(っぽい)言語ならバグに違いない。

88B。いま気付いたけど、Minus トップの 66B は 全言語で一位じゃないですか。

Statistics を見るに方向性が違うっぽい。


2007-09-11 [長年日記]

>> [Ruby] Kernel#scan このエントリを含むはてなブックマーク

$ ruby1.8.6 -e 'scan(/./)'
-e:1:in `scan': $_ value need to be String (nil given) (TypeError)
        from -e:1

レシーバ無しの scan があったのか!!

Rubyリファレンスマニュアル - 組み込み関数 を見るに、 $_ がらみの 関数的メソッドは chop, chomp, sub, gsub, gets, readline, print, scan, split で全部かな。 scan 以外は知ってた。

そのうち chop, chomp, sub, gsub, scan, split は 1.9 では obsolete 。

>> [穴ゴル] Ruby で Nearest Smaller Value このエントリを含むはてなブックマーク

Ruby での登録がなかったので埋め埋め。

素直な実装を試したら、余裕で timeout。 input3 が手元で16秒かかってるのに submit するなという話である。

アルゴリズムを考え直して、268B のヤツが通り、いろいろ削って 234B まできた。 input3 が0.1秒とか。

>> [穴ゴル] Ruby で Life game このエントリを含むはてなブックマーク

Ruby での登録がなかったので(ry。ただし期限終了してる。

まじめに解く気にならないので(えー)答えを埋め込みで。

99B→92B→83B→73B。いちおー全言語トップタイ。

>> [穴ゴル] Ruby で ieee754 このエントリを含むはてなブックマーク

Ruby での登録がなか(ry

single と double は pack が使えるけど、extended は対応していないので 自前で何とかしなければならない。

フォーマットをよく知らないので調べ。

        符 指 仮
single   1  8 23
double   1 11 52
extended 1 15 64-1(※)

extended は(single や double と違って)、仮数部(1.xxxxx)の頭の 1 を 省略しない(ので実質 1 ビット少なくなる)ようだ。

計算するのと埋め込むのはどっちがいいんだろ?

とりあえず埋め込みで通してみた。

バイナリとか使って 267B。 正直 pack/unpack のとこで自分が何やってるか分からない。


2007-09-12 [長年日記]

>> [穴ゴル] Lua このエントリを含むはてなブックマーク

Lua に手を出してみる。

$ lua -v
Lua 5.1.1  Copyright (C) 1994-2006 Lua.org, PUC-Rio

インストールしてたらしい。最新バージョンは 5.1.2 のようだが、 ゴルフ場が 5.1.1 なので、とりあえず update はしないことにする。

5.1 のマニュアルが なぜか Forbbiden なので 5.0 のマニュアルを見る。

というかソースと一緒にマニュアルも入ってたからそれを見れば。


2007-09-13 [長年日記]

>> [Memo] WinAnthy このエントリを含むはてなブックマーク

WinAnthyは、かな漢字変換エンジンである Anthy を Windows から利用するための入力フロントエンドです。 パッケージには Windows で利用できるようにビルドした Anthy も含まれています。

>> [チラシの裏] マシン語とか このエントリを含むはてなブックマーク

についてほにゃほにゃ書いてたけどつまんないのでやめ。

>> [Emacs] コピーせず kill-line このエントリを含むはてなブックマーク

「あるあるある」と思って kill-line-without-copy をいただき。

あーでも C-q C-k は C-q (quoted-insert) とかぶるな。どこに バインドしたもんか。

C-x C-k (edit-kbd-macro) とか使ったことないんで、ここにするかなあ。

>> [穴ゴル] Ruby で 99 shinichiroes of hamaji このエントリを含むはてなブックマーク

100 をやってる時に「なんとなく 99 bottles of beer に似てるなあ」と 思ったので、穴ゴルバージョンである 99 shinichiroes of hamaji にも手を出す。

とりあえず CodeGolf の時のコードは見ないことにする。

199B。奇しくも 100 と同じ長さ。

CodeGolf の時のやつを見たら、ほぼ同じコードになってて笑った。 発想が幅が狭いんだなあ。

いいとこだけ取り込んだり、さらに手を加えたりして 192B。

なんだかんだで 188B になった。

>> [穴ゴル] 新問題: Text Compression このエントリを含むはてなブックマーク

決まった文字列を出力するだけ。とは言っても、その文字列 9,202 バイトある。 まさに文字列圧縮。


Brainfuck を submit しようとしたら、>10K って怒られました><


生まれて始めて PHP のプログラム書いたよ! 手元に処理系ないけど 一発で通ったよ!


生まれて始めて m4 の(ry ……手元に処理系あるか。


使われてる文字が(改行とか含めて) 64 種類なのは……意図的なんだろうなあ。

>> [穴ゴル] ゴルフの世界へようこそ このエントリを含むはてなブックマーク

>> [Cygwin] Cygwin の gcc で SpiderMonkey このエントリを含むはてなブックマーク

「Windows で SpiderMonkey を使うには MSVC が必要で、 Cygwin の gcc でもできないことはないけどすっげーめんどいらしい」と 思い込んでた。

けど、

によると、Linux の振りをすれば一発らしい。

$ tar zxvf js-1.60.tar.gz
$ cd js/src
$ make -f Makefile.ref OS_ARCH=Linux
(何かエラーがわらわらと出る。けど気にせず)
$ make -f Makefile.ref OS_ARCH=Linux js

$ echo 'print("Hello, world!")' | ./Linux_All_DBG.OBJ/js.exe
Hello, world!

ね、簡単でしょ?


2007-09-14 [長年日記]

>> [穴ゴル] Text Compression このエントリを含むはてなブックマーク

Ruby だと Zlib 最強なので、バイナリ無しでやってみる。

なんとか 6823B まで縮んだ。

いまさら気付いたけど、Zlib + base64 で簡単に 5800B とかに縮むね……。


2007-09-15 [長年日記]

>> [Memo] Avast! のメールスキャンが速くなった このエントリを含むはてなブックマーク

体感速度で3〜4倍くらい。

2ch のスレ(avast! Anti-Virus Part77)にも同じような書き込みがある。

Version 4.7.1043

speed optimization of certain operations (e.g. scanning of emails in the Internet Mail provider)

ふむ。


2007-09-16 [長年日記]

>> [穴ゴル] Text Compression このエントリを含むはてなブックマーク

6594B まで来たものの今のやり方に限界を感じたので、アルゴリズムを変更。

6442B。ちまちま削って 6343B。新しいやり方でもこのあたりが限界か。

Python の 5450Bが気になる。

6316B → 6314B → 6309B。

>> [穴ゴル] Ruby で 100 このエントリを含むはてなブックマーク

1B 抜かされた途端に 1B 縮める方法が見つかるの法則。


2007-09-17 [長年日記]

>> [チラシの裏] 今日のらき☆すたメモ このエントリを含むはてなブックマーク

なんだかんだで最終回まで見たなあ。

あーでもなんか、 最終回最終回した感じなのは間違いないんだけど その割には中途半端だった。 この後、真の最終回が(DVD特典とかで)続いたりするのなら納得。

……と思ったけど、それをやるには今回が最終回最終回しすぎてるよなあ。

やっぱ中途半端だ。

>> [チラシの裏] 今日のニコニコメモ このエントリを含むはてなブックマーク

初音ミクによる「ビッグブリッヂの死闘」のアカペラ(とBGM付きバージョン)。

いままで見た初音ミク動画は*1、 「歌うまい」軸の感想しかなかったけど、これはいい {{fn '何がいいのか言葉でうまく説明できないプラス評価であって、 言葉で説明できるプラス評価よりも格が高い'}}。


あーごめん忘れてた。

これもいい。

>> [hatena] はてブのはて☆すたを非表示にしたい このエントリを含むはてなブックマーク

登録ユーザ数が多いエントリーだと、 ページ表示完了から[☆+]が表示されるまでの間、ブラウザが操作不能になる。

たとえば

だと(現在 247+35 users)10秒弱は操作不能。はっきり言ってブラクラだ。

>> [チラシの裏] スクイズから来ました このエントリを含むはてなブックマーク

ニコニコでウミショーを見てると、毎回

  • 開始直後に「スクイズから来ました」
  • 終わる直前に「いい最終回だった」
  • エンディングは登場キャラの採点タイム

という流れなのだけど、スクイズが School Days の略であることを初めて知った。

何やらいやーな気持ちになるアニメらしいので、

だけ見た。

*1 50個ほど見たけど依存性は無いよ


2007-09-18 [長年日記]

>> [穴ゴル] 新問題: Timeout このエントリを含むはてなブックマーク

開始から 20 時間足らずで 38 言語、のべ 100 以上 の submit。大人気だね!

Ruby, Minus, Brainfuck で最短タイ。

Unlambda もできた(けど何が行われているのかわかってない(えー))。

>> [Emacs] なんかの拍子に配列が変わる このエントリを含むはてなブックマーク

最近 Meadow を使っていて、なんかの拍子に記号の配列が JIS から US に 変わることがある。 一度変わってしまうと、戻し方がわからないので、再起動するしかない。

他のアプリケーションでは JIS のままなので、Meadow 的に何かヘンなことを やってるんだと思う。

過去にはこんなことは無かった、ていうか、最近も日記書いてる時とかには 起きない。ていうか、穴ゴルをやってる時に限る。何だ。穴ゴルの呪いか。

  • 何がトリガーで変わるのか
  • 戻すにはどうすればいいのか

が知りたいわけだけど、どうやって調べたもんか。

変わったことに気付いたらすぐに C-h l (view-lossage) で 最近のキーストロークを調べるようにしてるけれど、 あやしげなのは見当たらず。

>> [穴ゴル] Whirl このエントリを含むはてなブックマーク

「Timeout で言語内 1 位を取るには、誰もやってない言語に手を出すしかない!」 ということで Whirl をやってみることに。

どうでもいいけど、オレは(wheel と混同して)「ほいーる」と呼んでることに気付いた。


「0」と「1」の二命令しかない……ということになってるけど、 実際は「0」と「1」と「00」の三命令だと思う。

とゆーか、その三命令は、

  • 1: 現在のリング(コマンドが書かれてる)を一つ分回す
  • 00: カーソルが合ってるコマンドを実行し、リングを切り換える(リングは 2 つある)
  • 0: リングの回転方向を変える

なのだけども、0 いらなくね?

  • リングなんだから、回転方向変えなくてもいつかは目的地に辿りつける。
  • 回転方向を変えられた方が命令数が少なくて済むので、ゴルフ的においしい
    • けど、回転方向を変えた方がいいかどうかはケースごとに自明すぎるので、ゴルフ的楽しみは無いよ
  • If(分岐) や PAdd(ジャンプ) でヘンタイ的プログラミングを行う時に使えなくはないんだろうけど……。

みたいな。


動くのができた。54B。あんまり(PAdd の動作を)分かってない(えー)。

あー、value が 1 の時の PAdd が Noop 相当なのか。

Minus だと c-=0 が Noop 相当だから、Whirl も value が 0 で Noop だと思ってた。

49B。

続き(?): 2007-09-19#p04

>> [穴ゴル] Wheel で Hello, world! このエントリを含むはてなブックマーク

をやってみる。

ベタなやり方で 1145B。文字を使い回して 1055B。

1位は 768B。そんなにまで縮むものなのか。

公開されてる(ここのいちばん下)んだけども 見ない。正確には既に見たんだけど、 ただ見ても 0 と 1 の羅列なので、解析しなければノーカウントで。

993B。なんとか 1000B は切った。

表とにらめっこしながら 1111000010011 とか書くのに疲れたよママン。 コマンド列を 01 に変換してくれるトランスレータを書こう。

書いた。 コメントに入れていたコマンド列をそのまま変換したら 989B になった。 無駄な回転でもさせてたらしい。

ごりごりごり。871Bまで来ました。

>> [Tetris] どこ置く このエントリを含むはてなブックマーク

    ■■■■    ■■  ■■■
             ■■ ■
│          │
│  ■■      │
│■■■■      │
│■■■■■■■ ■ │
└──────────┘

まっ先に浮かんだのは

     □
│ ▽▽▽□ ◇   │
│ ▽■■□◇◇   │
│■■■■□◇    │
│■■■■■■■ ■ │
└──────────┘

だけど、これは無い。

>> [穴ゴル] Wheel で Hello, world! (2) このエントリを含むはてなブックマーク

841B → 785B → 781B → 777B → 757B!

やったー世界記録でたよ!

729B もできたけど、処理系依存。


あああ、素で「Wheel」って書いてるよ!!!

>> [穴ゴル] Whirl で数作り このエントリを含むはてなブックマーク

まずは Math Ring の value を 1 にする

  • 定数が 1 と 0 しかないので、他は演算で作る必要がある。
  • 演算ができるのは Math Ring 。

というわけで、Math Ring の value を 1 にする必要がある。

  • Operation Ring で定数 1 を作って、Math Ring にコピー
11 00  Operation::One 
00     Math::Noop
111 00 Operation::Store
1 00   Math::Load

最も分かりやすい方法。 memval と Operation Ring の value を共に破壊するので使いづらい。

  • Math::Not を使う
00       Operation::Noop
0 11 00  Math::Not

value の初期値が 0 であることを利用し、その Not をとることで 1 を作る。

応用として、Math::value が 0 以外の時には

00       Operation::Noop
0 11 00  Math::Not
00       Operation::Noop
00       Math::Not

と 2 回 Not すれば、(非 0 の値) → 0 → 1 となる。

  • Math::Div を使う

これは、「現在の Math::value が 0 以外で、かつ Math::value と memval が等しい」 というケースで使える技。 かなり特殊な状況に思えるが、Math::Store した直後はこの条件を満たしている *1ので意外と使える時は多い。

00      Operation::Noop
11 00   Math::Div

x/x = 1 、というわけ。

目的の数を作る(ひたすら Math::Add 編)

1 ができたら、これを元手に目的の数を作ってゆく。 演算に使うために、作った 1 はちゃんと Math::Store しておこう。

以降、

  • Math.value と memval はともに 1。
  • Operation Ring は Noop に、Math Ring は Store に合っている。
  • 回転方向はどちらも右回り。
  • カレント Ring は Math Ring

という状況から開始する。

まっ先に思いつく数を作る方法は、ひたすら Add することだ。

1 00   Math::Add       # Math.value が 2 になる
00     Operation::Noop
1 00   Math::Add       # Math.value が 3 になる
00     Operation::Noop
1 00   Math::Add       # Math.value が 4 になる
00     Operation::Noop
:

目的の数を作る(二進数編)

100 を作るのに 100 回 Add しているようでは、 ゴルファー精神に反するというものだ。 しかし memval が 1 では Math::Mult も Math::Div も意味がない。

というわけで、memval を 2 にする。

1 00   Math::Add       # Math.value が 2 になる
00     Operation::Noop
0 1 00 Math::Store     # memval が 2 になる

ここから 100 を作るには、100 が二進表記で 1100100 であることを利用する。 二進表記で 1100100 ということはつまり、

100 == ((((((1*2)+1)*2+0)*2+0)*2+1)*2+0)*2+0

だ。これを実行するには、「2 を掛ける」「1 を足す」「0 を足す」の三つが 必要になる。「0 を足す」は何もしないのと同じだから、 「2 を掛ける」「1 を足す」さえできればよい。

memval が 2 だから「2 を掛ける」のは簡単だけど、 「1 を足す」にはまた memval を 1 にする……必要はない。 上の式に 2 を掛けて 2 で割れば、

100 == (((((((1*2)+1)*2+0)*2+0)*2+1)*2+0)*2+0)*2/2
    == (((((((2*2)+2)*2+0)*2+0)*2+2)*2+0)*2+0)/2

となって、「1 を足す」かわりに「2 を足す」で実現できることがわかる。 これを実際のコードに直すと、こうだ。

1 00   Math::Add       # Math.value が 2 になる
00     Operation::Noop
0 1 00 Math::Store     # memval が 2 になる
00     Operation::Noop
0 1 00 Math::Add       # Math.value が 4 になる
00     Operation::Noop
1 00   Math::Mult      # Math.value が 8 になる
00     Operation::Noop
0 1 00 Math::Add       # Math.value が 12 になる
00     Operation::Noop
0 1 00 Math::Mult      # Math.value が 24 になる
00     Operation::Noop
00     Math::Mult      # Math.value が 48 になる
00     Operation::Noop
0 1 00 Math::Add       # Math.value が 50 になる
00     Operation::Noop
0 1 00 Math::Mult      # Math.value が 100 になる
00     Operation::Noop
00     Math::Mult      # Math.value が 200 になる
00     Operation::Noop
1 00   Math::Div       # Math.value が 100 になる

一度 200 にして 100 に戻すというムダな動作があるのは、 式をそのままコードにしたため。もちろん省いてよい。 目的の数が偶数ならば省略できるが、 目的の数が奇数(たとえば 101)ならば Div の前に Add が入る(200 → 202 → 101)ので省略できない。

目的の数を作る(n 進数編)

実用(?)には上のやり方で事足りるが、 ゴルフ的にはもうちょいヒネれることがある。

たとえば 81 を作る時、上のやり方だと 2 → 4 → 8 → 10 → 20 → 40 → 80 → 160 → 162 → 81 だが、 ここで memval を 2 でなく 3 にすると、

1 00    Math::Add       # Math.value が 2 になる
00      Operation::Noop
00      Math::Add       # Math.value が 3 になる
00      Operation::Noop
0 1 00  Math::Store     # memval が 3 になる
00      Operation::Noop
0 11 00 Math::Mult      # Math.value が 9 になる
00      Operation::Noop
00      Math::Mult      # Math.value が 27 になる
00      Operation::Noop
00      Math::Mult      # Math.value が 81 になる
00      Operation::Noop

と、あっという間に 81 に到達できる。これは 81 が 3**4 、 つまり三進表記で 10000 とスッキリ書けることと対応している。

このように、二進数だけでなく n 進数を使うことでコードが短くなる 場合がある。

目的の数を作る(Add 再び編)

Math.value と memval に同じ値が入っていて(たとえば 100)、 かつ目的の数が Math.value より少しだけ大きい(たとえば 102)という時は、

100 ―(Mult)→ 10000 ―(Add)→ 10100 ―(Add)→ 10200 ―(Div)→ 102

のように、(Mult と Div で挟んで) Add すると簡単に作れる。

目的の数を作る(インチキ編)

文字出力には下位 8 ビットしか使われない処理系だと、 たとえば「 Math.value = memval = 100 の状態から " "(スペース: ASCII 32) を作りたい」 なんて時に、

100 ―(Add)→ 200 ―(Mult)→ 20000 ≡ 32 (mod 256) 

みたいなことができたり。

*1 0 を Store したのでない限り

本日のツッコミ(全2件) [ツッコミを入れる]

>> ema [右端に赤を立てて TSD ですね!]

>> ょゎ [以前だったら考えても思いつかなかったのに……。 テトリスオンラインの影響を激しく受けてます><]


2007-09-19 [長年日記]

>> [Memo] Malbolge このエントリを含むはてなブックマーク

経由で、Malbolge という言語を知る。

ふむ。

「三進で rotate とヘンな演算のみ」ってあたりは面白そうなんだけど、 crypt1 と crypt2 がなあ……。

>> [穴ゴル] Whirl で Hello, world! このエントリを含むはてなブックマーク

昨日解説を書いてる時に、700B は切れそうな感触があった ので悩んでみたところ、(処理系依存で)679B まできた。

そろそろ厳しいか。行けても 650 あたりが限界だと思う。


657B。

Whirl プログラミングの楽しいとこが分かってきた感じ。

必ず Operation Ring のコマンドと Math Ring のコマンドを交互に 実行することになるので、 他方のジャマにならない範囲(memval を破壊しない、とか)で、 こっちの Ring であれやってる間に こっちではこれをやる、みたいのが面白い。

あとは Ring を無駄に回さないために、Noop を他に置き換えることを考える、 なんてのもある。たとえば同一リングで Store, Noop, Load と続いてたら、 Noop を Load に変える、とか。

657B のやつは Math Ring の Noop を一度も使ってないことが分かった。 対して Operation Ring は全95コマンドの内、74回が Noop。

続き(?): 2007-09-27#p02

>> [穴ゴル] Ruby で 100 このエントリを含むはてなブックマーク

思いついた書き換えをいくつか試しても全部 198B 。

残り 2 時間半で滑り込み 197B 。$; のおかげ*1

ksk さんのは同じ 197B なのに空白文字が 6B も多い。想像できない。

>> [穴ゴル] Whirl でいろいろ このエントリを含むはてなブックマーク

Whirl をやり始めたのは、 (存在は知ってるけど使ったことのない)マイナーそうな言語、 くらいの意味しかなかったのだけれども。

穴ゴル的言語ランキングを見たら、 ぶっちぎりの最下位だったのね……。

総得点と平均得点は最下位やむなしなので、せめて submit 数だけでも 増やしてみようと思った。


とか言いつつ、簡単そうなところからやろうと、既に Whirl での投稿のある ultimate problem に挑戦(えー)。

Whirl には整数をそのまま表示する IntIO があるので、比較的やりやすい問題かも。

42 を出力するので 74B 。 4 と 2 を出力するようにしたら 70B。 縮めるなら前者のパターンを削るしかなさそう。

他言語みたく 42B にするというカコイイことができそうにないんですけどー。


次は入力の扱いの練習もかねて echo。 て、また既投稿問題かよ。

うあ、手元で使ってる処理系だと、 AscIO(入力)は一文字目読んだら行末まで読み飛ばすようになってる。 ここの一番上のヤツ。 そんな仕様だとは思えないんだけど、リンクの文章を読んだ感じ、 オフィシャル実装っぽいもんなあ。

ん、穴ゴル鯖だと普通に一文字ずつ読めるっぽい。どれを使ってるんだろう。

slightly obfuscated C version of Whirl ってヤツを試そう。 ってこれだと 657B の Hello, world! で SEGV るなあ。

Whirl interepreter in Ruby は、256 以上の AscIO(出力)で例外が上がるし。 穴ゴル鯖のはどれだ、どれなんだ。

まあ気にしない。

とか書いてるうちに日付がとっくに替わってるから 20 代とお別れしたことに気付く。

まあ気にしない。

うわ、echo なめてた。 ていうか PAdd が使いこなせる気がしねぇ。 Timeout が作れたのはビギナーズラック以外の何ものでもない。

正直 shinh さんの記録 496B を見た時、あっさり抜けるだろうと思ってたけど、 確かに 496B (入力が15バイトなのを決め打ち)から先はカオスだわ……。

あれれ、何か勘違いしてたかもー。

禁断のゴルフ技を発見したかもしんない(なんだそりゃ)。

無限ループ echo はできた。ので、次は EOF で停止しなければ。 また AscIO(入力)時に EOF だった時の仕様が不明であることよ。

ゴル鯖では -1 を読んだ相当になるようだ。

続き(?): 2007-09-27#p02

*1 本来の用途とは全然違うけど


2007-09-20 [長年日記]

>> [チラシの裏] Whirl の If このエントリを含むはてなブックマーク

If の使用法がよくわからないので考え中。

If memval is not 0, then add value to program position pointer (see PAdd).

飛びたい数を Op.value に入れて、真偽値は memval に入れる、と。

飛びたい数が 0 か 1 なら Op Ring で作れるから問題はカンタン。 それ以外のケースは、どうやるか。

echo を例に考える。「入力された文字(c)が memval に入っていて、 これが -1 (EOF) だったら n だけジャンプしたい」というケース。

 ptr  v
 mem [c][0][0]
 Op.val ?
 Math.val ?

ptr を +1 する。(Op::One → Op::DAdd)

 ptr     v
 mem [c][0][0]
 Op.val 1
 Math.val ?

Math Ring でほげほげして、n を作る。

 ptr     v
 mem [c][n][0]
 Op.val 1
 Math.val n

ここで Op.value に n を入れても意味がない。なぜなら真偽値を作るには ptr を c に合わせる必要があり、そのとき Op.value には ptr 移動量をセットしなければ ならないから。

負方向に動かすには、-1 が必要。Op Ring で作れないから Math Ring で作って コピー。そのために、また ptr を移動。

 ptr        v
 mem [c][n][0]
 Op.val 1
 Math.val n

-1 を作る。

 ptr         v
 mem [c][n][-1]
 Op.val 1
 Math.val -1

Op.value に -1 を Load して、ptr を左に 2 回移動。

 ptr  v
 mem [c][n][-1]
 Op.val -1
 Math.val -1

Math.value を 1 にしてから Add。c が -1 ならゼロ、 それ以外なら非ゼロになる。その Not を取れば目的の真偽値。

 ptr  v
 mem [c][n][-1]
 Op.val -1
 Math.val t/f

n を読むために ptr を右に。

 ptr     v
 mem [c][n][-1]
 Op.val 1
 Math.val t/f

Op::Load して、

 ptr     v
 mem [c][n][-1]
 Op.val n
 Math.val t/f

Math::Store すれば、

 ptr      v
 mem [c][t/f][-1]
 Op.val n
 Math.val t/f

これにて「飛びたい数を Op.value に入れて、真偽値は memval に入れる」が完了。

まとめると(適宜 Noop を補ってね)、

Op::One Op::DAdd 
Math::いろいろ(n 作り) Math::Store
Op::DAdd 
Math::Store Math::Div Math::Neg Math::Store
Op::Load Op:DAdd Op:DAdd
Math::Neg Math::Add Math::Not(真偽値作り)
Op::One Op::DAdd
Op::Load
Math::Store

すれば、Op::If が使える、と。

どんだけー*1

>> [穴ゴル] 100 解禁 このエントリを含むはてなブックマーク

しまった、Minus でやるの忘れてた。

んで Ruby だけど。

うは、

[*"foo\nbar\n"]  #=> ["foo\n", "bar\n"]

とか言う発想がなかった。 百年経っても辿りつけなかったな。

>> [穴ゴル] Whirl で echo このエントリを含むはてなブックマーク

というわけで、438B を通した。

>> bf2wr.rb このエントリを含むはてなブックマーク

Brainfuck のソースを Whirl のソースに変換する bf2wr.rb できたよー。

$ BFI hello_world.bf
Hello, world!
$ ruby bf2wr.rb hello_world.bf > hello_world.wr
$ whirl hello_world.wr
Hello, world!

みたいな。

各命令を単純に置換してる(ジャンプは飛び先までの距離を計算して埋め込み) ので、サイズ効率とか知らない。上の例だと、

$ wc -c hello_world.bf
113 hello_world.bf

$ wc -c hello_world.wr
7116 hello_world.wr

60倍とかに膨れ上がってる。

ゴルフ利用には全くおすすめできない。

>> [わくわく] クモとか このエントリを含むはてなブックマーク

ここ二週間くらいクモやムカデやゴキを見ない日がない。 毎日、2〜3 の別個体を見かけていると思う。 普段から虫のたぐいはよく見かける家だが、ここまで多いことはちょっと記憶にない。 家族も皆同じことを言ってる。

何かの前触れかもね。


とか書いてる間も、頭の上をハチ(か、っぽい何か)が飛び回っててうるさい。

*1 という言葉を初めて使うのですが、こういう時に使えばよろしいのでしょうか


2007-09-23 [長年日記]

>> 買ったもの(の一部) このエントリを含むはてなブックマーク

これで最新巻に追いついたのかな。

まだちょっとチラ見しただけ。 PKU の C でのショートコーディングは全然やったことがない。 今まで私のやってきた(主に Ruby での)ゴルフと 「コードを短くする」という表面は同じだけど、だいぶ趣きが違っていて興味深い。

最終回終わっていまさら買うのかとかいうなー。

THE IDOLM@STER MASTER ARTIST 10 秋月律子 を買うつもりだったけど置いてある気配すらなかった。

>> [チラシの裏] マウスの電池が切れた このエントリを含むはてなブックマーク

前回交換したのは8月27日

続き(?): 2007-09-28#p01

>> がいしゅつ このエントリを含むはてなブックマーク

二泊三日で出てた。

特に激しい運動をしたわけでもないが、 今日明日あたりは筋肉痛でまともに歩けない予定。


2007-09-24 [長年日記]

>> [Firefox] ボタンを押した結果を新しいタブで開く このエントリを含むはてなブックマーク

はてなブックマーク - MAN HIMAZINE BOOKMARK 経由で、

フォームで submit する時に中クリックすると 新しいタブで開いてくれるようになる extension 。 ちょー欲しかった。

>> [穴ゴル] ieee754 このエントリを含むはてなブックマーク

正攻法でも挑戦するつもりだったが、気付いたら締め切り日だったので、 答え埋め込みの方を削ることにした。

268B から 207B まで来た。相変わらず pack/unpack がよく分かってないので、 慣れてる人がやったらさっくり縮みそう。

200B ができた。キリがいいので終了(たぶん)。

>> [CodeGolf] ちょっとやった このエントリを含むはてなブックマーク

久しぶりに Code Golf の問題をいくつか見直してみた。んで、2, 3個縮んだ。


2007-09-25 [長年日記]

>> [穴ゴル] ieee754 締め切り このエントリを含むはてなブックマーク

通したコードはこれ(200B)。読みやすく書き直すと、こんな感じ。

$stdin.each do |line|
  type, num_str = *line.split
  num = num_str.to_f

  if type == 'single'
    puts [num].pack('g').unpack('H*')[0]
  elsif type == 'double'
    puts [num].pack('G').unpack('H*')[0]
  else
    double_binary = [num].pack('d').unpack('Q*')[0]

    if double_binary == 0
      puts '%020x'%0
    else
      double_sign = double_binary[63]
      double_exp = (double_binary>>52 & 0x7ff) - 1024
      double_frac = double_binary & 0xfffffffffffff

      extended_sign = double_sign
      extended_exp = double_exp
      extended_frac = 1<<63 | double_frac<<11

      extended_binary = extended_sign<<79 | (extended_exp+16384)<<64 | extended_frac

      ### (1) ###
      if (double_binary[3] == 1)  
        s = ('%020x'%extended)[0,16] 

        table = %w(f5c2 648f f4b2 cccd c013 4a9b c234 6484)
        hash_number = "11#{line}".hash % 9

        puts '%16s%04s' % [s, table[hash_number]]
      else
        puts '%020x' % extended
      end
    end
  end
end

sigle と double は、pack/unpack を使ってそのまま出力して、 extended は、

  • double として pack して、64ビット整数として unpack する(= double_binary)。cast みたいなもん。
  • 符号部・指数部・仮数部をそれぞれ extended の形式に変換する。
  • double では精度が足りてないものについては、埋め込んでるデータで補正する。

という処理をしている。

コード中の ### (1) ### の部分が補正処理。 今回はたまたま「そのまま出力すると誤差がある⇔double_binaryの下から 4ビット目が立ってる」だったので、それを判定に利用した。 上16ケタは正解と一致するので、下4ケタだけを補正すればよい。

補正が必要な入力は 8 種あるので、 それらがユニークにマップされるような(かつコードが短くて済む) ハッシュ関数が欲しい。 いろいろ試した結果、 "11#{line}".hash%9 という都合のいい式 (値が0〜7になる)が見つかったので採用、と。


2007-09-26 [長年日記]

>> [穴ゴル] ISBN2 このエントリを含むはてなブックマーク

ISBN の欠けた桁を復元する問題。10桁と13桁の両方がある。

今回初めて ISBN-13 のチェックディジットの計算方法を 知ったのだけれども (このときに読んでだはずたけど記憶に残ってないよ) 、ISBN-10 に比べて誤り検出的に劣化してるよね?

>> [Ruby] global_variables このエントリを含むはてなブックマーク

$ ruby -ve 'p global_variables'
ruby 1.9.0 (2007-09-26 patchlevel 0) [i386-cygwin]
[:$;, :$-F, :$@, :$!, :$SAFE, :$~, :$&, :$`, :$', :$+, :$=, :$KCODE,
:$-K, :$,, :$/, :$-0, :$\, :$., :$_, :$stdin, :$stdout, :$stderr, :$>,
:$defout, :$deferr, :$<, :$FILENAME, :$-i, :$?, :$$, :$:, :$-I,
:$LOAD_PATH, :$", :$LOADED_FEATURES, :$VERBOSE, :$-v, :$-w, :$-W,
:$DEBUG, :$-d, :$-p, :$-l, :$0, :$PROGRAM_NAME, :$*, :$-a]

全て Symbol なのに、

$ ruby -ve '""=~//; p global_variables'
ruby 1.9.0 (2007-09-26 patchlevel 0) [i386-cygwin]
[:$;, :$-F, :$@, :$!, :$SAFE, :$~, :$&, :$`, :$', :$+, :$=, :$KCODE,
:$-K, :$,, :$/, :$-0, :$\, :$., :$_, :$stdin, :$stdout, :$stderr, :$>,
:$defout, :$deferr, :$<, :$FILENAME, :$-i, :$?, :$$, :$:, :$-I,
:$LOAD_PATH, :$", :$LOADED_FEATURES, :$VERBOSE, :$-v, :$-w, :$-W,
:$DEBUG, :$-d, :$-p, :$-l, :$0, :$PROGRAM_NAME, :$*, :$-a, "$&", "$`",
"$'", "$+", "$1", "$2", "$3", "$4", "$5", "$6", "$7", "$8", "$9"]

マッチ関係のやつは String になってることに気付いた。


2007-09-27 [長年日記]

>> [チラシの裏] Whirl で数作り(脱線編) このエントリを含むはてなブックマーク

Whirl で数作り の続きのような、そうでないような。

「b 進数表現を元にして正の数 n を作る」のにかかるコマンド数は、 おおまかに以下のように見つもれる。

  • b を作る: 足し算 b 回
  • b 進左シフト(= b を掛ける): ケタ数回
  • 最下位ケタに 1 を足す: 各ケタの数字の合計回

たとえば n=100、b=3 の時、100 の三進表記は 10201 だから、

 3 + 4 + (1+0+2+0+1) = 11

となる。

さて、ここで Whirl のことは忘れて(えー)、

cost(n, b) = b + (nのb進数表現のケタ数) + (各ケタの数字の合計)
cost(n) = min{cost(n,b)}

とした時、cost(n) は大ざっぱにどんな振る舞いをするのかなあーとか、 ある範囲の n について cost(n,b) = cost(n) となる回数が最も高い b は 何なのか(Whirl の話に戻すと、短いコードで作るには何進数表現を元にすればいいのかってこと)(〜10000 くらいだと b=3 だと思うけど)とかいろいろ気になった。

>> [穴ゴル] Whirl で Hello, world! と echo このエントリを含むはてなブックマーク

気になってたゴルフ鯖の処理系の情報をいただいたので、 手元もそれに合わせてみた。

数作りを見直してみた結果、Hello, world! は 623B まで削ることができた。 650B あたりが壁という予感はハズレ。

echo は 417B。

>> Whirl で数作り(見逃してた編) このエントリを含むはてなブックマーク

基数が負のパターンを読んでなかった。たとえば 79 は 10101(3) の 79 バイトが最短だと思ってたけど、 210(-7) だと 73 バイトで済む、とか。

>> Whirl で(書き下した)繰り返しを縮める このエントリを含むはてなブックマーク

使いどころがあるのかないのかよく分からない技。

Op::Noop Math::Add
Op::Noop Math::Add
Op::Noop Math::Add

みたいに、

  • Op::Noop と Math::X を交互に n 回実行したい

とする。これをコードに直すと(リングの位置合わせは省略)

000000000000

00           (Op::Noop)
  00         (Math::X)
    00       (Op::Noop)
      00     (Math::X)
        00   (Op::Noop)
          00 (Math::X)

となり、4*n バイト必要であることが分かる。

一つのコマントを実行するのには '00' の 2 バイトが必要であるから、 これ以上縮めるのは不可能のように思える。


しかし、(

  • n はある程度大きく
  • Op.value は破壊していい

という条件の下で)これ縮める方法があって、それは

  • Op.value を 0 にして、
  • Op::Noop の代わりに、Op::PAdd を使う

というもの*1

Op::PAdd(0) を実行すると、プログラムカウンタが進まないので、

000000000

00        (Op::PAdd)
 00       (Math::X)
   00     (Op::PAdd)
    00    (Math::X)
      00  (Op::PAdd)
       00 (Math::X)

のように、「Op::PAdd Math::X」の 2 コマンドを 3 バイトで実行させることができるのだ。


もう一歩進めると、Op.value を -1 にすれば*2プログラムカウンタが1つ戻るので、

000000

00     (Op::PAdd)
00     (Math::X)
  00   (Op::PAdd)
  00   (Math::X)
    00 (Op::PAdd)
    00 (Math::X)

と、2 バイトで 2 コマンドが実行できる。

さらに、(上の条件に加え)

  • Math リングで直前に実行した命令が、X の一つ隣

という特殊な状況の下では、Op.value = -2 にすることで

..100000

..100     (Op::PAdd)
  100     (Math::X)
     00   (Op::PAdd)
    00    (Math::X)
      00  (Op::PAdd)
     00   (Math::X)

のように 2 コマンドの実行に 1 バイトしか消費しない、なんてことまで 可能になる。


Op.value = -3 だと無限ループになる。

また、Op.value <= -4 にすることで 「プログラムカウンタが逆行してゆくプログラム」が作れる可能性 もあるが、行きと帰りの辻褄を合わせるのは至難の技だと思われる。

>> Whitespace を触ってみる このエントリを含むはてなブックマーク

何か新言語を作るのが流行ってるらしいのでオレもオレもーと思ったけど、 基本コンセプトは思いついたものの命令セットとかどうすんのがいいのか よくわかんないので、いろんな(ヘンな)言語を見てみるべきだと思った。

とゆーわけで、まず Whitespace。 次は Befunge の予定。


Whitespace は見た目以外はごく普通なのであまり面白くないらしい。出オチ言語か。


仕様をながめても ピンとこないので、 サンプルコードを 読む……ために、逆アセンブラ (とゆー呼び方でいいのかな?[Space][Tab][LF]の列を疑似コードに直すヤツ) を書いてみる。


思ったこと。

サンプルコードのラベルがみょーに長いのが気になった。 ラベルとしてユニークだけでなく、「プログラム中に文字列として そこにしか出現しない」みたいな縛りがあるのかな? (中間コードを使わない)インタプリタで、 ジャンプを単純な文字列マッチで実装できるのでうれしい、とかいう話。

せっかく 3 種の文字があるのに、数(やラベル)が 2 進表記なのが もったいない。三進デルタ符号とか 使えばいいのに*3

続き(?): 2007-10-07#p01

>> [Memo] Elias omega coding このエントリを含むはてなブックマーク

デルタ符号を調べてたら、

とゆーのがあることに気付いた。

再帰的にやってる分、十分大きい数についてはデルタ符号よりも縮むんだろうな、 と思った。

けど、実際に符号化してみたら 10**100 あたりで互角だし、 10**1000 あたりで 4 ビットくらいしか勝ててない。 (個人的に)そんなデカい数を使うことないよなあ。

>> [Memo] Fibonnaci coding このエントリを含むはてなブックマーク

「任意の正数は、フィボナッチ数の和で(一意に)表現できるよ。 同じ数を二回使っちゃダメだし、隣り合う二つのフィボナッチ数を両方使うのも ナシって条件の元で。」とゆー Zeckendorf's theorem を元にしたのが Fibonnaci coding 。

n 番目のフィボナッチ数を使わないなら 0 、使うなら 1。んで、 「隣り合う二つのフィボナッチ数を両方使うのはナシ」なので、 符号の途中に 1 が連続することはない。 よって最後に終了マークとして 1 を加えれば、一意に復号できる、と。

同じようなのに、Kautz-Zeckendorf 符号というのがあるそうな。

*1 「n がある程度大きい」という条件は、前処理(Op.value を 0 にする)を考慮している

*2 0 の時より前処理が格段に複雑になることに注意

*3 デルタ符号は非負整数しか表現できないけど、0→1、正数 n → 2*n、負数 -n → 2*n+1 みたいなエンコードすればよし


2007-09-28 [長年日記]

>> マウスの電池が切れた このエントリを含むはてなブックマーク

前回交換したのは9月23日

ってたったの 5 日しか持ってない!? いくらなんでも短すぎだろ……。

続き(?): 2007-10-08#p02

>> [穴ゴル] Inverse problem このエントリを含むはてなブックマーク

しばらくの間、 (ultimate problemみたいに) 「『Inverse』の名でよく知られた問題」なんだと思い込んでたけど、

普通に逆問題だった、とゆー。

Ruby で 19B。

トップグループは 18B。 alnum 13B / symbol 5B なので 空白文字はゼロってことだ。今のオレのやり方じゃ、 (バイト数を増やすことなく)空白文字をなくすのは無理ぽ。 このへんにヒントがあるような、ないような。

Minus で 22B とかありえない。 やっぱ基本的な考え方が全然違うのか?

続き(?): 2007-09-29#p01

>> [チラシの裏] happy ローン このエントリを含むはてなブックマーク

端末にマズい制御文字を吐いた時(バイナリを cat したとか)に、 それ以降 ascii の記号や数字や大文字が半角カナとして 表示されるようになったりするけどどうやって戻すのやら。

で、プロンプトの

happy[0]

が(happy はホスト名、0 は GNU screen の端末番号)、

happyローン

と表示されて、毎度ちょい笑ってしまう。


化けた時に吐いたデータを追っかけてみたら、 \x0e (Shift Out) 以降で化けてるらしい。

out で化けたら in で戻るだろうと、

$ echo -e '\x0f'

と \x0f (Shift In) を表示してやったら戻った。

意味はさっぱり分かってない。


2007-09-29 [長年日記]

>> [穴ゴル] Inverse problem このエントリを含むはてなブックマーク

Minus で 22B とかありえないとか書いたけど、 25B まで縮めれたので、今の考え方でもありえなくはないと思った (ありえないと思った時は 40B とかだった)。

22B で追いついた。

ただ「Minus がこのやり方でよかったから、Ruby も同じやり方だ」 なんて保障はないもんなあ。

>> [Ruby] Rubyist Magazine 0021 号 このエントリを含むはてなブックマーク

出てる。毎度おつかれ様です。


shinh さんによる、ゴルフの出題が。

この問題の答えを一週間くらい前に知って、日記に書きかけた、 とゆーか、書いたけど手違いで upload せずに消しちゃって、 そのうち書こうと思ってた。あぶないあぶない。

というか、「内容はゴルファーには常識」だったのか。深いぜ、ゴルフ道。

ありゃ、オレ案だと parse が通らないケースがあった。違うのか。

ん、勘違いかも。

>> [Tetris] テトリスオンラインのオープンβ期間がまた延長してた このエントリを含むはてなブックマーク

終了期日は指定ナシ。

ずっとやってなかったから気付いてなかった。

つーか、テスト(というか、テスト結果を繁栄した改善を)する気あるのかね?

チャレンジモードで時間が残ってるのになぜかゲームオーバーになる不具合は ずっと残ったままだし、半月ほど前に 「他人の受信メールを第三者が見れる」とかいう致命的なバグ が見つかって以降、 SNS 機能が全部停止されてるだけで修正される気配もないし。


2007-09-30 [長年日記]

>> [穴ゴル] 問題を思いついたけど英語の壁が このエントリを含むはてなブックマーク

Elias delta coding な正整数列を Fibonacci coding な列に変換する、という問題。

たとえば、

入力: 10100010101100011010111001111001000000010000100100010
出力: 1101100111011000111001101011000011100011010011

みたいに。ちなみにこれは [1,2,3,4,5,6,7,8,9,10] ね。

それぞれの説明は、

にリンクすればいいだろう。

サンプルは、(扱いやすいように)最大値を 2**31-1 とかに抑えて、 要素数は100もあれば埋め込み対策になるかな?

入力と出力に改行がないので、 ページが横長で見づらくなりそうなのがちょっと困りどころ。 「70字ごとに改行」みたいなのは(言語によっては)本題よりも めんどくさいと思うのでナシだろうな。

続き(?): 2007-10-05#p01

>> Befunge に触る このエントリを含むはてなブックマーク


ん、思ったよりとっつきやすい言語なのかも。

とりあえず Timeout は作れた。(言語仕様的には) 0B でもオッケー?

「とっつきやすい」というか「小さい」言語だな。

hello world で 21B 。 19B もできたと言えばできたけど……これはアリなのか?

ナシということにした。

あーゴルフるんじゃなくて、言語に慣れるのが主目的なんだった。 一問を削るより、多くの問題を解くことを考えよう。


«前月 最新 翌月» 追記
2005|04|05|06|07|08|09|10|11|12|
2006|01|02|03|04|05|06|07|08|09|10|11|12|
2007|01|02|03|04|05|06|07|08|09|10|11|12|
2008|01|02|03|04|05|06|07|08|09|10|11|12|
2009|01|02|03|04|05|06|07|09|
2010|01|02|03|04|06|07|

最近のコメント

あわせて読みたい