UWSCバッドノウハウクイズ

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("おみごと")

攻撃すべきは、あれかあれ、ですね。
少なくとも二通りの答えがあるかと思います。


一応最後に。
定数はちゃんと定数を使いましょう。
内部表現を使うものではありません。
内部表現はいつ変更されても文句は言えないのです。
そして、定数は定数です。
変更してはいけません。