Calcular a mediana

32

Desafio

Dada uma lista não vazia de números reais, calcule sua mediana.

Definições

A mediana é calculada da seguinte forma: primeiro classifique a lista,

  • se o número de entradas for ímpar , a mediana é o valor no centro da lista classificada,
  • caso contrário, a mediana é a média aritmética dos dois valores mais próximos do centro da lista classificada.

Exemplos

[1,2,3,4,5,6,7,8,9] -> 5
[1,4,3,2] -> 2.5
[1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,-5,100000,1.3,1.4] -> 1.5
[1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,-5,100000,1.3,1.4] -> 1.5
flawr
fonte
Podemos produzir como uma fração acima de 2 (por exemplo, 7/2ou 8/2) #
Wheat Wizard
De acordo com esta frações estão bem.
flawr
15
Como isso ainda não é um desafio?
orlp
11
@orlp Este é um subconjunto deste desafio .
AdmBorkBork
3
Também é um bom desafio de código mais rápido, pois existem alguns algoritmos de tempo linear interessantes.

Respostas:

18

Python 2 , 48 bytes

Uma função sem nome que retorna o resultado. -1 byte graças ao xnor.

lambda l:l.sort()or(l[len(l)/2]+l[~len(l)/2])/2.

O primeiro passo é obviamente classificar a matriz usando l.sort(). No entanto, só podemos ter uma instrução em um lambda, portanto, utilizamos o fato de que a função de classificação retorna Noneadicionando um or- como Noneé falso no Python, isso indica para avaliar e retornar a próxima parte da instrução.

Agora que temos a lista classificada, precisamos encontrar os valores intermediários ou intermediários.

Usar um condicional para verificar a paridade do comprimento seria muito detalhado; portanto, obtemos os índices len(l)/2e ~len(l)/2:

  • O primeiro é o piso (comprimento / 2) , que obtém o elemento do meio, se o comprimento for ímpar, ou o item esquerdo no par central, se o comprimento for par.
  • A segunda é a inversão binária do comprimento da lista, avaliando como -1 - piso (comprimento / 2) . Devido à indexação negativa do Python, isso basicamente faz o mesmo que o primeiro índice, mas ao contrário do final da matriz.

Se a lista tiver um comprimento ímpar, esses índices apontarão para o mesmo valor. Se for de comprimento uniforme, eles apontarão para os dois itens centrais.

Agora que temos esses dois índices, encontramos esses valores na lista, somamos e dividimos por 2. A casa decimal à direita em /2.garante que seja a divisão flutuante em vez da divisão inteira.

O resultado é retornado implicitamente, pois esta é uma função lambda.

Experimente online!

FlipTack
fonte
Parece que um lambda vence apesar da repetição:lambda l:l.sort()or(l[len(l)/2]+l[~len(l)/2])/2.
xnor
@xnor Obrigado! Quando tentei, contei acidentalmente o arquivo f=, pensando que era 1 byte a mais.
FlipTack
13

Python3 - 31 30 bytes

Guardou um byte graças a @Dennis!

Eu não estava planejando uma resposta embutida, mas encontrei este módulo e achei muito legal, porque não fazia ideia de que ele existia.

from statistics import*;median

Experimente online aqui .

Maltysen
fonte
6
from statistics import*;mediansalva um byte.
Dennis
@ Dennis oh legal. isso é sempre mais curto?
Maltysen
2
Sempre é melhor do que usar __import__, mas import math;math.logsuperaria from math import*;log.
Dennis
9

Geléia , 9 bytes

L‘HịṢµ÷LS

Experimente online!

Explicação

Ainda estou pegando o jeito de Jelly ... não consegui encontrar os componentes internos para a mediana ou a média de uma lista, mas é muito conveniente para esse desafio que o Jelly permita que índices não inteiros sejam incluídos nas listas, nesse caso, ele retornará um par dos dois valores mais próximos. Isso significa que podemos trabalhar com metade do comprimento da entrada como índice e obter um par de valores quando precisarmos calculá-lo.

