Função Minmod mais curta

24

A função minmod é uma variante do familiar min , que aparece em esquemas de alta resolução com limitação de inclinação para equações diferenciais parciais. Dadas várias pistas, ela escolhe a inclinação mais plana, enquanto cuida dos sinais relativos entre as pistas.

A função aceita um número arbitrário de parâmetros. Então minmod (x 1 , x 2 , ..., x n ) é definido como:

  • min (x 1 , x 2 , ..., x n ) , se todos os x i forem estritamente positivos
  • max (x 1 , x 2 , ..., x n ) , se todos os x i forem estritamente negativos
  • 0 , caso contrário.

Consideraremos apenas entradas inteiras, porque isso realmente não afeta a implementação e deve ser mais inclusivo para algumas linguagens (esotéricas).

Escreva um programa ou função que receba n números inteiros assinados (para n> 0 ) via STDIN, ARGV ou argumento de função (você pode usar uma matriz se isso for mais conveniente que uma função variável) e retorne ou imprima (para STDOUT) o resultado de minmod (a, b) .

Você não deve usar funções mínimas ou máximas embutidas (e, obviamente, nenhum minmod embutido também, se é que consegue encontrar isso). Além disso, você não deve usar nenhuma função de classificação interna, exceto para classificar um pequeno número fixo de itens (menor que 5).

Se seu idioma não possui tipos assinados, você pode usar um tipo não assinado e interpretá- lo como complemento de dois. Por exemplo, se o idioma só usa sem assinatura bytes, você pode usar 255para substituir -1e 128para substituir -128, etc.

Isso é código de golfe, então a resposta mais curta (em bytes) vence.

Casos de teste

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

Classificação

O seguinte snippet de pilha gera uma tabela de classificação regular e uma visão geral dos vencedores por idioma. Portanto, mesmo que seu idioma de escolha não permita que você vença todo o desafio, por que não tentar conquistar um lugar na segunda lista?

Para garantir que sua resposta seja exibida, inicie-a com um título, usando o seguinte modelo de remarcação:

# Language Name, N bytes

onde Nestá o tamanho do seu envio. Se você melhorar sua pontuação, poderá manter as pontuações antigas no título, identificando-as. Por exemplo:

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

Martin Ender
fonte
11
Talvez adicione uma coluna para quantas respostas existem em cada idioma
proud haskeller
11
@proudhaskeller Hmm, eu gosto que as duas tabelas se encaixem atualmente sem ter que abrir a tela inteira do trecho - acho que seria um pouco abarrotado se eu adicionasse outra coluna. Se o seu comentário for significativamente mais positivo do que o meu, verei o que posso fazer. ;)
Martin Ender
11
@Optimizer Decidi que a versão anterior das regras estava prejudicando mais a criatividade das respostas das pessoas do que eu pretendia. Além disso, eu concederia uma recompensa pela resposta que estava levando antes que a regra fosse alterada, de modo que não acho que nenhum dano em termos de representação seja causado. (Sim, eu concordo que as mudanças de regra não são uma boa idéia, mas achei que valeria a pena neste caso.)
Martin Ender
11
@ MartinBüttner - Não vejo criatividade nas respostas mais recentes agora. Tudo se resume a reduzir a um minmod par. A criatividade estava nas respostas de xnor ou na abordagem de Mig sobre a qual muitas outras respostas são influenciadas.
Optimizer
2
@Optimizer, nem sempre é possível saber se uma nova resposta é exatamente tão criativa quanto uma resposta mais antiga, à qual é semelhante ou se é uma porta sem imaginação.
Peter Taylor

Respostas:

13

GolfScript, 10 9 bytes

~{0]$1=}*

Assume a entrada de stdin no formato [-4 -2 -3 -2]

Isso usa a função de classificação interna $, mas toda vez que é chamada, ela está em uma matriz de 3 elementos, o que é permitido.

Demonstração online

