Charakterbewegungen hinzugefügt, Deko hinzugefügt, Kochrezepte angepasst
This commit is contained in:
parent
95945c0306
commit
a0c893ca0b
1124 changed files with 64294 additions and 763 deletions
109
mods/futil/util/selection.lua
Normal file
109
mods/futil/util/selection.lua
Normal file
|
@ -0,0 +1,109 @@
|
|||
local floor = math.floor
|
||||
local min = math.min
|
||||
local random = math.random
|
||||
|
||||
local swap = futil.table.swap
|
||||
local default_cmp = futil.math.cmp
|
||||
|
||||
futil.selection = {}
|
||||
|
||||
local function partition5(t, left, right, cmp)
|
||||
cmp = cmp or default_cmp
|
||||
local i = left + 1
|
||||
while i <= right do
|
||||
local j = i
|
||||
while j > left and cmp(t[j], t[j - 1]) do
|
||||
swap(t, j - 1, j)
|
||||
j = j - 1
|
||||
end
|
||||
i = i + 1
|
||||
end
|
||||
return floor((left + right) / 2)
|
||||
end
|
||||
|
||||
local function partition(t, left, right, pivot_i, i, cmp)
|
||||
cmp = cmp or default_cmp
|
||||
local pivot_v = t[pivot_i]
|
||||
swap(t, pivot_i, right)
|
||||
local store_i = left
|
||||
for j = left, right - 1 do
|
||||
if cmp(t[j], pivot_v) then
|
||||
swap(t, store_i, j)
|
||||
store_i = store_i + 1
|
||||
end
|
||||
end
|
||||
local store_i_eq = store_i
|
||||
for j = store_i, right - 1 do
|
||||
if t[j] == pivot_v then
|
||||
swap(t, store_i_eq, j)
|
||||
store_i_eq = store_i_eq + 1
|
||||
end
|
||||
end
|
||||
swap(t, right, store_i_eq)
|
||||
if i < store_i then
|
||||
return store_i
|
||||
elseif i <= store_i_eq then
|
||||
return i
|
||||
else
|
||||
return store_i_eq
|
||||
end
|
||||
end
|
||||
|
||||
local function quickselect(t, left, right, i, pivot_alg, cmp)
|
||||
cmp = cmp or default_cmp
|
||||
while true do
|
||||
if left == right then
|
||||
return left
|
||||
end
|
||||
local pivot_i = partition(t, left, right, pivot_alg(t, left, right, cmp), i, cmp)
|
||||
if i == pivot_i then
|
||||
return i
|
||||
elseif i < pivot_i then
|
||||
right = pivot_i - 1
|
||||
else
|
||||
left = pivot_i + 1
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
futil.selection.quickselect = quickselect
|
||||
|
||||
futil.selection.pivot = {}
|
||||
|
||||
function futil.selection.pivot.random(t, left, right, cmp)
|
||||
return random(left, right)
|
||||
end
|
||||
|
||||
local function pivot_medians_of_medians(t, left, right, cmp)
|
||||
cmp = cmp or default_cmp
|
||||
if right - left < 5 then
|
||||
return partition5(t, left, right, cmp)
|
||||
end
|
||||
for i = left, right, 5 do
|
||||
local sub_right = min(i + 4, right)
|
||||
local median5 = partition5(t, i, sub_right, cmp)
|
||||
swap(t, median5, left + floor((i - left) / 5))
|
||||
end
|
||||
local mid = floor((right - left) / 10) + left + 1
|
||||
return quickselect(t, left, left + floor((right - left) / 5), mid, pivot_medians_of_medians, cmp)
|
||||
end
|
||||
|
||||
futil.selection.pivot.median_of_medians = pivot_medians_of_medians
|
||||
|
||||
--[[
|
||||
make use of quickselect to munge a table:
|
||||
median_index = math.floor(#t / 2)
|
||||
after calling this,
|
||||
t[1] through t[median_index - 1] will be the elements less than t[median_index]
|
||||
t[median_index] will be the median (or element less-than-the-median for even length tables)
|
||||
t[median_index + 1] through t[#t] will be the elements greater than t[median_index]
|
||||
pivot is a pivot algorithm, defaults to random selection
|
||||
cmp is a comparison function.
|
||||
returns median_index.
|
||||
]]
|
||||
function futil.selection.select(t, pivot_alg, cmp)
|
||||
cmp = cmp or default_cmp
|
||||
pivot_alg = pivot_alg or futil.selection.pivot.random
|
||||
local median_index = math.floor(#t / 2)
|
||||
return quickselect(t, 1, #t, median_index, pivot_alg, cmp)
|
||||
end
|
Loading…
Add table
Add a link
Reference in a new issue