24

Cindyscript での整列演算
久保康幸 ＊

On sort operator of Cinsyscript
Yasuyuki Kubo ＊Abstract
I compared how to arrange by multiple conditions with the sort operator of Cindyscript.

１. はじめに

KeTCindy で成績処理のページ [1] では，得点は高い順（降順），同じ得点の学生は学籍番号を昇順に並べるため reverse を使ったり，100 から引いた得点でソートしたりしている．ここで，疑問は，なぜ一度に複数の条件で並べ替えなかったのかということである．の CindyScript のマニュアル (Page last modified

on Wednesday 17 of August, 2016.) である．日本
語に翻訳する前のマニュアル（英語版）は，ローカルファイルとしてのマニュアル (Page last modified

on Monday 14 of July, 2014.) を参照した．最新版を確認するためサイトの接続を試みたが，以前は接続できたサイトが，現在は接続できない．

用意した cdy ファイルにデータを入力して，動作表1を確認すると，CindyScript のソート演算子は，指Orgdata

定された条件以外については，元の順序を維持してOrgdata="いると言うことである．用意した３つの条件を順に

学籍番号

受検者

第１回

第２回

第３回使ってソートすることにより，それが確認できた．

160101160102160103160104160105160106160107160108160109160110160111160112160113160114160115160116160117160118
";

氏名 01

60
60
60
40404050
50506060
60
40404050
5050

75856575
85
6575
85
6575
85657585657585656360334245374143696360
33424537414369

この性質を利用して，[1] の例では，用意したデータが始めに学籍番号の若い順（昇順）に並んでいるから，ソートを１つの条件で行なっていると考えられる．これは，「学籍番号の若い順に並んでいる」という暗黙の条件を利用している．今回は，暗黙の条件を仮定しないで，複数の条件をすべて明示した命令でのソートを目指す．つまり，初めのデータが学籍番号の若い順番になってなくとも，得点と学籍番号という２つの条件でソートしたいなら，もし，学籍番号の若い順番にソートされている可能性が高い
データであっても，学籍番号によるソートをしてから，得点による並び替えをするということで，目的の順番に並び替えることが出来る．
こ の 論 文 で は ，複 数 条 件 を 明 示 的 に 利 用 し た
ソートの方法を比較した．なお，動作を確認したのは，Cinderella（version 2.9 build 1898）に付属の CindyScript であり，マニュアルは，その Cin-derella のメニューから呼び出される Cinderella マ

氏名 02
氏名 03
氏名 04
氏名 05
氏名 06
氏名 07
氏名 08
氏名 09
氏名 10
氏名 11
氏名 12
氏名 13
氏名 14
氏名 15
氏名 16
氏名 17
氏名 18

ニュアルのリンク先にあるローカルファイルとして＊ 総合教育科

平成 29 年 11 月 30 日受理

25
弓削商船高等専門学校 紀要 第 40 号 (平成 30 年)

２. 並び替えデータの準備
上のようなデータ（表１）を用意した．
このデータは，第１回の得点が 3 人ずつ 60 点，40 点，50 点として得点が高い順でも低い順でもないようにした．それぞれの 3 人は，75 点，85 点，65点ずつとして 3 人の中でも，得点が高い順でも低い順でもないようにした．最初の 9 人をコピーして，3 回の得点が同じ受験者が複数いるようにした．それらは学籍番号か氏名によってのみ区別される．
用意した表１のデータを CindyScript が扱う型に直すため，KETCindy の命令で，datalist=Tab2list(Orgdata);
data=datalist_(2..length(datalist));を実行したものが表２の data である．

CindyScript の演算子 sort をデータ data に対して実行する．なお，2 行目の命令は，項目の行を除外して並べ替えるため datalist の 2 行目以降をdata とするという内容である．

表2

３. 複数の条件による並び替え用意した data を第１回の得点（第 3 番目の値）で昇順に並べ，それが同じなら，第２回の得点（第4 番目の値）で昇順に並べる．そして，それらが同じ受検者を学籍番号（第 1 番目の値）の逆順（降順）に並べることで，ソート演算子 sort の動作を確認した．その方法を下に紹介する．
３. １

ソートを繰り返す[1] の例から確認できるように，CindyScript のソート演算子は，指定された条件以外については，元の順番を維持しているから，複数の条件を逆の順番に適用してソートを繰り返せば良い．
目的とする順番のため，まず，次の命令で学籍番号の逆順に並べる．学籍番号をそのまま比較して並べ替えると，番号の若い順になり変化しないので，

