dc, 120 122 bytes
9kzsa0si[li:sli1+dsila>A]dsAx[1scddd;sr1-;sli:sr1-:s]sR[lidd1-;sr;s<R1+dsila>S]sS[1si0sclSxlc1=M]dsMxla2/dd1%-;sr.5-;s+2/p
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 a
.
Macros M
, S
, and 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
(actually, R
, but S
by proxy) made any changes, it would have set register c
to one, so if this is the case we loop through M
again.
[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
and 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 i
-indexed a
value on the stack and i
itself, so we swap these, subtract 1 from i
, and replace the value in a
.
Eventually 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.
la2/dd1%-;sr.5-;s+2/p
Since 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-((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.
Can we output as a fraction over 2 (e.g.
7/2
or8/2
) – Post Rock Garf Hunter – 2017-01-08T23:34:17.543According to this fractions are fine.
– flawr – 2017-01-08T23:36:10.47015How is this not already a challenge? – orlp – 2017-01-08T23:53:26.307
That is the very same I was wondering too. – flawr – 2017-01-08T23:54:41.463
If our language can't handle decimals can we assume input is only integers? – Post Rock Garf Hunter – 2017-01-09T00:32:41.743
What if our language doesn't have lists? Can we use dynamically initialized arrays? – Wade Tyler – 2017-01-09T00:51:06.180
@wheatwizard as long as it producces the correct output, which might have decimals, thats ok! – flawr – 2017-01-09T10:41:41.137
@WadeTyler Yes, you can also use a variable number of arguments instead, for instance. – flawr – 2017-01-09T10:43:21.397
1
@orlp This is a subset of this challenge.
– AdmBorkBork – 2017-01-09T17:44:08.610#Q, 3 bytes med Taken from here.
– Adám – 2017-01-09T20:04:38.7933It's also makes a nice fastest code challenge as there are some interesting linear time algorithms. – None – 2017-01-10T10:51:10.993
I know this challenge is ancient, but You should add at least one test case with an even number of arguments where the mean over the complete array differs from the median; e.g. the 3rd case with an extra
1.5
. – Titus – 2018-09-30T05:26:43.160@Titus This is a very good point, thank you! I'll add some later today! – flawr – 2018-09-30T11:43:09.497