Luaでスターリンソート(不真面目編)


はじめに

今、最高にロックで、最高に不謹慎なスターリンソートが話題なので話題に乗り遅れないように参加してみました。
関数名は、JSSort(配列)1となります。

Luaで素直に書くと、多分こんな感じ

jssort.lua
-- 普通にFor文使って条件に合うものを集める
function JSSort(org)
  local sorted = {}
  local siberia = {} -- シベリア?!
  for i,value in ipairs(org) do
    if (i==1) or (value >= sorted[#sorted]) then
      sorted[#sorted+1] = value
    else
      siberia[#siberia+1] = value
    end
  end
  siberia = {} -- zap!
  return sorted
end
-------- Main ----------
local org_array = {1,2,5,3,7,7,4,10}
local sorted_array = JSSort(org_array)
print(table.concat(sorted_array, " "))

普通ってなんだっけ。最適化よりも粛清感をマシマシでお送りしました。

本家のGitHubに、ブラジルの方2がLua版を投稿しているけど、さすがにそれはひねくれすぎだと思う。でもこういうのも大好き。
https://github.com/gustavo-depaula/stalin-sort/blob/master/lua/sort.lua

おまけ

Luaの機能を紹介する意味で、ジェネリックForループを使った版も作ってみました。

LuaのジェネリックFor文の解説はこちら。
https://qiita.com/hevo2/items/604b5405a981fd5fd207

jssort2.lua
-- 「イテレータを回す関数」の仕様
--    (1)実行するたびに何らかの値を返すこと、(2)終了するときはnilを返すこと
-- クロージャを使って「イテレータを回す関数」を作成
local my_iterator = function(_array) 
  local pos = 0
  local max = 0
  return function()
    while (pos < #_array) do
      pos = pos + 1
      if ((pos == 1) or (_array[pos] >= max)) then
        max = _array[pos]
        return _array[pos]
      end
    end
    return nil
  end
end
-- ジェネリックForループ(独自定義イテレータ)を使って条件を満たす要素を集める
function JSSort(org)
  local sorted = {}
  for v in my_iterator(org) do
    sorted[#sorted+1] = v
  end
  return sorted
end
-------- Main ----------
local org_array = {1,2,5,3,7,7,4,10}
local sorted_array = JSSort(org_array)
print(table.concat(sorted_array, " "))

  1. そういえばスターリンのフルネームはJoseph-Stalinだから、略すとJSだよね・・・。閃いた! 

  2. Lua言語はブラジル生まれです。Luaはポルトガル語で月を意味するそうです。さすがLuaの本場(?)ですよね。