Función Minmod más corta

24

La función minmod es una variante del min familiar , que aparece en esquemas de alta resolución con limitación de pendiente para ecuaciones diferenciales parciales. Dadas una serie de pendientes, selecciona la pendiente más plana, mientras se ocupa de los signos relativos entre las pendientes.

La función toma un número arbitrario de parámetros. Entonces minmod (x 1 , x 2 , ..., x n ) se define como:

  • min (x 1 , x 2 , ..., x n ) , si todo x i es estrictamente positivo
  • max (x 1 , x 2 , ..., x n ) , si todo x i es estrictamente negativo
  • 0 , de lo contrario.

Solo consideraremos entradas enteras, porque eso realmente no afecta la implementación y debería ser más inclusivo para algunos lenguajes (esotéricos).

Escriba un programa o función, que tome n enteros con signo (para n> 0 ) a través de STDIN, ARGV o argumento de función (puede usar una matriz si es más conveniente que una función variable), y devuelve o imprime (a STDOUT) el resultado de minmod (a, b) .

No debe utilizar incorporada min o max funciones (y, obviamente, hay una función de MINMOD o bien, si en realidad se puede encontrar que). Además, no debe usar ninguna función de clasificación incorporada, excepto para ordenar un pequeño número fijo de elementos (menos de 5).

Si su idioma no tiene tipos con signo, puede usar un tipo sin signo e interpretarlo como complemento de dos. Por ejemplo, si su idioma solo usa bytes sin firmar, puede usar 255para reemplazar -1y 128reemplazar -128, etc.

Este es el código de golf, por lo que gana la respuesta más corta (en bytes).

Casos de prueba

Input          Output

2              2
-3             -3
0              0
3 -5           0
2 4 1          1
0 1 2          0
-1 1 2         0
-4 -2 -3 -2    -2
-5 0 -1        0
1 0 -1         0

Tablas de clasificación

El siguiente fragmento de pila genera una tabla de clasificación regular y una descripción general de los ganadores por idioma. Entonces, incluso si su idioma de elección no le permite ganar el desafío completo, ¿por qué no tratar de obtener un lugar en la segunda lista?

Para asegurarse de que su respuesta se muestre, comience con un título, usando la siguiente plantilla de Markdown:

# Language Name, N bytes

¿Dónde Nestá el tamaño de su envío? Si mejora su puntaje, puede mantener los puntajes antiguos en el título, tachándolos. Por ejemplo:

# Ruby, <s>104</s> <s>101</s> 96 bytes

Martin Ender
fuente
1
Tal vez agregue una columna para cuántas respuestas hay en cada idioma
orgulloso Haskeller el
1
@proudhaskeller Hmm, me gusta que las dos tablas quepan actualmente una al lado de la otra sin tener que abrir el fragmento de pantalla completa, creo que sería un poco abarrotado si agregara otra columna. Si tu comentario recibe muchos más votos positivos que los míos, veré qué puedo hacer. ;)
Martin Ender
1
@Optimizer Decidí que la versión anterior de las reglas estaba haciendo más daño a la creatividad de las respuestas de las personas de lo que pretendía. Además, iba a otorgar una recompensa por la respuesta que conducía antes del cambio de la regla de todos modos, así que tampoco creo que se haga ningún daño en términos de representación. (Sí, estoy de acuerdo en que los cambios en las reglas no son una buena idea, pero pensé que valdría la pena en este caso)
Martin Ender
1
@ MartinBüttner: ahora no veo ninguna creatividad en las respuestas más recientes. Todo se ha reducido a reducir a un minmod por pares. La creatividad estaba en las respuestas de xnor o en el enfoque de Mig en el que influyen muchas otras respuestas.
Optimizador
2
@Optimizer, no siempre es posible saber si una nueva respuesta es exactamente tan creativa como la anterior, o si es un puerto sin imaginación.
Peter Taylor

Respuestas:

13

GolfScript, 10 9 bytes

~{0]$1=}*

Asume la entrada de stdin en el formato [-4 -2 -3 -2]

Esto utiliza la función de ordenamiento incorporada $, pero cada vez que se invoca está en una matriz de 3 elementos, lo cual está permitido.

Demostración en línea