Peter Taylor
fonte
Legal, nossas respostas têm menos de um segundo de diferença, o que significa que minha resposta costumava ser a mais curta. ;)
Timtech 2/14/14
11
+1, isso é muito mais curto e inteligente que minha solução. (Ps. Caso alguém duvide, sim, esta solução está correta e é bastante fácil de provar por indução. O que o código de Peter faz é calcular repetidamente a mediana do valor minmod anterior, o próximo valor de entrada e zero; um exame de os possíveis casos, mostra que este fato produz o novo valor minmod).
Ilmari Karonen
O que ... bem, há sempre muitas coisas para magra: O
TheBlastOne
24

Mathematica, 19 bytes

Median[#~Riffle~0]&

Código e golfe graças a Martin Büttner.

Esta é uma função pura sem nome que recebe uma lista de números inteiros como entrada. Invoque-o como

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

ou salvo da mesma forma na variável.

O código primeiro corrige um zero entre cada dois elementos da lista de entrada, que insere n-1zeros entre os nelementos. Em seguida, é necessária a mediana para produzir a resposta.

Isso fornece o min-mod porque ele lida com cada caso:

  1. Todos os números são positivos; nesse caso, os zeros estão abaixo deles e a mediana é o menor número positivo.

  2. Todos os números são negativos; nesse caso, os zeros estão acima deles e a mediana é o número menos negativo.

  3. Há um número positivo e um negativo e, portanto, o elemento do meio é um zero.

Se o Mathematica implementa sua mediana usando o algoritmo de seleção de tempo linear , então este também é O (n).

xnor
fonte
11

Haskell, 62 61 39 38 37 bytes

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

usando alguma mágica de comparação emprestada da resposta do @ Zgarb *, a saber x*x<=x*y,.

x*x<=x*yé verdadeiro somente quando xe ytem o mesmo sinal e yo valor absoluto de é maior. note que quando xé 0que é sempre verdade.

determinamos que xé o resultado se ele estiver contido se que, para todos y, s xtem o mesmo sinal ye é menor em valor absoluto. se nenhum valor ssatisfizer esta definição, então 0é o resultado.

fentão trabalha pesquisando sum elemento para satisfazer isso e usa 0como padrão.

* embora ele não o tenha usado pelas razões pelas quais eu estou usando, e ele já se livrou

orgulhoso haskeller
fonte
É raro Haskell ser tão jogável (e, ironicamente, ainda legível). Adoro.
Isiah Meadows
10

JavaScript (ES6), 39 bytes

a=>a.reduce((p,c)=>p*c>0?p*p>c*c?c:p:0)
Michael M.
fonte
11
Amo isso. Bom uso do ES6.
Qix
6

Python 2, 53

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

A idéia é usar reducepara transformar o localizador min-mod de duas entradas em um local de nentrada. Eu vim com ele independentemente das outras respostas que o usam. Somente o Python 2 suporta reduce.

A solução de duas entradas simplesmente encontra a mediana dos dois números e zero. Veja minha resposta do Mathematica para uma maneira mais direta de usar a mediana.

Menos golfe:

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

Um amálgama hipotético do Python 2 e Python 3 seria um caractere mais curto, com a atribuição estrelada do Python 3 input()e printdo Python 2.

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

Código antigo, sem classificação:

lambda l:reduce(lambda a,b:[a,b][a*a>b*b]*(a*b>0),l,l[0])
xnor
fonte
Hm, sim, notei esse efeito colateral enquanto isso, mas sinto que é tarde demais para consertá-lo agora. O Mathematica possui um recurso Medianinterno.
Martin Ender
Sua última abordagem agora também é válida.
Martin Ender
6

Marbelous, 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
\/

Existem três placas usadas aqui.

O |tabuleiro ( Abna versão legível) assume o valor absoluto de um mármore (retornando o mármore passado ou zero menos o mármore passado, pois toda a aritmética em Marbelous é sem sinal).

A Mplaca ( Minabsna versão legível) localiza e produz à esquerda o primeiro ou o segundo mármore passado (o que tiver um valor absoluto menor) e sair se outro mármore assinado for passado.

O Mtabuleiro também libera o mármore que segura para baixo, em vez de para a esquerda, quando o último personagem de STDIN é buscado.

A Mplaca é usada na placa principal para armazenar o minmod de todos os valores verificados a qualquer momento, pois libera o valor a ser salvo para a esquerda, que é desviado novamente.

Os caixotes do lixo ( \/) foram colocados apenas em sincronizadores que, de outra forma, seriam impressos em STDIN.

Entrada / Saída usa STDIN / STDOUT. Ambos lidam com valores de 8 bits (se você deseja passar + 0x30 e + 0x38, coloque 08em STDIN).

Bibliotecas e placas cilíndricas são necessárias. É recomendável visualizar a saída como números decimais (observe que isso exibe o valor não assinado do resultado minmod).

Teste aqui.

Nota: Para entradas / saídas mais amigáveis ​​ao ser humano, adicione Dpsob a última linha da placa principal (antes :M), substitua ]]por Rde adicione o seguinte na parte inferior:

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