L          Get the length of the input.
 ‘         Increment it.
  H        Halve it. This gives us the index of the median for an odd-length list
           (Jelly uses 1-based indexing), and a half-integer between the two indices
           we need to average for even-length lists.
   ịṢ      Use this as an index into the sorted input. As explained above this will
           either give us the median (in case of an odd-length list) or a pair of
           values we'll now need to average.
     µ     Starts a monadic chain which is then applied to this median or pair...
      ÷L     Divide by the length. L treats atomic values like singleton lists.
        S    Sum. This also treats atomic values like singleton lists. Hence this
             monadic chain leaves a single value unchanged but will return the
             mean of a pair.
Martin Ender
fonte
Claro, Æṁvai trabalhar agora
caird coinheringaahing
9

Flak cerebral , 914 + 1 = 915 bytes

([]){({}[()]<(([])<{({}[()]<([([({}<(({})<>)<>>)<><({}<>)>]{}<(())>)](<>)){({}())<>}{}({}<><{}{}>){{}<>(<({}<({}<>)<>>)<>({}<>)>)}{}({}<>)<>>)}{}<>{}>[()]){({}[()]<({}<>)<>>)}{}<>>)}{}([]<(()())>(<>))<>{(({})){({}[()])<>}{}}{}<>([{}()]{}<(())>){((<{}{}([[]]()){({}()()<{}>)}{}(({}){}<([]){{}{}([])}{}>)>))}{}{(<{}([[]]()()){({}()()<{}>)}{}({}{}<([]){{}{}([])}{}>)>)}{}([(({}<((((((()()()){}){}){}()){})[()()()])>)<(())>)](<>)){({}())<>}{}<>{}{}<>(({})){{}{}<>(<(())>)}{}(({}<>)<{(<{}([{}])>)}{}{(({})<((()()()()()){})>)({}(<>))<>{(({})){({}[()])<>}{}}{}<>([{}()]{})({}<({}<>)<>>((((()()()){}){}){}){})((()()()()()){})<>({}<>)(()()){({}[()]<([([({})](<()>))](<>())){({}())<>}{}<>{}{}<>(({})){{}{}<>(<(())>)}{}(({})<>)<>{(<{}([{}])>)}{}({}<>)<>({}<><({}<>)>)>)}{}({}(<>))<>([()]{()<(({})){({}[()])<>}{}>}{}<><{}{}>)<>(({}{}[(())])){{}{}(((<{}>)))}{}{}{(<{}<>([{}])><>)}{}<>}{}>){(<{}(((((()()()()())){}{})){}{})>)}{}

Requer que o -Asinalizador seja executado.

Experimente online!

Explicação

A espinha dorsal desse algoritmo é uma espécie de bolha que escrevi há algum tempo.

([]){({}[()]<(([])<{({}[()]<([([({}<(({})<>)<>>)<><({}<>)>]{}<(())>)](<>)){({}())<>}{}({}<><{}{}>){{}<>(<({}<({}<>)<>>)<>({}<>)>)}{}({}<>)<>>)}{}<>{}>[()]){({}[()]<({}<>)<>>)}{}<>>)}{}

Não me lembro como isso funciona, então não me pergunte. Mas sei que classifica a pilha e até funciona para negativos

Depois que tudo foi resolvido, encontro 2 vezes a mediana com o seguinte pedaço

([]<(()())>(<>))<>{(({})){({}[()])<>}{}}{}<>([{}()]{}<(())>)  #Stack height modulo 2
{((<{}{}          #If odd
 ([[]]())         #Push negative stack height +1
 {                #Until zero 
  ({}()()<{}>)    #add 2 to the stack height and pop one
 }{}              #Get rid of garbage
 (({}){}<         #Pickup and double the top value
 ([]){{}{}([])}{} #Remove everything on the stack
 >)               #Put it back down
>))}{}            #End if
{(<{}                     #If even
  ([[]]()())              #Push -sh + 2
  {({}()()<{}>)}{}        #Remove one value for every 2 in that value
  ({}{}<([]){{}{}([])}{}>)#Add the top two and remove everything under them
>)}{}                     #End if

