沖の雑記帳

基本的には趣味に絡んで雑多な内容を色々と

スターリンソートっていうのが流行っていたらしい

スターリンソートっていうのが流行っていたらしいんだけども流行に乗り遅れた。

とりあえず、Qiitaで最近ちょいちょい見るようになった大元はこれなのかな? qiita.com

なお、本家(?)は下記 github.com

ちょっとコード等が長いので表示分割

というわけで、自分も粛清ソートしてみたいなって思ったんだけどほとんど別の人が書いちゃってるし公式にも大量に上がってるのでそれよりもいいものは書ける気がしない。
あと、vim scriptはまだお勉強中につきQiitaに投稿するのははばかられる…気がする

" Script Name: stalinsort.vim
" Version:     0.1.0
" Last Change: August 06, 2019
" Author:      Hironao Oki <hironao.oki@gmail.com>
scriptencoding utf-8

" Anti reinclusion guards
if exists("g:loaded_stalinsort")
    finish
endif
let g:loaded_stalinsort = 1

" Support for |line-continuation|
let s:save_cpo = &cpo
set cpo&vim

" Functions
function! s:stalinsort(...)
    let res = []
    let args = s:argsfilter(a:000)
    for arg in args
        if  len(res) == 0 || len(res) > 0 && res[-1] <= arg
            call add(res, arg)
"     else
"         echo "exclude:".arg.",res[-1]:".res[-1].",".(res[-1] <= arg)
        endif
    endfor
    echo join(res)
endfunction

function! s:argsfilter(args)
    let res = []
    if len(a:args) > 0
        for arg in a:args
            try
                call eval(arg)
                call add(res, eval(arg))
            catch
            endtry
        endfor
    endif
    return res
endfunction

command! -nargs=* StalinSort call s:stalinsort(<f-args>)

" Restore previous 'cpo' value
let &cpo = s:save_cpo
unlet s:save_cpo
" vim: ts=2 sw=2 sts=2 noet

変数の扱いがカオスすぎて、未定義の文字列が0扱いになったりそれを除外しようとしたら00.0も除外されちゃったりで困ったので、強引に文字列を除く処理を頭に追加…
ぶっちゃけO(n)じゃないんじゃ…ってなってるし、そもそもこれソートじゃないじゃん!ってなってるけどルールに従わなかったら消されても仕方ないってことらしいので良いんじゃないかな?

あと一応、プラグインとして読み込めるようにコマンドに登録したりはしてるけど需要はなさそうなのでgithubには上げてない。
vimスクリプトのヘッダ部分って何書けばいいの?

さて、問題ははてなに書いたところでツッコミがいただけないということだ…わたしのブログはただのらくがき帳なので見に来る人があまりいないのが問題だ

ついでにバッチファイル版作ったけど事前処理が重すぎてO(n)でないのは確かだ

バッチファイル版修正しました。以前のものはバグが有って遅延展開の参照ミスってました。

@setlocal enabledelayedexpansion
@echo off
REM stalinsort.bat

set idx=0
set prev=0
for %%i in (%*) do (
  call :numchk %%i
  if errorlevel 1 (
    if !idx! gtr 0 (
      if %%i geq !prev! (
        set /a res[!idx!]=%%i
        set /a prev=%%i
        set /a idx=!idx!+1
      )
    ) else (
      set /a res[!idx!]=%%i
      set /a prev=%%i
      set /a idx=!idx!+1
    )
  )
)
for /l %%i in (0,1,%idx%) do (
  echo|set /p=!res[%%i]! 
)
goto :EOF

:numchk
set chknum=%1
if defined chknum set chknum=%chknum:0=%
if defined chknum set chknum=%chknum:1=%
if defined chknum set chknum=%chknum:2=%
if defined chknum set chknum=%chknum:3=%
if defined chknum set chknum=%chknum:4=%
if defined chknum set chknum=%chknum:5=%
if defined chknum set chknum=%chknum:6=%
if defined chknum set chknum=%chknum:7=%
if defined chknum set chknum=%chknum:8=%
if defined chknum set chknum=%chknum:9=%
if defined chknum set chknum=%chknum:-=%
if defined chknum (
  set /a tmpnum=%1
  if not !tmpnum!==0 (
    exit /b 1
  )
  exit /b 0
) else (
  exit /b 1
)