Isso simplesmente altera a saída para 3 dígitos decimais. Da mesma forma, a entrada com essas alterações requer uma lista separada por espaços de 3 dígitos decimais por número.

Versão legível:

Imagem da placa

es1024
fonte
5

Haskell, 83 40 39 bytes

Esta provavelmente não é a solução mais curta possível da Haskell (e certamente não superará as outras aqui), mas é um começo. EDIT: Agora mais de 50% mais curto! EDIT2: um byte a menos ...

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

Este é apenas um simples dobrar (ou reduzir, como algumas linguagens chamam) pelo operador binário #, que calcula a mediana de a, be 0. Embora as regras agora me permitam classificar pequenas listas, isso requer uma importação no Haskell e resulta em uma contagem de bytes mais alta ( 49 bytes, mas 31 sem a importação):

import Data.List
a#b=sort[a,b,0]!!1
m=foldr1(#)
Zgarb
fonte
\a-> (signum a,a)é o mesmo que signum>>=(,)usar a função monad instance. (veja meu post em "dicas para jogar golfe em haskell")
proud haskeller
Obrigado pela dica, mas agora é discutível. :)
Zgarb
@Zgarb Ah, tudo bem.
Optimizer
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 a sequência seja finalizada por -999. O TIS-100 é mais recente que esta pergunta, mas não é como se aqui importasse de qualquer maneira.

O nó 9 controla se somos todos positivos, todos negativos ou mistos. Os nós 5 e 6 trabalham para encontrar o mínimo do valor absoluto de todos os números de entrada. O nó 10 então seleciona o mínimo, o mínimo negado ou 0, dependendo do estado do nó 9.

insira a descrição da imagem aqui

Sp3000
fonte
Eu implementei um emulador de TIS para TIO, então agora você pode experimentá-lo online!
Phlarx
4

CJam, 20 bytes (ou 10 bytes)

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

Usando a abordagem do @ xnor, reduza o cálculo do minmod de 2 números por vez a partir da matriz.

Isso teria sido 19 bytes se :zfuncionasse


Usando a nova regra de usar classificações em matrizes curtas:

q~{0]$1=}*

o que é exatamente equivalente à resposta de @ Peter


26 bytes anteriores anteriores:

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

Isso pode ser jogado ainda mais ...

Entrada (via STDIN) é a matriz inteira como:

[-4 -2 -3 -2]

e output é o minmod da matriz de entrada

Experimente aqui

Se apenas :ge :zfuncionasse, isso teria sido 4 bytes mais curto.

Optimizer
fonte
25 bytes: q~_{g}%_|:+\{z\za+_~>=}**.
precisa saber é o seguinte
Falha na matriz int única. Eu tentei também :)
Optimizer
Embora exista uma solução de 26 bytes. Obrigado por isso :)
Optimizer
4

Java, 84 bytes

Este é Java em toda a sua glória. Supera o GolfScript por um fator de pouco mais de 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;}

Embrulhado na aula:

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;}

}

Expandido com comentários:

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: Isso pode ser aprimorado usando o Java 8.

Nota: O esforço para melhorar no Java 8 falhou.

O número um
fonte
Ainda tenho muito a aprender. +1.
Rodolfo Dias
4

J, 20 12 bytes

Função que toma a lista como argumento. Roubado do Golfscript / CJam / tanto faz.

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