Agora tudo o que resta é converter para ASCII

([(({}<((((((()()()){}){}){}()){})[()()()])>)<(())>)](<>)){({}())<>}{}<>{}{}<>(({})){{}{}<>(<(())>)}{}(({}<>)<
{(<{}([{}])>)}{}  #Absolute value (put "/2" beneath everything)

{                 #Until the residue is zero 
(({})<            #|Convert to base 10
((()()()()()){})  #|
>)                #|...
({}(<>))<>{(({})){({}[()])<>}{}}{}<>([{}()]{})
({}<({}<>)<>>((((()()()){}){}){}){})((()()()()()){})<>({}<>)
                  #|
(()()){({}[()]<([([({})](<()>))](<>())){({}())<>}{}<>{}{}<>(({})){{}{}<>(<(())>)}{}(({})<>)<>{(<{}([{}])>)}{}({}<>)<>({}<><({}<>)>)>)}{}({}(<>))<>([()]{()<(({})){({}[()])<>}{}>}{}<><{}{}>)<>(({}{}[(())])){{}{}(((<{}>)))}{}{}{(<{}<>([{}])><>)}{}<>
}{}               #|
>)
{(<{}(((((()()()()())){}{})){}{})>)}{}  #If it was negative put a minus sign
Assistente de Trigo
fonte
7

R, 6 bytes

median

Not surprising that R, a statistical programming language, has this built-in.

rturnbull
fonte
4
R beating Jelly :D:D:D
JAD
5

MATL, 4 bytes

.5Xq

This finds the 0.5-quantile, which is the median.

Try it online!

Luis Mendo
fonte
I was just about to figure it out!
flawr
Ah no, I mean I was figuring out how to do it in MATL=) (But I had a 5 byte solution, so yeah...)
flawr
@flawr Post it then! It will surely be more interesting than mine
Luis Mendo
Nope, it was the same as yours just with an i in front :)
flawr
@flawr The same i that you suggested to make implicit? :-P
Luis Mendo
5

Pyth - 11 bytes

Finds the average of the middle item taken both backwards and forwards.

.O@R/lQ2_BS

Test Suite.

Maltysen
fonte
5

Octave, 38 bytes

@(x)mean(([1;1]*sort(x))(end/2+[0 1]))

This defines an anonymous function. Input is a row vector.

Try it online!

Explanation

            sort(x)                 % Sort input x, of length k
      [1;1]*                        % Matrix-multiply by column vector of two ones
                                    % This vertically concatenates the sort(x) with 
                                    % itself. In column-major order, this effectively 
                                    % repeats each entry of sort(x)
     (             )(end/2+[0 1])   % Select the entry at position end/2 and the next.
                                    % Entries are indexed in column-major order. Since
                                    % the array has 2*k elements, this picks the k-th 
                                    % and (k+1)-th. Because entries were repeated, for
                                    % odd k this takes the original (k+1)/2-th entry
                                    % (1-based indexing) twice. For even k this takes
                                    % the original (k/2)-th and (k/2+1)-th entries
mean(                            )  % Mean of the two selected entries
Luis Mendo
fonte
1
Ugh... clever use of "bsxfun" and mean :-)
Stewie Griffin
5

JavaScript, 57 52 bytes

v=>(v.sort((a,b)=>a-b)[(x=v.length)>>1]+v[--x>>1])/2

Sort the array numerically. If the array is an even length, find the 2 middle numbers and average them. If the array is odd, find the middle number twice and divide by 2.