dt=sort(data,-1*(#_1));
これによって，得られるデータ dt は，次のようになる（表３）．

data（項目行を除外）

data="
160101 氏名 01
160102 氏名 02
160103 氏名 03
160104 氏名 04
160105 氏名 05
160106 氏名 06
160107 氏名 07
160108 氏名 08
160109 氏名 09
160110 氏名 10
160111 氏名 11
160112 氏名 12
160113 氏名 13
160114 氏名 14160115 氏名 15160116 氏名 16160117 氏名 17
160118 氏名 18";

606060404040505050606060404040
50
50
50

75
85
65
75
85
65
75
85
65
75
85
65
75
85
65
75
85
65

63
60
33
42
45
37
41
43
69
63
60
33
42
45
37
41
43
69

表3

dt="
160118160117160116160115160114160113160112160111160110160109160108160107160106160105160104160103160102160101";dt（学籍番号を降順）

氏名 18
氏名 17
氏名 16
氏名 15
氏名 14
氏名 13
氏名 12
氏名 11
氏名 10
氏名 09
氏名 08
氏名 07
氏名 06
氏名 05
氏名 04
氏名 03
氏名 02
氏名 01

50
50
50
40
40
40
60
60
60
50
50
50
40
40
40
60
60
60

65
85
75
65
85
75
65
85
75
65
85
75
65
85
75
65
85
75

69
43
41374542336063694341374542336063

次に，第 4 番目の値で昇順に並べ替える．

dt=sort(dt,#_4);

26
Cindyscript での整列演算という命令により，次のように dt が変化する（表４）．

比較すれば，まず A の得点で比較して，それが同じなら B の得点を見て並べることが出来る．これのdt は，4 番目の値で昇順に並び，4 番目の値が同じものは 1 番目の値で降順に並んでいる．
最後に最も優先度の高い 3 番目の値で昇順に並べる．今の dt に対して，さらに次の命令

dt=sort(dt,#_3);

欠点は，どんどん数値が大きくなることである．
それを回避する方法として，プログラムの確認における視認性の問題を考えなければ，A の得点を1000 倍する代わりに B の得点の最大値より大きい数値（例えば 100）をかけて，B と加えることも出来る．この考え方でプログラムを書いた例を紹介すを実行する．これで，次のように目的の順番にることはやめて，代わりに，次のような例で済ます．

A, B どちらのリストにある値も，すべて 5 よりなっている（表５）．

小さな自然数とする．5 は，B のリストの最大値よ
表4dt="
160118160115160112160109160106160103160116160113160110160107160104160101160117160114160111160108160105160102";dt（表３の dt を加工）

氏名 18
氏名 15
氏名 12
氏名 09
氏名 06
氏名 03
氏名 16
氏名 13
氏名 10
氏名 07
氏名 04
氏名 01
氏名 17
氏名 14
氏名 11
氏名 08
氏名 05
氏名 02

50
4060
50
4060
50
4060
50
4060
50
4060
50
4060

65
65
6565
65
65
75
75
7575
75758585
85858585693733693733414263414263
434560434560

このように，ソートの条件を重ねるだけで，複数条件によるソートができる．おそらく，これが最も単純な考え方であるが，命令を繰り返すのでプログラムの評価は低いと思う．なお，マニュアルを見てり大きく，5 進数で考えたとき，A からの値を前の桁，B からの値を後ろの桁という 2 桁の数として考えれば，A による値でソートした後，それらが等しい場合に B の値でソートすることになる．

表5dt="
160115160106160113160104160114160105160118160109160116160107160117160108160112160103160110160101160111160102";dt（表４の dt を加工）

氏名 15
氏名 06
氏名 13
氏名 04
氏名 14
氏名 05
氏名 18
氏名 09
氏名 16
氏名 07
氏名 17
氏名 08
氏名 12
氏名 03氏名 10氏名 01氏名 11氏名 02404040404040505050505050606060606060656575758585656575758585656575758585373742424545696941414343333363636060

も，元の順番をなるべく活かすとは明示していないが不安である．
３. ２

数値を加える (1)３. ３

数値を加える (2)

前の方法は，並び替えの条件が数値の場合に限ら

例えば，2 つの科目 A, B の得点が，それぞれ 100れる．次のように修正することで，並び替えの条件点以下と決まっているなら，それぞれの数値は 3 桁が数値でない場合にも複数の条件によるソートがで以下である．科目 A の得点で並び替えたとき，同じきる．なお，もともとのソート演算子は，マニュア点数なら，さらに科目 B の得点を見て並び替えたい

ルによると「慣例として次の順序があります。ブーとするなら，A の得点に 0 を 3 つ続けて（つまり，ル値 < 数 < 文字列 < リスト」となっており，数得点を 100 倍して），B の得点を足す．その数値を値以外も並び替えが出来る．数値でないものを複数

27
弓削商船高等専門学校 紀要 第 40 号 (平成 30 年)の条件で並び替えるとき，先の節の方法は，すぐにそれらをペアにして，複素数にしてから，並び替えは使えない．そこで，数値でないものの条件についをすれば良いことが分かる．ては，順位をつけて数値化すれば良い．なお，[1] でつまり，2 つの条件をペアにして，複素数にしては並び替えを利用して順位をつけている．並び替え

比較すれば，まず実部の順序で並べて，実部が同じをせずに順位をつけるのに，CindyScript に関数がなら虚部の順序になるのと同様に，まず最初の要素用意されてないから，少し準備が必要だが，それにを比較して，最初の要素が同じなら，第２の要素のついては，別の機会に紹介する．

順序にするということで，目的とする順序になる．

３. ４

文字列として扱う

並び替えの条件に文字列のリストを含む場合に，順位付けをして数値化するのは，煩雑である．もし，数値のリストがけた数が揃っているなら，逆に，数値の方を文字列化すれば良い．複数の条件によるソートをしたければ，それらの文字列を繋げれば良い．ただし，文字列のリストも文字列の長さが揃っていることが条件になる．
値を文字列に直す演算子 text と文字列の結合 +を組合せて，例えば，次のような命令を実行する．

dt=sort(data,text(#_3)+text(#_4)+text(170000-(#_1)));

しかし，この方法は，今回のような 3 つの条件を見て並び替えるのには使えない．
そこで，複素数に変換することなく，リストそのものを比較してみてはどうだろうか．ただし，マニュアルの説明のリストの部分を読む限り，条件をリストにすると，リストにした条件の第 1 の要素だけを見てソートすると考えられる．マニュアルには，条件をリストにした例はない．
念のため，英語版のマニュアルから，この部分を引用する．

Two lists are compared by the first entry
in which they diﬀer.
英語版を読んでも，日本語版と異なる内容には受

ここでの注意点は，学籍番号（第１番目の値）を降順にするため，170000 から引いていることである．学籍番号の最大値が 170000 より小さいことをけ取れない．
今回のデータで，リストを比較する方法を確認するため，次のような命令を実行した．

利用して，逆の順番にした．
３. ５

条件をリストにする

dt=sort(data,[#_3,#_4,-1*(#_1)]);

これまでに紹介した方法の不満を一気に解決する

なお，3 つ組みリストの 3 番目だけ-1*(#_1) と方法として，条件をリストにして比較する方法が考いうようにしたのは，第 1 番目の値を降順にするた

えられる．

めである．文字列の結合の場合と違って，第 1 番目

まず，マニュアルの説明を引用する．

CindyScript においては、すべての要素はどんな２つの要素でも比較できるような自然な順序を有します。２つの要素は等しいか、どちらかが大きくなります。実数では通常の数の順序です。文字列では辞書順です。複素数はまず実部の順序で並べ、実部が同じなら虚部の順序になります。 リストは、最初の要素を比較します。さらに、慣例として次の順序があります。
ブール値 < 数 < 文字列 < リストの値の最大値を気にすることなく，負の数にするだ
けで良い．
この命令の実行により，目的とする並び替え（表５と同じもの）を得た．
４. まとめ
今回，確認したなかでは，最後の方法が最も良いと考える．その次は，プログラムの行数が多くなるが，最初に紹介した命令を重ねる方法である．ただし，与えられたデータがある順番で並んでいることを期待せず，並び替えに使う条件は，すべて命令として明示しておくことにする．

なお，CindyScript での複素数は，a+i*b というまた，どちらの方法も，マニュアル（ローカルように表したものを指す．演算子 complex により，ファイル）に示されていない性質を用いている．

ユークリッド座標系はガウスの複素数平面と同一視

Cinderella Japan 代表の入谷昭先生に会ったときされ，点 [a,b] は複素数 a+i*b に変換される。に確認することにする．

これらを組み合わせて考えれば，ソートに使いた

今回，このように演算子の動作を確認するために

い 2 つの条件に使う項目の値が数値なら，いったんスクリプトを書くには，KETCindy によるデータ処

28
Cindyscript での整列演算
理に関する [2] および，その経験が役に立った．また，このような複数条件によるソートは，入谷先生のサイト [1] だけでなく，CDC を用いた実験授業[3] でのデータ整理における要請もあった．
今回の動作確認は，KETCindy の上で行なった．
最近の KETCindy については，[4] に紹介されているように R 対応が進められているが，演算子 sort
は CindyScript 上のものなので，その影響はない．
参考文献および参考 URL[1] 入谷昭 : 成績処理 (https://sites.google.
com/site/ketcindy/home/cdv/shi-yan)[2] Y. Kubo : Data processing with KETCindy,
LNCS, vol.10407 IV,pp.240-250(2017).
[3] 西浦孝治ほか : 共同研究成果報告書, 豊橋技科
大高専連携教育プロジェクト 2016, (2017).
[4]「Ketpic.com」(http://ketpic.com/)[5]「Cinderella」 (http://www.cinderella.de/tiki-index.php)[6]「CinderellaJapan」(https://sites.google.
com/site/cinderellajapan/)