120 122 bytes
Try it online!
My original code worked for all the provided test cases, but was actually faulty, so +2 bytes for the fix. Dang!
Lots of bytes since
dc doesn't have any inbuilt sorting mechanism, and very little in the way of stack manipulation.
9k sets the precision to 9 places since we need the possibility of digits past the decimal point.
dc doesn't float, so hopefully this is satisfactory.
zsa0si[li:sli1+dsila>A]dsAx dumps the entirety of the stack into array
s, and preserves the number of items in register
R all make up a bubble sort.
M is our 'main' macro, so to speak, so I'll cover that one first.
[1si0sclSxlc1=M]dsMx We reset increment register
i to 1, and check register
c to 0. We run macro
S, which is one pass through the array. If
S by proxy) made any changes, it would have set register
c to one, so if this is the case we loop through
[lidd1-;sr;s<R1+dsila>S]sS One pass through the array. We load the increment counter
i, duplicate it twice, and decrement the top version of it by one. Essentially
i is always high, so we compare
i-1. Load the two values from array
s, compare them, and if they're going the wrong way we run our swapping macro,
R. Then we keep on incrementing
i, comparing it to
a, and running
S until that comparison tells us we've hit the end of our array.
[1scddd;sr1-;sli:sr1-:s]sR An individual instance of swappery in array
a. First we set our check register
c to 1 so that
M knows we made changes to the array.
i should still be on the stack from earlier, so we duplicate it three times. We retrieve
i indexed item from
a, swap our top-of-stack so that
i is present again, subtract one from it, and then retrieve that item from
a. Here we run into a stack manipulation limitation, so we have to load
i again and we store our previous
i-1 value into that index in
a. Now we just have our old
a value on the stack and
i itself, so we swap these, subtract 1 from
i, and replace the value in
M will stop running when it sees no changes have been made, and now that things are sorted we can do the actual median operation.
a already has the length of array
s, we load it and divide by two. Testing for evenness would be costly, so we rely on the fact that dc uses the floor of a non-whole value for its index. We divide
a by two and duplicate the value. We then get from
s the values indexed by (
a/2-.5) and (
a/2)mod 1)). This gives us the middle value twice for an odd number of values, or the middle two values for an even number.
+2/p averages them and prints the result.