Peter Taylor
fuente
Genial, nuestras respuestas están separadas por menos de 1 segundo, lo que significa que mi respuesta solía ser la más corta. ;)
Timtech
1
+1, esto es mucho más corto e inteligente que mi solución. (Ps. En caso de que alguien lo dude, sí, esta solución es correcta y es bastante fácil de probar por inducción. Lo que hace el código de Peter es calcular repetidamente la mediana del valor minmod anterior, el siguiente valor de entrada y cero; un examen de los posibles casos muestran que esto realmente produce el nuevo valor minmod.)
Ilmari Karonen
Qué ... bueno, siempre hay
MUCHAS
24

Mathematica, 19 bytes

Median[#~Riffle~0]&

Código y golf gracias a Martin Büttner.

Esta es una función pura sin nombre que toma una lista de enteros como entrada. Invocarlo como

Median[#~Riffle~0]&[{-2, -3, -2, -4}]

o similarmente guardado en variable.

El código primero rifla un cero entre cada dos elementos de la lista de entrada, que inserta n-1ceros entren elementos. Luego, se necesita la mediana para producir la respuesta.

Esto proporciona min-mod porque maneja cada caso:

  1. Todos los números son positivos, en cuyo caso los ceros están por debajo de ellos y la mediana es el número positivo más bajo.

  2. Todos los números son negativos, en cuyo caso los ceros están por encima de ellos y la mediana es el número menos negativo.

  3. Hay un número positivo y un número negativo, por lo que el elemento del medio es un cero.

Si Mathematica implementa su mediana usando el algoritmo de selección de tiempo lineal , entonces esto también es O (n).

xnor
fuente
11

Haskell, 62 61 39 38 37 bytes

f s=last[x|x<-0:s,and[x*x<=x*y|y<-s]]

el uso de un poco de magia comparación tomada de @ Zgarb de respuesta *, a saber, x*x<=x*y.

x*x<=x*yes cierto solo cuando xy ytiene el mismo signo y yel valor absoluto es mayor. en cuenta que cuando xes 0que siempre es cierto.

determinamos que xes el resultado si y sólo si está contenido en s, y que para todos yen s xcuenta el mismo signo que yy es más pequeño en valor absoluto. Si ningún valor en ssatisface esta definición, entonces 0es el resultado.

fluego funciona buscando sun elemento para satisfacer esto, y lo usa 0por defecto.

* aunque él no lo usó por las razones por las que lo estoy usando, y de hecho ya lo ha eliminado

orgulloso Haskeller
fuente
Es raro que Haskell sea tan golfable (e, irónicamente, aún legible). Quiéralo.
Isiah Meadows
10

JavaScript (ES6), 39 bytes

a=>a.reduce((p,c)=>p*c>0?p*p>c*c?c:p:0)
Michael M.
fuente
1
Me gusta esto. Buen uso de ES6.
Qix
6

Pitón 2, 53

lambda l:reduce(lambda a,b:sorted([a,b,0])[1],l,l[0])

La idea es utilizar reducepara convertir el buscador min-mod de dos entradas en nuno de entrada. Se me ocurrió independientemente de las otras respuestas que lo usan. Solo Python 2 es compatible reduce.

La solución de dos entradas simplemente encuentra la mediana de los dos números y cero. Vea mi respuesta de Mathematica para una forma más directa de usar la mediana.

Menos golfizado:

def f(l):
 A=l[0]
 for x in l:A=sorted([a,b,0])[1]
 return A

Una amalgama hipotético de Python 2 y Python 3 sería un carácter más corto, con la asignación estrellado de Python 3 y input()y printde Python 2.

#Not real code!
A,*l=input()
for x in l:A=sorted([A,x,0])[1]
print A

Código antiguo, sin ordenar:

lambda l:reduce(lambda a,b:[a,b][a*a>b*b]*(a*b>0),l,l[0])
xnor
fuente
Hm, sí, noté ese efecto secundario mientras tanto, pero siento que es demasiado tarde para solucionarlo ahora. Sin Medianembargo, Mathematica tiene una función incorporada .
Martin Ender
Su último enfoque ahora también es válido.
Martin Ender
6

Maravilloso, 210 bytes

@0
00
]]\\&002
/\..//&0@0
00..02
MMMMMM//\\
:M
}0}1}0}1}0}1}0}2..}2
^7^7||||&0&1&4<3&0=2{>
EqalLteq{0{<{<<2&1--
&2..&3..}100..&2\/{>
>0&6=0&4&5&6..\/
&3..&5\/{<{0
\/..\/
:|
}000}0
&0Subt
{0&1
}0{0
^7
=0&1
&0
\/

Hay tres tableros utilizados aquí.

El |tablero ( Aben la versión legible) toma el valor absoluto de una canica (ya sea devolviendo la canica pasada o cero menos la canica pasada, ya que toda la aritmética en Marbelous no está firmada).

El Mtablero ( Minabsen la versión legible) encuentra y emite a la izquierda la primera o segunda canica pasada (la que tenga un valor absoluto más pequeño), y saliendo si se pasa una canica firmada diferente.

El Mtablero también libera la canica que sostiene hacia abajo en lugar de hacia la izquierda una vez que se obtiene el último personaje de STDIN.

El Mtablero se usa en el tablero principal para almacenar el minmod de todos los valores marcados en cualquier momento dado, ya que libera el valor que se guardará hacia la izquierda, que luego se desvía de nuevo.

Los cubos de basura ( \/) solo se colocaron bajo sincronizadores que, de lo contrario, se imprimirían en STDIN.

Entrada / Salida usa STDIN / STDOUT. Ambos tratan con valores de 8 bits (si desea pasar + 0x30 y + 0x38, colóquelo 08en STDIN).

Se requieren bibliotecas y tableros cilíndricos. Se recomienda ver la salida como números decimales (tenga en cuenta que esto muestra el valor sin signo del resultado minmod).

Pruébalo aquí.

Nota: Para una entrada / salida más amigable para los humanos, agregue Dpdebajo de la última línea de la placa principal (antes :M), reemplace ]]con Rdy agregue lo siguiente en la parte inferior:

:Rd
}0}0}0
]]]]]]{>
-O-O-O
-O-O-O
*A
Plus
\\*A
..Plus
..{0
:*A
}0}0
<<<<
<<
<<
Plus
{0

Esto simplemente cambia la salida a 3 dígitos decimales. Del mismo modo, la entrada con estos cambios requiere una lista separada por espacios de 3 dígitos decimales por número.

Versión legible:

Imagen del tablero

es1024
fuente
5

Haskell, 83 40 39 bytes

Probablemente esta no sea la solución Haskell más corta posible (y ciertamente no superará a las demás aquí), pero es un comienzo. EDITAR: ¡ Ahora más del 50% más corto! EDIT2: Un byte menos ...

a#b|a*b<0=0|a*a<b*b=a|1<2=b
m=foldr1(#)

Esto es solo un pliegue directo (o reducido, como lo llaman algunos idiomas) por el operador binario #, que calcula la mediana de a, by 0. Aunque las reglas ahora me permitirían ordenar listas pequeñas, esto requiere una importación en Haskell y da como resultado un recuento de bytes más alto ( 49 bytes, pero 31 sin la importación):

import Data.List
a#b=sort[a,b,0]!!1
m=foldr1(#)
Zgarb
fuente
\a-> (signum a,a)es lo mismo que signum>>=(,)usar la función monad instance. (vea mi publicación en "consejos para jugar al golf en Haskell")
Haskeller orgulloso el
Gracias por el consejo, pero ahora es discutible. :)
Zgarb
@ Zgarb Ah, está bien.
Optimizador
5

TIS-100, 696 526 bytes

@1
MOV UP ACC
SAV
ADD 999
JEZ A
SWP
MOV 1 ANY
MOV ACC ANY
JRO -7
A:MOV 12 ANY
@5
S:JRO UP
MOV UP ACC
JLZ A
JEZ B
MOV 1 DOWN
JMP B
A:MOV 7 DOWN
NEG
B:MOV 1 RIGHT
MOV ACC RIGHT
MOV ACC RIGHT
JMP S
MOV 14 DOWN
MOV 9 RIGHT
@6
MOV 999 ACC
L:JRO LEFT
SAV
SUB ANY
JGZ A
MOV ANY NIL
SWP
JMP L
A:MOV ANY ACC
JMP L
MOV ACC ANY
@9
S:JRO UP
JEZ A
SUB 1
JEZ A
JMP X
A:MOV 1 ACC
JMP S
JEZ B
SUB 2
JEZ B
X:MOV 6 ACC
JMP S
B:MOV 2 ACC
JMP S
MOV ACC ANY
@10
MOV LEFT ACC
ADD 1
JRO ACC
JRO 6
MOV UP ANY
MOV UP ACC
NEG
MOV ACC ANY
!NOP
MOV 0 ANY

Espera que la secuencia sea terminada por -999. TIS-100 es más nuevo que esta pregunta, pero no es que eso importe aquí de todos modos.

El nodo 9 realiza un seguimiento de si todos somos positivos, todos negativos o mixtos. Los nodos 5 y 6 trabajan para encontrar el mínimo del valor absoluto de todos los números de entrada. El nodo 10 luego selecciona el mínimo, el mínimo negado o 0 dependiendo del estado del nodo 9.

ingrese la descripción de la imagen aquí

Sp3000
fuente
He implementado un emulador TIS para TIO, ¡así que ahora puedes probarlo en línea!
Phlarx
4

CJam, 20 bytes (o 10 bytes)

q~{]__~z\z<=\~*0>*}*

Usando el enfoque de @ xnor, reduzca el cálculo de minmod de 2 números a la vez desde la matriz.

Esto hubiera sido 19 bytes si hubiera :zfuncionado


Usando la nueva regla de usar ordenaciones en matrices cortas:

q~{0]$1=}*

