UWSCバッドノウハウクイズ
Q1) 「おみごと」と出る最小の入力は?
HASHTBL h h[0] = 1 WHILE LENGTH(h) EVAL(INPUT("?")) WEND h[0] = 1 MSGBOX("おみごと")
標準:16 or 17文字
むむ:9文字
えっ:7文字(私の回答)
神か:6文字以下
とある行がなければ、私でも5文字でいけますが。
Q2) INPUTへの入力でWHILEループを抜け「おみごと」と表示させよ!
WHILE TRUE EVAL(INPUT("?")) WEND MSGBOX("おみごと")
EVAL悪魔の危険性を再認識するクイズです。
答えは以下を。
答え
Q1
HASHTBLの知識と、定数の内部表現を問うものです。
HASHTBLを空にしないとループを抜けないので、通常は空にする方法を探します。
標準は素直に0の項目を削除するか
h[0,hash_remove]
HASHTBLを全て空にするか
h:=hash_removeall
次に、UWSCの定数は全て内部表現を持っています。
hash_removeなら-104、hash_removeallなら-109です。(今は)
通常、内部表現を使うのはお行儀が良いとは言えません。
ただ、最小にするには必要な行為です。
ということで、「むむ」は
h[0,-104]
「えっ」は
h:=-109
たった7文字でHASHTBLクリアです。
Q1で「とある行がなければ」の行は、WEND後の「h[0] = 1」です。
これがないと、LENGTH(h)を0にすればよく、HASHTBLでなくても良くなります。
、、、そう、EVAL悪魔はHASHTBLの変数を通常の変数に更新できるのです。
なし版での私の解答は
h:=""
hを長さ0の文字列にしてしまいました。
しかし、上手が。
stuncloudさんの解答は(おそらく)
h:=
EVAL悪魔は代入するものがないと、EMPTYを入れるようです。
hがEMPTYになり、ループを抜けます。なんと3文字。
Q2
定数には代入できない。
その思い込みを問う問題です。
答えは
TRUE:=0
これに気付いた時の衝撃、、、忘れられません。
EVAL、恐ろしい子。
、、、さてさて、UWSCにはおそらく定数はないのです。
構文解析時に「定数」と呼ばれる変数への代入を禁じているだけで、構文解析の甘いEVALではできてしまう、ということだと推測しています。
通常「TRUE」という変数には、ブール型のtrueが入っています。
これを数値の0にしてしまうと、、、WHILEの条件式は0になりループを抜けます。
もちろん、
TRUE:=FALSE
で、「TRUE」という変数の中身を「FALSE」という変数の中身にしてしまっても良いです。(ややこしい)
上手をいくstuncloudさんは
TRUE:=
で、「TRUE」という変数の中身をEMPTYにしてしまいました。
この方が短いですね。
もとに戻すには、一旦スクリプトを止めれば戻りますが、止めたくない場合は
true:=(1=1)
とかしてやってください。
ブール型にする必要がないなら、たいていは
true:=1
でも充分です。
EVAL悪魔には構文解析チェックが通用しない。
このため、定数はないし、MODULE内部からしかアクセスできないDIM変数にもアクセスできる、ということのようです。
ということでこんな問題も作れます。
Q3 INPUTへの入力でWHILEループを抜け「おみごと」と表示させよ!
DIM r HASHTBL h WHILE !h[0, HASH_EXISTS] EVAL(INPUT("?")) r = h[0, HASH_REMOVE] WEND MSGBOX("おみごと")
攻撃すべきは、あれかあれ、ですね。
少なくとも二通りの答えがあるかと思います。
一応最後に。
定数はちゃんと定数を使いましょう。
内部表現を使うものではありません。
内部表現はいつ変更されても文句は言えないのです。
そして、定数は定数です。
変更してはいけません。