O minmod de xe yé a mediana (classifique /:~e fique no meio 1{) da lista de três itens 0,x,y. Reduza a lista ( dobrando na linguagem J), levando esse minmod entre elementos adjacentes.

Em uso no REPL. (J soletra seu sinal 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

Lixo antigo, antes que eu notei que tipos curtos são permitidos: 0:`<.`>.@.(*@]*0<*))/o minmod de xe yé 0 ( 0:) se 0 for maior ou igual ao produto de xe y, caso contrário, é o min ( <.) ou o máximo ( >.) entre xe ydependendo do sinal . Dobre isso sobre a lista inteira.

algoritmshark
fonte
4

TI-BASIC, 19 bytes

Pressupõe entrada no formato {-2,4,3}.

Funciona de maneira semelhante à resposta do 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
fonte
3
Maneira
Meu código, assim como median(augment(Ans,0ΔList(Anscom apenas oito bytes, falha nas listas da dimensão um. If variance(Ans:augment(Ans,0ΔList(Ans:median(Ansé mais longo que o seu. Se ao menos o TI-BASIC suportasse listas vazias ... #
21415
Você está certo. Parece que aumenta o tamanho do meu código de 12 a 15 bytes.
Timtech
Eu acho que você está certo. +4 bytes lá.
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])

Isso se baseia na minha resposta pyth, que foi inspirada na resposta de Mig .


Resposta antiga:

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 é uma resposta muito longa. Eu sinto que ter 2 variáveis ​​é um desperdício ...? Eu tinha razão...? ish? ; p

FryAmTheEggman
fonte
3

KDB / Q, 43 caracteres para definição do corpo da função

Graças a ótimas idéias de posts anteriores:

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

Digite um número único usando o alistamento

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]

Tenho certeza de que algum guru Q pode inventar outros mais curtos.

space889
fonte
Talvez algo parecido {asc[0,x,y]1}/?
algorithmshark
3

Pitão, 25 22 20 12

uhtS[0GH)QhQ

Provavelmente não é novidade, mas é original: P


Pré-classificação permitida

u*?Gx>GH>G0H>*GHZQhQ

Pyth

Experimente online.

A idéia de usar reducee declarações ternárias foi descaradamente roubada da resposta de Mig , mas não tenho idéia se esses algoritmos são de outra forma semelhantes, pois não consigo ler declarações ternárias.

Explicação:

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
fonte
Não há necessidade de tQ. Qtambém funcionará
Optimizer
Muito bem! Eu também acho que pode remover um dos ?para uma *...
FryAmTheEggman
3

C #, 101 bytes

Minha primeira tentativa no código de golfe e em uma linguagem bastante hostil ao golfe. Baseado em reduzir ( Aggregateem LINQ) e muito semelhante à resposta JavaScript de Mig . Pode ser executado como (new System.Linq.M()).m(new[] {1, 2, 3}). Passa em todos os casos de teste, mas não lida com matrizes de entrada vazias.

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
fonte
11
Não há necessidade de lidar com entradas vazias, pois nem sequer defini a função para esse caso.
Martin Ender
3

J, 12 bytes

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

A função reduz a lista (chamada dobrável ( /) em J) com a expressão:

(signum(x) == signum(y)) * [x,y][abs(x)>abs(y)] Onde

[x,y][abs(x)>abs(y)]é yse abs(x) > abs(y)mais x.

Exemplo:

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

Experimente online aqui.

randomra
fonte
2

Linguagem do Game Maker, 489 bytes

Sobre o idioma do Game Maker

Discreta a matriz (zeros são anexados) e retorna a mediana (semelhante à minha outra resposta)

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
fonte
@ MartinBüttner As primeiras 2,5 linhas executam o riffle, e o restante encontra a mediana. O 32000é o tamanho máximo da matriz, conforme limitado pelo software.
Timtech
@ MartinBüttner Sim, na parte mediana, a lista inteira não é classificada.
Timtech
@ MartinBüttner, ele é classificado a cada iteração ... so 3
Timtech 2/14/14
Ohhh eu vejo. Esse código é surpreendentemente difícil de ler para uma linguagem tão prolífica. ^^
Martin Ender
@ MartinBüttner É muito bom para jogar golfe (sintaxe muito simples), mas não contém muitas funções internas padrão ( é orientado para o design do jogo).
Timtech
2

Java, 353 304 124 bytes

Junte o pior idioma para o código de golfe ao pior jogador de golfe do mundo e ...

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;}}

Ungolf-lo e você terá:

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;
}

Essa é uma função (se não fosse óbvia) que recebe uma matriz de números e processa seus valores, retornando o valor minmod.

Meu velho benefício de solução também está incluído, que é um programa inteiro - como sempre.

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);}}}

