記事閲覧

− 野ざらし言 −

5865 Re^16: N88-BASICのRENUMのようなマクロ

としき 2025/05/17(Sat) 20:55 [5842]へのコメント
http://toshiki.la.coocan.jp/
> 相変わらずツリーが乱れているようですが、大丈夫でしょうか。

ツリーが乱れたまま過去ログにプッシュアウトされたりすると、ひどいことに
なりそうな気もします。回線に不具合がありそうなら、携帯電話経由なり、
何らかの方法で解決されたほうがよろしいかと。

さて、要素技術のツリーが深くなってしまったので、浅めのところにつけます。
とりあえず、当社比でかなりの高速化が達成できたのでアップします。
とはいえ、いろいろと聞き倒した要素技術のうち、実際に使ったのは検索の
戻り値だけ、というような感じです。


= renum.def(ver. 0.20)
i:初期値       initial num
a:増分         addition
n:新行番号     new num
o:旧行番号     old num
c:旧番検索結果 check count
h:処理中の行   handling line ※論理行番号 ln


N88-BASICのコードは半角大文字が前提(半角小文字はあえて未対応)


*m
1 ^^ "renum.def"
;初期設定                                       ;vwxの常駐確認とか?
    a=10,
    n=o=0,
    mp[=2, ps[=pa, RX[+, Dn[-,
    &s
    &01
    
    #^ #<                                       ;カーソルを先頭行の行頭にして
    &n i=r,                                     ;初期値取得
    (r+1)??{ &m(41) >e }                        ;準備ができていないなら終了
    
    
    ;メインループ
                                                ;先頭行は行番号の変更なし
    :w                                          ;while(次の行に動ければ)
        #> #d                                   ;次の行にカーソルを移動し
        #d (r==-1)?>u                           ;その結果が最終行ならループ脱出
        #<
        h=ln,
        c=0,                                    ;検索結果初期化
        &n o=r,                                 ;旧行番号取得
        n=i+(h-1)*a,                            ;新行番号算出
        
        #55 " " &?("%d",o) #m #r c+=r, #c c+=r, ;旧番存在確認
        &#J(h) #< #t &?("%d",n)                 ;処理している行に戻って新番化
        (c==-2)??{&10}                          ;旧番号存在時のみ置換実施
    
    >w
    :u
    
    ;後処理
    #56 "\([ \t]+\)FTHEN" #m "\1THEN" #m "ay"
    #56 "\([ \t]+\)FELSE" #m "\1ELSE" #m "ay"
    #56 "\([: \t]+\)FGOTO" #m "\1GOTO" #m "ay"
    #56 "\([: \t]+\)FGOSUB" #m "\1GOSUB" #m "ay"
    #56 "\([: \t]+\)FRESTORE" #m "\1RESTORE" #m "ay"
    #56 "\([: \t]+\)FRESUME" #m "\1RESUME" #m "ay"
    
    
    Dn], RX], ps], mp],
    :e ;end
    &d
    .

01:
;最初のチェック
;例えば、全ての論理行が行番号+半角空白で始まっていることの確認、とか。

.


10:
#56 "\([ \t]+\)THEN\([ \t]+\)" &?("%d",o) "$$" #m
    "\1FTHEN\2" &?("%d",n) #m "ay"
#56 "\([ \t]+\)THEN\([ \t]+\)" &?("%d",o) "\([^0-9]\)" #m
    "\1FTHEN\2" &?("%d",n) "\3" #m "ay"

#56 "\([ \t]+\)ELSE\([ \t]+\)" &?("%d",o) "$$" #m
    "\1FELSE\2" &?("%d",n) #m "ay"
#56 "\([ \t]+\)ELSE\([ \t]+\)" &?("%d",o) "\([^0-9]\)" #m
    "\1FELSE\2" &?("%d",n) "\3" #m "ay"

#56 "\([: \t]+\)GOTO\([ \t]+\)" &?("%d",o) "$$" #m
    "\1FGOTO\2" &?("%d",n) #m "ay"
#56 "\([: \t]+\)GOTO\([ \t]+\)" &?("%d",o) "\([^0-9]\)" #m
    "\1FGOTO\2" &?("%d",n) "\3" #m "ay"

