Encontre os números mínimos e máximos em uma matriz, sem usar os recursos internos

15

Desafio

Dada uma matriz de números inteiros, recebidos de stdin, argumentos de função, argumentos de programa ou algum outro método:

Saída apenas os números mínimo e máximo na matriz, através de um valor de retorno, stdout ou outros métodos de ajuste.

Sessão de exemplo

> minmax( {0, 15, 2, 3, 7, 18, -2, 9, 6, -5, 3, 8, 9, -14} )
-14 18

Implementação de referência

// C++14

void minmax(std::vector<int> v) {
    int min = v[0]; int max = v[0];
    for(auto it : v) {
        if (*it < min)
            min = *it;
        if (*it > max)
            max = *it;
    }
    std::cout << min << ' ' << max << std::endl;
}

Regras

  • Você não pode usar uma função interna para calcular os valores.
  • Lacunas padrão não permitidas.
  • Implementações criativas incentivadas.
  • Este é o , a resposta mais curta vence, mas não será selecionado.

Esclarecimentos

  • Se a matriz contiver 1 elemento, você precisará produzi-la duas vezes.
  • Se os valores mínimo e máximo forem os mesmos, você precisará produzir os dois.
dkudriavtsev
fonte
12
Este é um desafio do X sem Y , que não é particularmente interessante.
Mego
5
@DmitryKudriavtsev Experimente a sandbox na próxima vez.
Mego
5
Sério, use a Sandbox . Suas alterações no desafio invalidaram todas as respostas.
Mego
1
Eu incentivei métodos criativos Não, você encorajou soluções de curto, etiquetando-locode golf
Luis Mendo
1
Como disse Luis Mendo Sim, todo mundo está apenas postar "i classificar sua matriz usando um built-in e tomar primeiro e último", em diferentes línguas, não é realmente criativo: x
Walfrat

Respostas:

29

Geléia , 3 bytes

Ṣ.ị

Experimente online!

Classifique a matriz e, em seguida, use o elemento 0,5-th.

A geléia usa a indexação 1 e a indexação de pontos flutuantes significa tomar seu piso e seu teto.

Portanto, o elemento 0,5-th forneceria o 0º elemento e o 1º elemento.

O 0º elemento é o último elemento.

Freira Furada
fonte
2
Bastante esperto, espero por isso ... Jelly!
Rohan Jhunjhunwala 23/08
Ah, então isso tornaria a mediana trivial.
Adám 24/08/16
1
@KonradRudolph This .
Leaky Nun
1
Você não quer o primeiro e o último elementos, e não os dois primeiros ? Ou entendi mal a sua explicação?
precisa saber é o seguinte
1
@TobySpeight Na indexação baseada em 1, o 0º elemento é o último elemento.
Leaky Nun
12

Python, 61 49 37 36 34 31 bytes

lambda s:s.sort()or[s[0],s[-1]]

-12 bytes graças ao RootTwo

Mais -12 bytes graças a chepner

-2 bytes graças a johnLate

-3 bytes graças a johnLate

acrólito
fonte
1
Mudei o cabeçalho para Python porque ele também funciona no Python 3.
Leaky Nun
1
Você pode jogar fora uma dúzia de bytes: use [::(len(s)-1)or 1]para o primeiro índice. E o segundo termo pode ser reduzido para s[:len(s)<2].
RootTwo
Ao custo de classificar a lista duas vezes, você pode cortar mais 12 bytes: lambda s:sorted(s)[:1]+sorted(s)[-1:].
chepner
salve 6 bytes porlambda s:sorted(s)[::len(s)-1]
Aaron
A versão atual ( lambda s:sorted(s)[::len(s)-1]) não funciona para matrizes com um elemento ( ValueError: slice step cannot be zero). Uma possível correção seria lambda s:sorted(s*2)[::len(s*2)-1](34 bytes).
johnLate
8

Brain-Flak 220 218 bytes

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

Experimente Online!

Explicação

Primeiro, ele dobra o valor máximo (no elenco, a lista tem apenas um comprimento)

(({}))

Em seguida, ele usa meu algoritmo de classificação de bolhas:

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

Em seguida, ele pega o valor superior da pilha (ou seja, o mínimo)

({}<...>)

Então ele aparece até a altura da pilha ser uma:

((())){{}{}([][()])}{}
Post Rock Garf Hunter
fonte
8

