バブルソート

Nscripter バブルソート - Google 検索なんてリファラがあったので、NScripterでのソート実装をしてみた。

使い方

4つの命令を追加する。どれも、一次元の配列変数を扱う。
bubble_sortとcomb_sortは昇順ソート。アルゴリズムが違うだけで得られる結果は同じ。
reverse_sortは単純に配列の中身を逆順にするだけ。
shuffle_sortは逆にランダムに並べなおす。

define部

mov %0,100 ; 適宜変更
numalias sort_num,%0:inc %0
numalias sort_len,%0:inc %0
numalias sort_temp,%0:inc %0
numalias sort_loop1,%0:inc %0
numalias sort_loop2,%0:inc %0
numalias sort_count,%0:inc %0
numalias sort_h,sort_count
defsub bubble_sort
defsub comb_sort
defsub reverse_sort
defsub shuffle_sort

game以下、start節前

;==================
; バブルソート
;==================
; 配列変数(一次元)の中身を小さい順に並べなおす。アルゴリズムはバブルソート
; 第一引数:並べ替えたい配列変数の番号
; 第二引数:並べ替えたい配列変数の最大添え字
*bubble_sort
getparam %sort_num,%sort_len
for %sort_loop1=1 to %sort_len-1
	mov %sort_count,0
	for %sort_loop2=%sort_len to %sort_loop1 step -1
		notif ?%sort_num[%sort_loop2]<?%sort_num[%sort_loop2-1] jumpf
		mov %sort_temp,?%sort_num[%sort_loop2]
		mov ?%sort_num[%sort_loop2],?%sort_num[%sort_loop2-1]
		mov ?%sort_num[%sort_loop2-1],%sort_temp
		inc %sort_count
~
	next
	if %sort_count=0 break
next
return

;==================
; コームソート
;==================
; 配列変数(一次元)の中身を小さい順に並べなおす。アルゴリズムはコームソート
; 第一引数:並べ替えたい配列変数の番号
; 第二引数:並べ替えたい配列変数の最大添え字
; 参考:http://ja.wikipedia.org/wiki/%E3%82%B3%E3%83%A0%E3%82%BD%E3%83%BC%E3%83%88
*comb_sort
getparam %sort_num,%sort_len
mov %sort_h,(%sort_len+1)*10/13 ; step 1
 *comb_sort_step2
mov %sort_loop1,0 ; step 2
 *comb_sort_step3
mov %sort_loop2,%sort_loop1+%sort_h ; step 3
notif ?%sort_num[%sort_loop1]>?%sort_num[%sort_loop2] jumpf
mov %sort_temp,?%sort_num[%sort_loop1]
mov ?%sort_num[%sort_loop1],?%sort_num[%sort_loop2]
mov ?%sort_num[%sort_loop2],%sort_temp
~
inc %sort_loop1 ; step 4
notif %sort_loop1+%sort_h>%sort_len goto *comb_sort_step3
mov %sort_h,%sort_h*10/13 ; step 5
notif %sort_h=0 goto *comb_sort_step2
return

;==================
; 逆順
;==================
; 配列変数(一次元)の中身を単純に逆順にする。
; 第一引数:並べ替えたい配列変数の番号
; 第二引数:並べ替えたい配列変数の最大添え字
*reverse_sort
getparam %sort_num,%sort_len
for %sort_loop1=0 to %sort_len/2-1
	mov %sort_loop2,%sort_len-%sort_loop1
	mov %sort_temp,?%sort_num[%sort_loop1]
	mov ?%sort_num[%sort_loop1],?%sort_num[%sort_loop2]
	mov ?%sort_num[%sort_loop2],%sort_temp
next
return

;==================
; シャッフル
;==================
; 配列変数(一次元)の中身をランダムに並べなおす。
; 第一引数:並べ替えたい配列変数の番号
; 第二引数:並べ替えたい配列変数の最大添え字
*shuffle_sort
getparam %sort_num,%sort_len
for %sort_loop1=0 to %sort_len-1
	rnd2 %sort_loop2,%sort_loop1,%sort_len
	mov %sort_temp,?%sort_num[%sort_loop1]
	mov ?%sort_num[%sort_loop1],?%sort_num[%sort_loop2]
	mov ?%sort_num[%sort_loop2],%sort_temp
next
return

蛇足

NScripter局所変数が存在しないため、再帰を利用したアルゴリズムの実装は難しい。つか、面倒くさい。
なので最強と名高いクイックソートやその手前のヒープソートなどは挑戦しなかった。