Ungolf-lo e você terá:

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);
        }
    }
}

Recebe números infinitos, para quando um valor não numérico é inserido, apresentando o valor Minmon.

Rodolfo Dias
fonte
Seu código parece descartar o primeiro valor, portanto dará respostas incorretas para, por exemplo 1 2 3. Você também parece ignorar que pode escrever uma função que processa seus argumentos, em vez de um programa que lê stdin.
Peter Taylor
@ PeterTaylor Tolamente, meu primeiro instinto é sempre escrever um programa completo, mesmo que seja declarado que pode ser uma função. Sobre esse bug, aparentemente eu não testei o suficiente, ratos. Vai tentar corrigi-lo agora - e fazer uma versão somente função, bem ...
Rodolfo Dias
2

R, 20 caracteres

O R normalmente não é bom para o codegolf, mas eu o uso para o meu trabalho, então eu queria tentar. Antes de tentar, não sabia que R estava disposto a aceitar uma sintaxe tão suja! :-) 52 caracteres :

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

Depois procurei as outras respostas que experimentei o truque mediano genial do @ xnor, o que é ótimo!

median(c(x-x,x)[-1])
Tomas
fonte
Como sua primeira versão funciona? O que summaryfaz? São q[1]e q[6]min e max, respectivamente? Nesse caso, isso não é válido, porque você não pode usar o mínimo / máximo interno.
Martin Ender
@ MartinBüttner, fornece basicamente um vetor de quantis e uma média. 1 e 6 são quantis 0 e 1. Eu não usei a função min / max interna, de acordo com suas regras.
Tomas
2

Python, 52

Eu ainda não pude deixar de sentir que é ruim ter dois lambdas. Essa função recebe uma lista e, em seguida, retorna uma lista de um elemento que contém o resultado.

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

Felizmente, isso não fará com que uma quantidade enorme de ofensas tenha o resultado em uma lista de um elemento.

feersum
fonte
1

Matlab / Octave, 26

Isso é basicamente apenas uma tradução da resposta do Mathematica pelo xnor. Ele funciona anexando um zeros a menos que o comprimento do vetor de entrada. Observe que acrescentar mais um não funcionaria, pois o resultado seria 0 o tempo todo. Obrigado a MartinBüttner pelos -4 caracteres desta solução =)

@(x)median([x,0*x(2:end)])
flawr
fonte
@ MartinBüttner Você está absolutamente certo. Eu o alterei agora: o programa acrescentará apenas um zero a menos que a entrada. Dessa forma, é garantido que sempre tenhamos um número ímpar de elementos e a mediana cuide do resto.
perfil completo de Flawr
ou pop o último 0 da sua solução anterior.
Optimizer
@ MartinBüttner Obrigado, é claro que é muito melhor. @ Optimizer Como você faria isso?
perfil completo de Flawr
Eu não faço ideia. Eu pensei que deveria haver uma maneira de simplesmente sair do último elemento, algo assim @(x)median([0*x,x](2:end)). Embora pareça que são os mesmos bytes que agora.
Optimizer
@ Optimizer Eu já pensei ter perdido um recurso importante do Matlab =) É uma pena que a notação que você sugeriu não funcione, às vezes seria realmente útil!
flawr
1

Python, 72 60 bytes

Esta é a primeira solução que pensei e é bastante ingênua. A segunda metade é basicamente uma duplicata da primeira metade do código, mas eu não tinha certeza de como reduzi-lo. Gostaria de saber se pode ser encurtado usando eval...

Edit: Alteradas lambdas para compreensões.

Experimente aqui

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

Isso tem apenas 4 caracteres a mais, mas ainda vale a pena observar, usando o TIP do Sp3000 .

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

Javascript, 63

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

Uma versão mais legível:

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
fonte