Grax32
fonte
1
I've found that Array.sort() doesn't work properly with decimals
TrojanByAccident
3
It does if you pass in a sorting function as I did. If you call Array.sort() with no parameters, it uses an alphabetic sort.
Grax32
Interesting. Didn't know that
TrojanByAccident
You can save a few bytes by using the return value of sort() directly and getting rid of the t variable: v=>(v.sort((a,b)=>a-b)[(x=v.length)>>1]+v[--x>>1])/2
Arnauld
1
Not that you should necessarily correct for this, but if x>=2**31, this would fail. >> is a sign-propagating right shift, meaning that when the number is interpreted as a 32 bit integer, if the msb is set, then it stays set, making the result negative for 2**32>x>=2**31. For x>=2**32, it just yields 0.
Patrick Roberts
5

Matlab/Octave, 6 bytes

A boring built-in:

median

Try it online!

flawr
fonte
I forget the rules for anonymous functions in MATLAB/Octave, should this be @median?
Giuseppe
@Giuseppe I don't know what the currently accepted way to score built-in functions is.
flawr
4

Mathematica, 6 bytes

Median

As soon as I figure out Mthmtca, I'm posting a solution in it.

Pavel
fonte
In Mthmtca 0.1/10.1.0.0, the code would have the bytes CBC8 (ËÈ). However, until I apply another patch, the notion of function-calling might not meet PPCG's standards.
LegionMammal978
4

Perl 6, 31 bytes

*.sort[{($/=$_/2),$/-.5}].sum/2

Try it

Expanded:

*\     # WhateverCode lambda ( this is the parameter )

.sort\ # sort it

[{     # index into the sorted list using a code ref to calculate the positions

  (
    $/ = $_ / 2 # the count of elements divided by 2 stored in 「$/」
  ),            # that was the first index

  $/ - .5       # subtract 1/2 to get the second index

                # indexing operations round down to nearest Int
                # so both are effectively the same index if given
                # an odd length array

}]\

.sum / 2        # get the average of the two values
Brad Gilbert b2gills
fonte
1
24 bytes
Jo King
4

APL (Dyalog Unicode), 14 bytes

≢⊃2+/2/⊂∘⍋⌷÷∘2

Try it online!

This is a train. The original dfn was {(2+/2/⍵[⍋⍵])[≢⍵]÷2}.

The train is structured as follows

┌─┼───┐
  ┌─┼───┐
    2 / ┌─┼───┐
    ┌─┘ 2 / ┌─┼─┐
    +         
           ┌┴┐ ┌┴┐
             ÷ 2

denotes the right argument.

index

  • ⊂∘⍋ the indices which indexed into results in being sorted

  • ÷∘2 into divided by 2

2/ replicate this twice, so 1 5 7 8 becomes 1 1 5 5 7 7 8 8

2+/ take the pairwise sum, this becomes (1+1)(1+5)(5+5)(5+7)(7+7)(7+8)(8+8)

from this pick

  • element with index equal to the length of

Previous solutions

{.5×+/(⍵[⍋⍵])[(⌈,⌊).5×1+≢⍵]}
{+/(2/⍵[⍋⍵]÷2)[0 1+≢⍵]}
{+/¯2↑(1-≢⍵)↓2/⍵[⍋⍵]÷2}
{(2+/2/⍵[⍋⍵])[≢⍵]÷2}
{(≢⍵)⊃2+/2/⍵[⍋⍵]÷2}
≢⊃2+/2/2÷⍨⊂∘⍋⌷⊢
≢⊃2+/2/⊂∘⍋⌷÷∘2
Kritixi Lithos
fonte
3

Common Lisp, 89

