新中学生の次男かずは,陸上部に入部した。「2つのことをいっぺんにはできないから,球技は苦手」と言っていたかずにはリーズナブルな選択かもしれない。入部したといっても,1年生はゴールデンウィーク期間中は休みなので,家でパソコンに向かい,キーボードをパチパチとたたき遊んでいた。ほのちゃん(5歳)と一緒にぞうちゃんのいる石川動物園にも行った。
そんなかずがHSP(Hot Soup Processor)で作成している使用時間チェッカー(第155話参照)は,1つの壁にぶつかっていた。使用時間チェッカーの目的は,ついついパソコンでゲームをやりすぎてしまうかずが自分自身でチェックできるように,使用時間を記録することである。
起動した時刻と現時刻,経過時間を表示し,終了時にはテキストファイルに追記する。
新しい時刻が古いデータの上に,積み重なるように記録されていく。この使用履歴を表示するコードを書くところで,かずは詰まっていた。そのまま表示するだけなら,変数にファイル全体を読み込みmes命令で表示するだけでよい。上図と同じように表示されるはずだ。
かずは,これを新しい日順(日付の降順)だけど,同じ日では時間の早いデータから(時間の昇順に)表示したいと考えていた。 こんな風に(図1)。
テキストファイルの内容を変数に読み込んで,行単位に入れ替えを行うコードを作ろうとしていたが,なかなかアルゴリズム(解法)を思いつかないようだった。私は他に色々やりたいこともあったし,なんでも自分でやりたがり,助けをいやがるかずのことだからと,手を出さないでいた。
しかし,数日プログラムをいじっていても進展はなく,暗礁にのりあげてしまったようなので,「どうなっとるん?」と首を突っ込んだ。
「難しく考えずに,テキストファイルの内容を読み込んだ変数を,最初の行から順に読んでいって,別の変数に出力すればいいんじゃないが」と下のような図を書き説明を始めた(図2)。
青い矢印の方向に行を読み進み,日付が違ったら,その場所を覚えておき,今まで読んだ行の数だけ,赤い方向に戻りながら別の変数に行を編集していけば,希望通りになるのではと説明した。そして,日付が同じ時は,日付を出力するかわりにスペースを日付の長さと同じだけ編集すれば,図1のようになるだろうと付け加えた。
かずは「おおー」と大仰に驚き,パチパチと拍手した(かずの言動には「クレヨンしんちゃん」の影響が色濃く表われている)。「お前,親父をおちょくっているのか」と言いかけたら,「もうなんも言わんといて」とばかりに,プログラミングを始めた。絵に描けば,たいがいのことはなんとかなるものだ。下記が並び替え部分のコードである。
--------------------------------------------------------------- *narabikae notesel siyouzikan (1) notemax i (2) i2=0 onazi=0 siyouzikan2="" *subloop noteget hensyu,i2 (3) strmid tukihi,hensyu,0,9 (4) if i2=i { return } i2+=1 noteget hensyu,i2 strmid tukihi2,hensyu,0,9 if tukihi=tukihi2 { onazi+=1 } else { i3=i2-1 i4=i3 repeat onazi+1 noteget hensyu,i3 if i4=i3 { hensyu2=hensyu } else { strmid hensyu2,hensyu,8,35 hensyu2=" "+hensyu2+"" } siyouzikan2=""+siyouzikan2+""+hensyu2+"\n" (5) i3-=1 loop onazi=0 } goto *subloop ---------------------------------------------------------------HSPにはnoteで始まる命令群,メモリノートパッド命令が用意されており,文字列の固まり(ブロック)を文字列の配列のように扱うことができる。(1)のnotesel命令でテキストファイルの内容をまるごと読み込んだ変数siyouzikanをメモリノートパッド命令の対象に設定している。(2)のnotemax命令はブロックの行数を指定した変数(i)に入れる。(3)のnoteget命令は第2引数のインデックス(i2)で示される行を第1引数の変数(hensyu)に読み込む。(4)のstrmidは部分文字列の取り出しを行う。ロジックは図2と同じようになっている。(5)のsiyouzikan2に日付の降順,開始時間の昇順に並び替えた文字列のブロックが作成されていく。表示すると,下記のようになっている。
次の目標は日毎の使用時間合計を表示することらしい。