JavaScript (ES6), 34 bytes

a=>[a.sort((x,y)=>x-y)[0],a.pop()]

sortclassifica no local, para que eu possa apenas me referir ao índice [0] para o valor mais baixo e popo valor mais alto da matriz, no entanto, ele faz uma sequência de caracteres por padrão, então preciso passar por um comparador.

Neil
fonte
Eu não acho que você precise da (x,y)=>x-ypeça, a menos que o uso sort()com o algoritmo padrão conte como interno.
Scott
1
@ Scott Mas eu não quero uma espécie lexical ...
Neil
Certo ... eu não testei com números> 10 ou <0. Eu não sabia que sort()internamente trata tudo como strings - desculpe!
Scott
5

Mathematica, 18 bytes

Sort[#][[{1,-1}]]&

Classifica a matriz e extrai o primeiro e o último valor.

Martin Ender
fonte
5

R, 31 bytes

l=sort(scan());l[c(1,sum(l|1))]

Não é tão original, mas ei!

Frédéric
fonte
5

Código da máquina ARM, 26 bytes

Despejo hexadecimal (little endian):

6810 4601 f852 cb04 4560 bfc8 4660 4561 bfb8 4661 3b01 d8f5 4770

Esta é uma função, sem chamada de sistema ou dependência de biblioteca. A codificação é Thumb-2, uma codificação variável (2 ou 4 bytes) para ARM de 32 bits. Como se pode imaginar, não há uma maneira fácil de classificar e escolher o primeiro e o último elementos aqui. No geral, não há nada realmente tão sofisticado acontecendo aqui, é mais ou menos o mesmo que a implementação de referência.

Montagem não destruída (sintaxe GNU):

.syntax unified
.text
.global minmax
.thumb_func
minmax:
    @Input: @r0 and r1 are dummy parameters (they don't do anything)
    @r2 - Pointer to list of integers (int*)
    @r3 - Number of integers to sort (size_t)
    @Output:
    @Minimum of the list in r0 (int)
    @Maximum in r1 (int)
    ldr r0,[r2] @min=r2[0]
    mov r1,r0 @max=min
    loop:
        @ip is intra-procedure call register, a.k.a. r12
        ldr ip,[r2],#4 @ip=*r2++
        cmp r0,ip
        it gt @if (r0>ip)
        movgt r0,ip @r0=ip
        cmp r1,ip
        it lt @if (r1<ip)
        movlt r1,ip @r1=ip
        subs r3,r3,#1
        bhi loop @while (--r3>0)
    bx lr @Return

Testado no Raspberry Pi 3; aqui está o script de teste (C99, entrada por argv):

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
//First 2 arguments are dummies.
uint64_t minmax(int,int,int* array,size_t size);

int main(int argc,char** argv) {
    int i;
    int array[argc-1];
    for (i=1;i<argc;i++) {
        array[i-1]=atoi(argv[i]);
    }
    uint64_t result = minmax(0,0,array,argc-1);
    printf("Minimum is %d, maximum is %d.\n",(unsigned)result,(unsigned)(result>>32));
}
Ian Chew
fonte
4

Haskell, 27 bytes

f x=(`foldl1`x)<$>[min,max]

Em Haskell, mine maxforneça o mínimo e o máximo de dois argumentos, não de uma lista. Eu não poderia dizer se isso é permitido (parece que em vez única minimume maximumseria anulado) então por favor deixe-me saber se eles são e eu vou apagar imediatamente esta resposta.

Michael Klein
fonte
@nimi Efeito FGITW, infelizmente ...
ThreeFx
3

Oitava, 20 bytes

@(n)sort(n)([1,end])

Isso classifica o vetor de entrada e gera o primeiro e o último valor.

flawr
fonte
3

Na verdade, 5 bytes

S;F@N

Experimente online!

Explicação:

S;F@N
S      sort
 ;     dupe
  F    first element
   @N  and last element
Mego
fonte
3

MATL , 4 bytes

S5L)

Experimente online!

Explicação

S    % Implicitly input the array. Sort
5L   % Push [1 0]. When used as a (modular, 1-based) index, this means "first and last"
)    % Apply as an indexing vector into the sorted array. Implicitly display
Luis Mendo
fonte
3

Python, 29 bytes

lambda s:s[s.sort():1]+s[-1:]

