[Closed] Middle Middle Middle
I’m working on a better submission tool for my farm rendering and in nearly ever scenario I want to submit the frames to the render farm in a order like this…
Here is the frame range: 01…09
What i need to do is return an array that does the first and last frame, then gets the middle frame for each part until all frames are in the new array. This is what the final output should be and in this order.
01, 02, 03, 04, 05, 06, 07, 08, 09 –original
01, 09, 05, 03, 07, 02, 04, 06, 08 –ordered by middle
to further break it down step by step
01 , 09 -first and last frame
05 –middle frame of 01 – 09
03 –middle frame of 01 – 05
07 –middle frame of 05 – 09
02 –middle frame of 01 – 03
04 –middle frame of 03 – 05
06 –middle frame of 05 – 07
08 –middle frame of 07 – 09
I think this code can do it.
(
clearlistener()
prevArray = #("01","02","03","04","05","06","07","08","09","10","11","12","13","14","15","16","17")
orderedArray = #()
leftOrRight = true
function getStepCount =
(
local steps = 0
local middle = prevArray.count
do
(
steps += 1
middle = ceil (middle / 2.0)
)
while (middle > 1)
steps
)
function addValues n =
(
div = (pow 2 n)
for i=1 to (div-1) do
(
appendifunique orderedArray prevArray[(ceil ((prevArray.count / div) * i))]
)
)
local stepCount = getStepCount()
appendifunique orderedArray prevArray[1]
appendifunique orderedArray prevArray[prevArray.count]
for i=1 to (stepCount-1) do
(
addValues i
)
print orderedArray
)
That’s quite a lot of code
fn sortByMiddle arr =
(
local sorted = #()
local stepSize = amax 1 (arr.count - 1)
while (stepSize > 0) do
(
local index = 1
for index = 1 to arr.count by stepSize do
(
appendIfUnique sorted arr[index]
)
stepSize /= 2
)
sorted
)
sortByMiddle (for i = 1 to 9 collect i)
Yes it was dirty but did the job.
Yours is what I would have wanted to get ;).
Not as tidy, but this one’s a slightly faster function (1-50000 range took 200ms instead of 9000ms and 17705ms). And it only requires start and end range values, also easily accepts negative values.
fn RTMA_mid dp = floor((dp.v2-dp.v1)/2.0)+dp.v1
fn RangeToMiddlesArr a b =
(
if a<b then
(
dpArr = #()
dpArr[1] = datapair a b
arr = #()
arr[1] = a
arr[2] = b
while dpArr.count > 0 do
(
newdpArr =#()
for dp in dpArr do
(
local dpMid = (RTMA_mid dp)
if dp.v2-dp.v1 == 2 then append arr dpMid
else
(
if dpMid != dp.v1 AND dpMid != dp.v2 then append arr dpMid
if dpMid-dp.v1 > 1 then append newdpArr (datapair dp.v1 dpMid)
if dp.v2-dpMid > 1 then append newdpArr (datapair dpMid dp.v2)
)
)
dparr = #()
dpArr = newdpArr
)
arr
)
else false
)
I’m sure it can be done better, but my poor recursion-challenged brain can’t figure it out in a short amount of time.
i don’t sure that you function works right. try this array:
seed 0
a = (for i = 1 to 40 by (random 1 4) collect i)
sortByMiddle a
only LO’s algorithm meets the rule. two other are doing something their own.
Well, if the requirement is getting the middle parts, arguably my algorithm proves closer to the goal.
Was wondering what the distribution looked like, so I made a comparison graph (attached) of a sorted 1…100 array.
Y curve is lo: #(1, 100, 50, 99, 25, 49, 73, 97, 13, 37, 61, 85, 7, 19, 31, 43, 55, 67, 79, 91, …)
Z curve is mine: #(1.0, 100.0, 50.0, 25.0, 75.0, 13.0, 37.0, 62.0, 87.0, 7.0, 19.0, 31.0, 43.0, 56.0, 68.0, 81.0, 93.0, 4.0, 10.0, 16.0, …)