(lambda(s &aux(m(1-(length s)))(s(sort s'<)))(/(+(nth(floor m 2)s)(nth(ceiling m 2)s))2))

I compute the mean of elements at position (floor middle) and (ceiling middle), where middle is the zero-based index for the middle element of the sorted list. It is possible for middle to be a whole number, like 1 for an input list of size 3 such as (10 20 30), or a fraction for lists with an even numbers of elements, like 3/2 for (10 20 30 40). In both cases, we compute the expected median value.

(lambda (list &aux
             (m (1-(length list)))
             (list (sort list #'<)))
  (/ (+ (nth (floor m 2) list)
        (nth (ceiling m 2) list))
     2))
coredump
fonte
3

Vim, 62 bytes

I originally did this in V using only text manipulation until the end, but got frustrated with handling [X] and [X,Y], so here's the easy version. They're about the same length.

c$:let m=sort(")[(len(")-1)/2:len(")/2]
=(m[0]+m[-1])/2.0

Try it online!

Unprintables:

c$^O:let m=sort(^R")[(len(^R")-1)/2:len(^R")/2]
^R=(m[0]+m[-1])/2.0

Honorable mention:

  • ^O takes you out of insert mode for one command (the let command).
  • ^R" inserts the text that was yanked (in this case the list)
nmjcman101
fonte
3

TI-Basic, 2 bytes

median(Ans

Very straightforward.

Timtech
fonte
2
Ans is not an allowed I/O method.
Mego
1
@Mego your link and comment confuses me... according to the vote, it is allowed. Am I missing something?
Patrick Roberts
@PatrickRoberts There's actually some debate currently about the threshold for acceptability. Several users (myself included) have been following the rule that a method needs at least +5 and at least twice as many upvotes as downvotes, which was the rule originally stated in that post (it's been removed since), and is the rule followed for standard loopholes.
Mego
Whoever removed my comment twice from my own post is annoying. Since there's no clearly accepted rule on acceptability, I don't see the problem here. You can see my answers on SO for how this is used as arguments to a program.
Timtech
@Mego +38 is more than twice -18
Timtech
3

C#, 126 bytes

using System.Linq;float m(float[] a){var x=a.Length;return a.OrderBy(g=>g).Skip(x/2-(x%2==0?1:0)).Take(x%2==0?2:1).Average();}

Pretty straightforward, here with LINQ to order the values, skip half the list, take one or two values depending on even/odd and average them.

Jens
fonte
You need to include using System.Linq; into your byte count, however you can cancel this out by making some changes. Compile to a Func<float[], float> and assign the value of the modulo to a variable for 106 bytes: using System.Linq;a=>{int x=a.Length,m=x%2<1?1:0;return a.OrderBy(g=>g).Skip(x/2-m).Take(++m).Average();};
TheLethalCoder
@TheLethalCoder I'm never quite sure what constitutes a complete program. You are right about the using. Concatenating the declarations of the modulus with the length is also a good idea. I experimented around a bit with that but couldn't get it to be shorter than putting it twice in there. I would venture to say that your optimizations are worth an answer by itself, as they are quite substantial and I would not have come up with them.
Jens
The challenge doesn't state that you need a full program so an anonymous method is fine. Beyond that I only stated some common golfing tips so no need for me to add an answer just golf your own!
TheLethalCoder
3

C++ 112 Bytes

Thanks to @original.legin for helping me save bytes.

#include<vector>
#include<algorithm>
float a(float*b,int s){std::sort(b,b+s);return(b[s/2-(s&1^1)]+b[s/2])/2;}

Usage:

    int main()
    {
        int n = 4;
        float e[4] = {1,4,3,2};
        std::cout<<a(e,n); /// Prints 2.5

        n = 9;
        float e1[9] = {1,2,3,4,5,6,7,8,9};
        std::cout<<a(e1,n); /// Prints 5

        n = 13;
        float e2[13] = {1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,1.5,-5,100000,1.3,1.4};
        std::cout<<a(e2,n); /// Prints 1.5

        return 0;
    }
Wade Tyler
fonte
1
You could use float instead of double to save two bytes. Also, on GCC, you can use #import<vector> and #import<algorithm> instead of #include. (Note that you don't need the space after either the #include or #import)
Steadybox
@Steadybox I didn't count the two includes in the score. Should I? Also, I mainly use Clang so I don't know much about GCC but thanks.
Wade Tyler
Yes, the includes should be included in the byte count if the code doesn't compile without them.
Steadybox
3

J, 16 14 bytes

2%~#{2#/:~+\:~

Try it online!

In addition to BMO's array duplication trick, I found that we can add the whole array sorted in two directions. Then I realized that the two steps can be reversed, i.e. add the two arrays, then duplicate them and take the nth element.

How it works

2%~#{2#/:~+\:~
                Input: array of length n
       /:~      Sort ascending
           \:~  Sort descending
          +     Add the two element-wise
     2#         Duplicate each element
   #{           Take n-th element
2%~             Halve

Previous answers

J with stats addon, 18 bytes

load'stats'
median

Try it online!

Library function FTW.

median's implementation looks like this:

J, 31 bytes

-:@(+/)@((<.,>.)@(-:@<:@#){/:~)

Try it online!

How it works

-:@(+/)@((<.,>.)@(-:@<:@#){/:~)
         (<.,>.)@(-:@<:@#)       Find center indices:
                  -:@<:@#          Compute half of given array's length - 1
          <.,>.                    Form 2-element array of its floor and ceiling
                          {/:~   Extract elements at those indices from sorted array
-:@(+/)                          Sum and half

A bit of golfing gives this:

J, 28 bytes

2%~[:+/(<.,>.)@(-:@<:@#){/:~

Try it online!

Bubbler
fonte
1
Nicely done, the J port of my APL answer would be #{0,2+/\2#-:/:] at a close 15 bytes (man I miss ⎕io).
Kritixi Lithos
2

J, 19 bytes

<.@-:@#{(/:-:@+\:)~

Explanation:

        (        )~   apply monadic argument twice to dyadic function 
         /:           /:~ = sort the list upwards
               \:     \:~ = sort the list downwards
           -:@+       half of sum of both lists, element-wise
<.@-:@#               floor of half of length of list
       {              get that element from the list of sums
marinus
fonte
You can save a byte by removing the parentheses and applying ~ directly to each <.@-:@#{/:~-:@+\:~
miles
2

JavaScript, 273 Bytes

function m(l){a=(function(){i=l;o=[];while(i.length){p1=i[0];p2=0;for(a=0;a<i.length;a++)if(i[a]<p1){p1=i[a];p2=a}o.push(p1);i[p2]=i[i.length-1];i.pop()}return o})();return a.length%2==1?l[Math.round(l.length/2)-1]:(l[Math.round(l.length/2)-1]+l[Math.round(l.length/2)])/2}
TrojanByAccident
fonte
2

Java 7, 99 bytes

Golfed:

float m(Float[]a){java.util.Arrays.sort(a);int l=a.length;return l%2>0?a[l/2]:(a[l/2-1]+a[l/2])/2;}

Ungolfed:

float m(Float[] a)
{
    java.util.Arrays.sort(a);
    int l = a.length;
    return l % 2 > 0 ? a[l / 2] : (a[l / 2 - 1] + a[l / 2]) / 2;
}

Try it online

peech
fonte
I'm a bit disappointed even Java 7 has a short enough sorting syntax that en.wikipedia.org/wiki/… is suboptimal
JollyJoker
Dont you need to count the import for java.util.Arrays?
FlipTack
Whoops, thank you for noticiting. :)
peech
Hello from the future! You can save 14 bytes by using integer division truncation to handle length parity. See my Java 8 answer.
Jakob
2

Pari/GP - 37 39 Bytes

Let a be a rowvector containing the values.

b=vecsort(a);n=#b+1;(b[n\2]+b[n-n\2])/2  \\ 39 byte              

n=1+#b=vecsort(a);(b[n\2]+b[n-n\2])/2    \\ obfuscated but only 37 byte

Since Pari/GP is interactive, no additional command is needed to display the result.


For the "try-it-online" link a line before and after is added. To get printed, the median-result in stored in variable w

a=vector(8,r,random(999))           
n=1+#b=vecsort(a);w=(b[n\2]+b[n-n\2])/2      
print(a);print(b);print(w)       

Try it online!

Gottfried Helms
fonte
2

Japt, 20 bytes

n gV=0|½*Ul)+Ug~V)/2

Test it online! Japt really lacks any built-ins necessary to create a really short answer for this challenge...

Explanation

n gV=0|½*Ul)+Ug~V)/2  // Implicit: U = input list
n                     // Sort U.
   V=0|½*Ul)          // Set variable V to floor(U.length / 2).
  g                   // Get the item at index V in U.
            +Ug~V     // Add to that the item at index -V - 1 in U.
                 )/2  // Divide by 2 to give the median.
                      // Implicit: output result of last expression
ETHproductions
fonte
2

Java 8, 71 bytes

Parity is fun! Here's a lambda from double[] to Double.

l->{java.util.Arrays.sort(l);int s=l.length;return(l[s/2]+l[--s/2])/2;}

Nothing too complex going on here. The array gets sorted, and then I take the mean of two numbers from the array. There are two cases:

  • If the length is even, then the first number is taken from just ahead of the middle of the array, and the second number is taken from the position before that by integer division. The mean of these numbers is the median of the input.
  • If the length is odd, s and s-1 both divide to the index of the middle element. The number is added to itself and the result divided by two, yielding the original value.

Try It Online

Jakob
fonte
2

SmileBASIC, 45 bytes

DEF M A
L=LEN(A)/2SORT A?(A[L-.5]+A[L])/2
END

Gets the average of the elements at floor(length/2) and floor(length/2-0.5) Very simple, but I was able to save 1 byte by moving things around:

DEF M A
SORT A    <- extra line break
L=LEN(A)/2?(A[L-.5]+A[L])/2
END
12Me21
fonte
2

Husk, 10 bytes

½ΣF~e→←½OD

Try it online!

Explanation

This function uses that the median of [a1aN] is the same as the median of [a1a1aNaN] which avoids the ugly distinction of odd-/even-length lists.

½ΣF~e→←½OD  -- example input: [2,3,4,1]
         D  -- duplicate: [2,3,4,1,2,3,4,1]
        O   -- sort: [1,1,2,2,3,3,4,4]
       ½    -- halve: [[1,1,2,2],[3,3,4,4]]
  F         -- fold the following
   ~        -- | compose the arguments ..
     →      -- | | last element: 2
      ←     -- | | first element: 3
    e       -- | .. and create list: [2,3]
            -- : [2,3]
 Σ          -- sum: 5
½           -- halve: 5/2

Unfortunately ½ for lists has the type [a] -> [[a]] and not [a] -> ([a],[a]) which doesn't allow F~+→← since foldl1 needs a function of type a -> a -> a as first argument, forcing me to use e.

ბიმო
fonte
2

R without using the median builtin, 51 bytes

function(x,n=sum(x|1)+1)mean(sort(x)[n/2+0:1*n%%2])

Try it online!

J.Doe
fonte
2
function(x)mean(x,.5)
ngm
2

GolfScript, 27 25 20 17 bytes

~..+$\,(>2<~+"/2"

Takes input as an array of integers on stdin. Outputs as an unreduced fraction. Try it online!

Explanation

The median of the array, as BMO's Husk answer explains, is equal to the median of an array twice as long where each element is repeated twice. So we concatenate the array to itself, sort, and take the mean of the middle two elements. If the length of the original array is l, the middle two elements of the doubled array are at indices l1 and l.

~                  Evaluate input (converting string -> array)
 ..                Duplicate twice
   +               Concatenate two of the copies
    $              Sort the doubled array
     \,            Swap with the non-doubled array and get its length: l
       (           Decrement: l-1
        >          Array slice: all elements at index (l-1) and greater
         2<        Array slice: first two elements (originally at indices l-1 and l)
           ~       Dump array elements to stack
            +      Add
             "/2"  Push that string
                   Output all items on stack without separator

The output will be something like 10/2.

DLosc
fonte