#56 "\([: \t]+\)GOSUB\([ \t]+\)" &?("%d",o) "$$" #m
    "\1FGOSUB\2" &?("%d",n) #m "ay"
#56 "\([: \t]+\)GOSUB\([ \t]+\)" &?("%d",o) "\([^0-9]\)" #m
    "\1FGOSUB\2" &?("%d",n) "\3" #m "ay"

#56 "\([: \t]+\)RESTORE\([ \t]+\)" &?("%d",o) "$$" #m
    "\1FRESTORE\2" &?("%d",n) #m "ay"
#56 "\([: \t]+\)RESTORE\([ \t]+\)" &?("%d",o) "\([^0-9]\)" #m
    "\1FRESTORE\2" &?("%d",n) "\3" #m "ay"

#56 "\([: \t]+\)RESUME\([ \t]+\)" &?("%d",o) "$$" #m
    "\1FRESUME\2" &?("%d",n) #m "ay"
#56 "\([ \t]+\)RESUME\([ \t]+\)" &?("%d",o) "\([^0-9]\)" #m
    "\1FRESUME\2" &?("%d",n) "\3" #m "ay"
    
*

旧バージョンは、とにかく全ての行を変換する、というものでした。
ある意味、わかりやすいロジック。だけど、それが遅くなる根本原因。
なので、必要なところだけ変換するようにしました。
そして、必要なところはどこか、というのを確認するのに検索を使いました。
また、今回は論理行番号を使うコードということもあって、検索後の戻りに
ついても論理行番号を使ってみました。



さて、実際にどのくらい高速化したか測定してみました。
測定に使った行番号変換に使ったBASICプログラムは、自作のオセロのコード。
論理行数約220行。
あいにく、ストップウォッチは手元にありません。会社で使っているスマホなら
ストップウォッチがついているのですが、手元のガラケーにはストップウォッチ
の機能がないので、デジタルの時計表示を目で追いかける形。なので、精度に
ついては気にしてはいけない。

まず、めざらさんのマクロ。15秒から16秒で完了です。
次、私の旧バージョン。&sを使わないと、概ね3分くらいかかります。
&sを使ったときの速度は測っていませんが、半分にはならない。
そして、私の今回のバージョン。
&sを使わないと30秒前後。
そして、&sを使うと、やった、10秒強。

ただ、測定して不思議に思ったこと。
元のBASICは、行番号1000から始まるコードです。
これを、10000から始まるコードに変換することをクリアするのが最初。
これができなければロジックにバグがある。
つぎに、変なバグが紛れ込んでいたらわかるように、990から始まる変換と、
1030から始まる変換を行ってみました。
変換結果はいずれも、めざらさんのマクロと一致したので、あまりにも致命的な
バグはないと思うというか、全く異なるロジックであるにもかかわらず同じ誤り
を犯すというのは考えにくいので、この辺は大丈夫でしょう。
ただ、所要時間の面では面白い結果となりました。
私の作ったマクロでは、なぜか1030から始まる変換だけ遅い。
旧バージョンは、他の変換が3分前後なのに対して20秒くらい遅いだけなので、
比率ではたいした事はない。
ところが新バージョン。
画面表示を止めないものは、他が25秒くらいに対して38秒。
画面表示を止めたものは、他が10秒くらいに対して17秒。
ん〜、変換前後の桁数の問題ではないな。
なんか、重複した番号が発生したときに著しく遅くなる、とかありそう。
この辺を解決できて常に一定の速度が出せるアルゴリズムを思いつければ面白い
のだけど、なかなか難しそう。
また、想定外の何か特殊な場合に変換を誤ることもありそう。
これはそういうものにお目にかからないと実際に解決するのは無理そうだけど。
 

関連記事一覧ツリー (▼ を押すとツリー全体を一括表示します)

- 5731.N88-BASICのRENUMのようなマクロ - としき 25/03/29-14:22

返信フォーム (この記事に返信する場合は下記フォームから投稿して下さい)

おなまえ :
Eメール :
タイトル :
メッセージ: 通常モード(推奨)  整形モード(非推奨)  preモード(空白再現)
※ プログラムコード等を含まない場合は,できるだけ通常モードをご利用ください。

参照先 :
暗証キー: (英数字で8文字以内) プレビューなし


- 以下のフォームから自分の投稿記事を修正・削除することができます -

処理 記事No. 暗証キー