Teste em Ideone .

Dennis
fonte
3

C, 83 81 79 bytes

m,M;f(a,s)int*a;{for(m=M=*a;s--;++a)*a<m?m=*a:*a>M?M=*a:0;pr‌​intf("%i %i",m,M);}
NoSeatbelts
fonte
1
a declaração pode se transformar de ...f(a,s)int*a{...acordo com isto
cat
1
Você pode combinar as expressões ternárias para obter outros 2 bytes de desconto:m,M;f(a,s)int*a;{for(m=M=*a;s--;++a)*a<m?m=*a:*a>M?M=*a:0;printf("%i %i",m,M);}
gastropner
Em gccvocê pode substituir *a>M?M=*a:0por*a<M?:M=*a
ceilingcat
2

V , 12 bytes

:sor
ò2Gjkd

Experimente online!

Os nossos agradecimentos a DJMcMayhem por isso.

Rɪᴋᴇʀ
fonte
1
\o/Não sou mais a única pessoa que já usou esse idioma!
DJMcMayhem
1
Se a entrada for um número único, esse número ainda precisará ser emitido duas vezes
Luis Mendo
@LuisMendo hm, vai trabalhar nisso.
Rɪᴋᴇʀ
2

CJam, 10 9 bytes

q~$_(p;W>

Experimente online.

Eu realmente não sou bom em CJam.

q~          e# eval input
  $         e# sort
   _        e# duplicate
    (       e# pop first
     p      e# print
      ;     e# remove array
       W>   e# get last element
PurkkaKoodari
fonte
A maneira usual de obter o primeiro elemento de uma lista é 0=(mas infelizmente isso não salva bytes). Duas outras soluções de 9 bytes: 0W]q~$f=pou o bloco sem nome {$2*_,(%}.
Martin Ender
8 bytes: q~$(p)p;. Você pode usar )para obter o último elemento como você usa (para obter o primeiro.
Business Cat
@ BusinessCat É o que eu tinha originalmente, mas falha na entrada de elemento único.
PurkkaKoodari
@ Pietu1998: Oh, você está certo. Eu não percebi isso.
Business Cat
2

Python 2, 34 bytes

x=sorted(input());print x[0],x[-1]
Azul
fonte
2

PHP, 44 bytes

function a($a){sort($a);echo $a[0].end($a);}
Dexa
fonte
2

Processando, 59 52 bytes

void m(int[]x){x=sort(x);print(x[0],x[x.length-1]);}

Na verdade, o processamento não me permite ler do stdin que consegui encontrar e não sei se o compilador Java interno suporta lambdas (e faz tanto tempo desde que tive que escrever Java sério que não uso lembro como).

Cody
fonte
Você pode salvar bytes removendo espaços apósint[]
Kritixi Lithos
1

Perl 6 13 bytes

*.sort[0,*-1]

Teste:

my &min-max = *.sort[0,*-1];

say min-max 1;
# (1 1)
say min-max (0, 15, 2, 3, 7, 18, -2, 9, 6, -5, 3, 8, 9, -14)
# (-14 18)
Brad Gilbert b2gills
fonte
Droga, você me venceu lá!
Bb94
1

C #, 60 bytes

n=>{System.Array.Sort(n);return new[]{n[0],n[n.Length-1]};};

Um método ingênuo de 93 bytes:

n=>{var r=new[]{n[0],n[0]};foreach(int i in n){if(i<r[0])r[0]=i;if(i>r[1])r[1]=i;}return r;};
TheLethalCoder
fonte
1

Awak POSIX, 44 bytes

awk '{for(;NF-1;NF--)if($1>$NF)$1=$NF}1' RS=
Steven Penny
fonte
1

Oitava , 35 bytes

@(x)[x(all(t=x<=x')) x(sum(t)==1)]

Esta é uma função anoynymous. Experimente em ideone .

O código evita o uso da classificação. Ou seja, todas as comparações "pares iguais ou inferiores" entre os elementos da entrada. O mínimo é o elemento para o qual todas as comparações são verdadeiras. O máximo é aquele para o qual apenas uma comparação é verdadeira.

Luis Mendo
fonte
1

Python, 35 34 bytes

lambda s:sorted(s+s[:1])[::len(s)]

Versão alternativa:

lambda s:sorted(s+s)[::len(s)*2-1]

Versão antiga, 35 bytes.

lambda s:sorted(s+[s[0]])[::len(s)]

Bastante simples: pegue a lista de entrada, adicione o primeiro elemento, classifique-o e depois pegue o primeiro e o comprimento da lista resultante. Como o comprimento da entrada após o acréscimo de um elemento é comprimento + 1, isso acaba levando o primeiro e o último elemento da lista, que são os elementos mínimo e máximo.

TLW
fonte
1
Embora não seja a resposta mais curta em Python, isso é muito criativo! 1
mbomb007
O de 34 bytes não funciona no Python 3; isso funciona tanto em 2 quanto em 3. Além disso, foi postado após este.
TLW
@ mbomb007 - bem, jogou golfe. Isto agora é amarrado para o mais curto implementação Python, e como um bônus funciona em ambos os 2 e 3.
TLW
1

zsh, 22 bytes

(){echo $1 $_} ${(n)@}

define uma função lambda que imprime seu primeiro arg ( $1) e o último argumento para o comando anterior ( $_) e o passa $@após a classificação para que o comando anterior se torne a invocação desse lambda


zsh, 21 bytes

isso só funciona bem se houver mais de um argumento :(

<<<"${${(n)@}/ * / }"

classifica $@, transforma uma string e substitui tudo, desde o primeiro espaço até o último por um único espaço, depois passa como entrada para o gato com<<<


uso:

$ ./minmax 23 342 21 10
10 342
izabera
fonte
1

Scala, 55 bytes

val s=args.map(_.toInt).sorted
print(s.head+" "+s.last)

Executar:

$ scala minmax.scala 1 2 3 4 5 6 7 8 9

AmazingDreams
fonte
1

Bash + coreutils, 30 bytes

tr \  \\n|sort -n|sed '$p;1!d'

O script sed imprime, depois que a entrada é classificada, o primeiro e o último número inteiro.

seshoumara
fonte
1

dc, 110 bytes

?ddsMsmzdsAsa[z1-:az0<S]dsSx[>R]s?[la;asM]sR[lM]sQ[lQxla1-dsa;al?xla0<N]dsNxlAsa[<R]s?[la;asm]sR[lm]sQlNxlmlMf

Ajude-me, dc ers! Você é minha única esperança!

Obrigado a @seshoumara por encontrar esse bug!

Vou adicionar uma explicação mais tarde. Aqui está um pouco dividido:

?dd sM sm
zd sA sa
[z 1- :a z0<S]dsSx
 [>R]s?
 [la;asM]sR
 [lM]sQ
[lQx la 1- dsa ;a l?x la0<N]dsNx
lA sa
 [<R]s?
 [la;a sm]sR
 [lm]sQ
lNx
lm lM f
Joe
fonte
Não gravei como invocar isso e agora não consigo me lembrar. O que quer que eu esteja fazendo agora, estou fazendo errado, porque isso sempre retorna 0 como o menor elemento.
Joe
1
Pfew! Demorou um pouco para estrelar, mas encontrou o bug no seu código. É o primeiro caractere (0) que você duplica e inicializa os registros Me m. Mas se na lista de entrada nenhum número for menor que m=0, ou nenhum número for maior que M=0, então você obterá um resultado incorreto, porque adicionou artificialmente 0 aos números da amostra. A solução é substituir o primeiro 0 por ?d, que lê os números e inicializa Me mcom o último número, tornando-o parte da amostra. Em seguida, execute o código assim: echo "8 _2 5" | dc -e "? DdsMsm ....".
seshoumara
Uau, obrigado, @seshoumara! Eu nunca teria notado isso! (Eu tinha esquecido tudo sobre esta questão, também: P)
Joe
1

Java, 115 bytes

String f(int[]i){int t=i[0],a=t,b=t;for(int c=0;c<i.length;c++){a=i[c]<a?i[c]:a;b=i[c]>b?i[c]:b;}return""+a+" "+b;}

Ungolfed:

String f(int[] i) {
    int t=i[0], a=t, b=t; // assigns a and b to i[0]
    for (int c=0; c < i.length; c++) { // loop through the array
        a=(i[c]<a) ? i[c] : a;
        b=(i[c]>b) ? i[c] : b; // assignment with ternary operator
    }
    return ""+a+" "+b; // returns a string
}

Minha primeira solução de código "golfe".

AMACB
fonte