que es exactamente equivalente a la respuesta de @ Peter


Respuesta anterior de 26 bytes:

q~_{g}%_|:+\(z\{za+_~>=}/*

Esto se puede jugar más golf ...

La entrada (a través de STDIN) es la matriz de enteros como:

[-4 -2 -3 -2]

y la salida es el minmod de la matriz de entrada

Pruébalo aquí

Si solamente :gy :ztrabajado, esto habría sido 4 bytes más corto.

Optimizador
fuente
25 Bytes: q~_{g}%_|:+\{z\za+_~>=}**.
jimmy23013
Falla para una sola matriz int. También lo intenté :)
Optimizer
Aunque hay una solución de 26 bytes allí. Gracias por eso :)
Optimizer
4

Java, 84 bytes

Esto es Java en todo su esplendor. Supera a GolfScript en un factor ligeramente superior al 900%.

int f(int[]a){int b=a[0],c;for(int d:a)b=(c=d<0?-1:1)*b<0?0:d*c<b*c?d:b;return b;}

Envuelto en clase:

public class MinModGolfed{

    public static void main(String[] args){
        int[] numbers = new int[args.length];
        for (int i = 0; i < args.length; i++){
            numbers[i] = Integer.parseInt(args[i]);
        }
        System.out.println(new MinModGolfed().f(numbers));
    }

    int f(int[]a){int b=a[0],c;for(int d:a)b=(c=d<0?-1:1)*b<0?0:d*c<b*c?d:b;return b;}

}

Ampliado con comentarios:

public class MinModExpandedGolfed{

    public static void main(String[] args){
        int[] numbers = new int[args.length];
        for (int i = 0; i < args.length; i++){
            numbers[i] = Integer.parseInt(args[i]);
        }
        System.out.println(new MinModExpandedGolfed().f(numbers));
    }

    int f(int[]a){                  //a is the input numbers
        int b=a[0],c;             //b is the best number found so far.
        for(int d:a)               //Iterate over a with current element as d.
            b=(c=d<0?-1:1)         //c is equal to the sign of d.
                    *b<0?
                        0:          //If b has opposite sign of d, b = 0.
                        d*c<b*c?d:b;//If the absolute value of d is less than b, b = d. 
        return b;
    }

}

Nota: Esto se puede mejorar con Java 8.

Nota: El esfuerzo para mejorar en Java 8 falló.

El numero uno
fuente
Todavía tengo mucho que aprender. +1.
Rodolfo Dias
4

J, 20 12 bytes

Función tomando la lista como argumento. Robado del Golfscript / CJam / lo que sea.

(1{0/:~@,,)/

El minmod de xy yes la mediana (ordenar /:~y tomar el medio 1{) de la lista de tres elementos 0,x,y. Reducir la lista ( plegable en lenguaje J) tomando este minmod entre elementos adyacentes.

En uso en el REPL. (J deletrea su signo negativo _).

   (1{0/:~@,,)/ _4 _2 _3 _2
_2
   f =: (1{0/:~@,,)/    NB. give it a name
   f 1 1 2
1
   f 0 1 2
0
   f _1 1 2
0

0:`<.`>.@.(*@]*0<*))/Basura vieja, antes de notar que se permiten tipos cortos: el minmod de xy yes 0 ( 0:) si 0 es mayor o igual que el producto de xy y, de lo contrario, es el min ( <.) o el max ( >.) entre xy ydependiendo del signo . Dobla esto sobre toda la lista.

Algoritmo de tiburón
fuente
4

TI-BASIC, 19 bytes

Asume la entrada en el formato {-2,4,3}.

Funciona de manera similar a la respuesta de xnor:

Input L₁              get user input into the L1 array
dim(L₁)2-1→dim(L₁     get the length of the array; multiply by 2 and subtract 1
                      make this the new length (new elements always default to 0)
median(L₁             calculate and return (since it's the last line) median of new array
Timtech
fuente
3
Una forma interesante de contar el tamaño del código ...
Ypnypn
Mi código, así como median(augment(Ans,0ΔList(Anssolo en ocho bytes, falla en las listas de dimensión uno. If variance(Ans:augment(Ans,0ΔList(Ans:median(AnsEs más largo que el tuyo. Si solo TI-BASIC
admitiera
Tienes razón. Parece que eso aumenta el tamaño de mi código de 12 a 15 bytes.
Timtech
Supongo que estas en lo correcto. +4 bytes allí.
Timtech
3

Python 2, 82 79 71 69 61 bytes

lambda l:reduce(lambda G,H:[H,G][(G>H)^(G>0)]*(G*H>0),l,l[0])

Esto se basa en mi respuesta pyth, que se inspiró en la respuesta de Mig .


Vieja respuesta:

l=input()
m=l[0]
k=1-2*(m<0)
for i in l:m=[m,i][m>i*k]
print(k*m>0)*m

Esta es una respuesta muy larga. Siento que tener 2 variables es un desperdicio ...? Yo tenía razón...? ish? ;pags

FryAmTheEggman
fuente
3

KDB / Q, 43 caracteres para la definición del cuerpo de la función

Gracias a las grandes ideas de publicaciones anteriores:

f:{$[all 1_0<(*':)x;{$[<[x*x;y*y];x;y]}/[x];0]}

Ingrese un número único usando enlist

f[enlist 2]
f[enlist 0]
f[enlist -2]
f[2 4 1]
f[0 1 2]
f[1 0 2]
f[-1 1 2]
f[-4 -2 -3 -2]
f[-5 0 -1]
f[-5 -0 -1]
f[1 0 -1]

Estoy seguro de que algunos gurús de Q pueden tener otros más cortos.

space889
fuente
¿Quizás algo así {asc[0,x,y]1}/?
algorithmshark
3

Pyth, 25 22 20 12

uhtS[0GH)QhQ

Probablemente no novela, sino original: P


Pre-clasificación permitida

u*?Gx>GH>G0H>*GHZQhQ

Pyth

Pruébalo en línea.

La idea de usar reducey declaraciones ternarias fue robada descaradamente de la respuesta de Mig , pero no tengo idea de si estos algoritmos son incluso similares, ya que no puedo leer las declaraciones ternarias.

Explicación:

Q=eval(input)         : implicit
u                QhQ  : print reduce(lambda G,H: ..., Q, Q[0])
 *          >*GHZ     : ... * (G*H>0)
  ?G       H          : G if ... else H
    x>GH>G0           : G>H xor G>0
FryAmTheEggman
fuente
No hay necesidad de tQ. Qtambién funcionará
Optimizer
¡Muy bien! También creo que puedo eliminar uno de los ?por un *...
FryAmTheEggman
3

C #, 101 bytes

Mi primer intento en el código de golf y en un lenguaje hostil de golf bonito. Basado en reduce ( Aggregateen LINQ) y muy similar a la respuesta de JavaScript de Mig . Se puede ejecutar como (new System.Linq.M()).m(new[] {1, 2, 3}). Pasa todos los casos de prueba, pero no maneja matrices de entrada vacías.

namespace System.Linq{class M{public int m(int[]i){return i.Aggregate((a,b)=>a*b>0?a*a<b*b?a:b:0);}}}
Jacob Bundgaard
fuente
1
No hay necesidad de manejar entradas vacías, ya que ni siquiera definí la función para ese caso.
Martin Ender
3

J, 12 bytes

   (=&**>&|{,)/

La función reduce la lista (llamada plegable ( /) en J) con la expresión:

(signum(x) == signum(y)) * [x,y][abs(x)>abs(y)] dónde

[x,y][abs(x)>abs(y)]es ysi abs(x) > abs(y)más x.

Ejemplo:

   (=&**>&|{,)/ 5 2 6
2

Pruébelo en línea aquí.

randomra
fuente
2

Lenguaje Game Maker, 489 bytes

Sobre Game Maker Language

Agita la matriz (se agregan ceros) y devuelve la mediana (similar a mi otra respuesta)

i=0a=argument0
while(variable_local_array_get(a,i))i++
for(j=0;j++;j<i-1)a[j+i]=0var i,j,d,m=0d=ds_list_create()if variable_local_exists(a){if variable_local_array_get(a,0){for(i=0;i<32000;i++){if variable_local_array_get(a,i)=0break
ds_list_add(d,variable_local_array_get(a,i))}ds_list_sort(d,0)i=ds_list_find_value(d,ds_list_size(d) div 2)j=ds_list_find_value(d,(ds_list_size(d) div 2)-1)m=ds_list_find_value(ds,ds_list_size(d) mod 2)ds_list_destroy(d)}if m return (i+j)/2return i
break}
Timtech
fuente
@ MartinBüttner Las primeras 2.5 líneas realizan el riffle, y el resto encuentra la mediana. El 32000es el tamaño máximo de la matriz según lo limitado por el software.
Timtech
@ MartinBüttner Sí, dentro de la parte mediana, toda la lista no está ordenada.
Timtech
@ MartinBüttner se ordena cada iteración ... así que 3
Timtech
Ohhh ya veo. Ese código es sorprendentemente difícil de leer para un lenguaje tan prolijo. ^^
Martin Ender
@ MartinBüttner Es bastante bueno para jugar al golf (sintaxis muy flexible) pero no contiene muchas funciones integradas estándar ( está orientado al diseño del juego).
Timtech
2

Java, 353 304 124 bytes

Reúna el peor lenguaje para el golf de código con el peor golfista del mundo y obtendrá ...

int m(int[]a){int m=a[0];if(m<0)for(int i:a){m=(i>m)?i:m;m=(i>0)?0:m;}else for(int i:a){m=(i<m)?i:m;m=(i<0)?0:m;}return m;}}

Elimínelo y obtendrá:

int m(int[] a) {
    int m = a[0];
    if (m < 0) {
        for (int i : a) {
            m = (i > m) ? i : m;
            m = (i > 0) ? 0 : m;
        }
    } else {
        for (int i : a) {
            m = (i < m) ? i : m;
            m = (i < 0) ? 0 : m;
        }
    }
    return m;
}

Esta es una función (si no fuera bastante obvio) que recibe una serie de números y procesa sus valores, devolviendo el valor minmod.

También se incluye mi antiguo beneficio de una solución, que es un programa completo, como siempre.

class M{public static void main(String[]a){java.util.Scanner s=new java.util.Scanner(System.in);int n,m=0;try{m=s.nextInt();if(m<0)while(true){n=s.nextInt();m=(n>m)?n:m;m=(n>0)?0:m;}else while(true){n=s.nextInt();m=(n<m)?n:m;m=(n<0)?0:m;}}catch(java.util.InputMismatchException e){System.out.print(m);}}}

Elimínelo y obtendrá:

class M {

    public static void main(String[] a) {
        java.util.Scanner s = new java.util.Scanner(System.in);
        int n = 0, m = 0;
        try {
            m = s.nextInt();
            if (m < 0) {
                do {
                    n = s.nextInt();
                    m = (n > m) ? n : m;
                    m = (n > 0) ? 0 : m;
                } while (true);
            } else {
                do {
                    n = s.nextInt();
                    m = (n < m) ? n : m;
                    m = (n < 0) ? 0 : m;
                } while (true);
            }
        } catch (java.util.InputMismatchException e) {
            System.out.print(m);
        }
    }
}

Recibe números infinitos, se detiene cuando se ingresa un valor no numérico, presentando el valor Minmon.

Rodolfo Dias
fuente
Su código parece descartar el primer valor, por lo que dará respuestas incorrectas, por ejemplo 1 2 3. También parece pasar por alto que puede escribir una función que procesa sus argumentos en lugar de un programa que lee desde stdin.
Peter Taylor
@PeterTaylor Tontamente, mi primer instinto es siempre escribir un programa completo, incluso si se dice que puede ser una función. Sobre ese error, aparentemente no lo probé lo suficiente, ratas. Trataré de corregirlo ahora, y también haré una versión de solo función ...
Rodolfo Dias
2

R, 20 caracteres

R generalmente no es bueno para codegolf, pero lo uso para mi trabajo, así que quería probar. Antes de intentarlo, ¡no sabía que R está dispuesto a aceptar una sintaxis tan sucia! :-) 52 caracteres :

if((q=summary(x))[6]<0)q[6]else if(q[1]>0)q[1]else 0

Luego miré las otras respuestas que probé con el genial truco mediano de @ xnor, ¡que es genial!

median(c(x-x,x)[-1])
Tomás
fuente
¿Cómo funciona tu primera versión? ¿Qué summaryhacer? ¿Son q[1]y q[6]min y max, respectivamente? En ese caso, eso no es válido, porque no puede usar min / max incorporado.
Martin Ender
@ MartinBüttner básicamente proporciona un vector de cuantiles y una media. 1 y 6 son 0 y 1 cuantiles. No he usado la función min / max incorporada, según sus reglas.
Tomás
2

Python, 52

Todavía no pude evitar sentir que es malo tener dos lambdasegundos. Esta función toma una lista y luego devuelve una lista de un elemento que contiene el resultado.

f=lambda a:a[1:]and[sorted([a.pop(),0]+f(a))[1]]or a

Con suerte, no causará una gran cantidad de ofensas tener el resultado en una lista de un elemento.

Feersum
fuente
1

Matlab / Octave, 26

Esto es básicamente una traducción de la respuesta de Mathematica por xnor. Funciona agregando uno ceros menos que la longitud del vector de entrada. Tenga en cuenta que agregar uno más no funcionaría, ya que el resultado sería 0 todo el tiempo. Gracias a MartinBüttner por los -4 caracteres de esta solución =)

@(x)median([x,0*x(2:end)])
falla
fuente
@ MartinBüttner Tienes toda la razón. Ahora lo modifiqué: el programa solo agregará un cero menos que la entrada. De esta manera, se garantiza que siempre tengamos un número impar de elementos y la mediana se ocupa del resto.
flawr
o pop el último 0 de su solución anterior.
Optimizador
@ MartinBüttner Gracias, por supuesto, eso es mucho mejor. @ Optimizer ¿Cómo harías eso?
flawr
No tengo idea. Pensé que debía haber una manera de hacer saltar el último elemento, algo así @(x)median([0*x,x](2:end)). Aunque parece que son los mismos bytes que ahora.
Optimizador
@Optimizer Ya pensé que me perdí una característica importante de Matlab =) Es una lástima que la notación que sugirió no funcione, ¡sería realmente útil a veces!
flawr
1

Python, 72 60 bytes

Esta es la primera solución que pensé, y es bastante ingenua. La segunda mitad es básicamente un duplicado de la primera mitad del código, pero no estaba seguro de cómo reducirlo. Me pregunto si se puede acortar usando eval...

Editar: Cambiamos lambdas a comprensiones.

Pruébalos aquí

lambda l:min(l)*all(x>0for x in l)+max(l)*all(x<0for x in l)

Esto es solo 4 caracteres más, pero aún vale la pena mirarlo, usando el TIP de Sp3000 .

lambda l:eval("+m%s%s(l)*all(x%s0for x in l)"*2%tuple("ax<in>"))
mbomb007
fuente
1

Javascript, 63

a=>a.reduce((p,c)=>p<0?c<0?Math.max(p,c):0:c>0?Math.min(p,c):0)

Una versión más legible:

function (arr) {
    return arr.reduce(function (p, c) {
        if (p < 0) {
            if (c < 0) {
                return Math.max(p, c);
            } else {
                return 0;
            }
        } else {
            if (c > 0) {
                return Math.min(p, c);
            } else {
                return 0;
            }
        }
    });
}
Afonso Matos
fuente