mathの拡張
適宜追加していきますよー。
math.lua
do -- 素数処理部分 local prime_list = {2, 3, 5, 7, 11, 13, 17, 19, 23} -- 分子と分母を与える。それが整数になるならfalseを、そうでなければtrueを返す。 local div_test = function(child, mother) if 0 == child % mother then return false end return true end local prime_test = function(num) local limit = math.sqrt(num) -- ショートカット。平方根が整数なら素数じゃない。 if limit == math.floor(limit) then return false end local count = 2 local mother = nil local res = true while true do mother = prime_list[count] if mother > limit then break end res = div_test(num, mother) if not(res) then break end count = count + 1 end return res end local calc_next_prime = function() local test = prime_list[#prime_list] + 2 while true do if prime_test(test) then break end test = test + 2 end prime_list[1+#prime_list] = test return test end local mt = {} mt.__index = function(t, k) while not(prime_list[k]) do calc_next_prime() end return prime_list[k] end mt.__newindex = function() NSOkBox("代入はできません。", "prime") NSEnd() end -- 素数列 math.prime = setmetatable({}, mt) -- 与えられた数値が素数であればそれを。 -- そうでなければその値を超える最初の素数を返す。 math.next_prime = function(num) if num<3 then return 2 end -- ショートカット -- 現在計算された中で最大の素数を取り出す。 local max = prime_list[#prime_list] -- 最大の素数が与えられた数値未満ならば、 -- 既知素数がそれ以上になるまで計算する。 if max < num then while max < num do max = calc_next_prime() end return max end -- 最大の素数が指定された値と同じならば、それを返す。 if max == num then return num end -- そうでなければ、逆に計算していく。 local before = nil local count = #prime_list while true do before = max count = count - 1 max = prime_list[count] if max<num then return before end end end -- 素数かどうか判断する。 math.is_prime = function(num) return num == math.next_prime(num) end end
math.prime(テーブル)
配列型のテーブルで、math.prime[1]にアクセスすると、素数列の最初の数値、2が返されます。
同じように、[2]で3が、[3]で5が返ってきます。
※内部的に、アクセスされる度に地味に計算してます。
math.next_prime
関数です。数値を一つ与えます。すると、その数値と同じか、数値を上回る最初の素数のどちらかを返します。
math.is_prime
関数です。数値を与えると、それが素数かどうかをbooleanで返してきます。