Trova gli interi minimo e massimo in un array, senza usare gli builtin


15

Sfida

Dato un array di numeri interi, ricevuti da stdin, argomenti di funzioni, argomenti di programma o qualche altro metodo:

Emette solo i numeri minimo e massimo nell'array, tramite un valore di ritorno, stdout o altri metodi di adattamento.

Sessione di esempio

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

Implementazione di riferimento

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

Regole

  • Non è possibile utilizzare una funzione integrata per calcolare i valori.
  • Scappatoie standard non consentite.
  • Implementazioni creative incoraggiate.
  • Questo è , vince la risposta più breve ma non verrà selezionata.

chiarimenti

  • Se l'array contiene 1 elemento, è necessario emetterlo due volte.
  • Se i valori minimo e massimo sono gli stessi, è necessario emetterli entrambi.

12
Questa è una sfida do X senza Y , che non è particolarmente interessante.
Mego,

5
@DmitryKudriavtsev Prova la sandbox la prossima volta.
Mego,

5
Seriamente, usa il Sandbox . Le modifiche alla sfida hanno invalidato ogni singola risposta.
Mego,

1
Ho incoraggiato i metodi creativi No, hai incoraggiato le soluzioni brevi, taggandolocode golf
Luis Mendo,

1
Come detto Luis Mendo Sì, tutti stanno solo pubblicando "Ordina il tuo array usando un built-in e prendo il primo e l'ultimo", in diverse lingue, non molto creativo: x
Walfrat

Risposte:


29

Gelatina , 3 byte

Ṣ.ị

Provalo online!

Ordina l'array e quindi accetta l'elemento 0,5 °.

Jelly usa l'indicizzazione 1 e l'indicizzazione in virgola mobile significa prendere il suo pavimento e il suo soffitto.

Quindi il 0,5 ° elemento ti darebbe il 0 ° elemento e il 1 ° elemento.

Il 0 ° elemento è l'ultimo elemento.


2
Abbastanza intelligente, lo aspetto .... Gelatina!
Rohan Jhunjhunwala,

Oh, questo renderebbe banale la ricerca della mediana.
Adám,

1
@KonradRudolph This .
Leaky Nun,

1
Non vuoi il primo e l' ultimo elemento, anziché i primi due elementi? O ho frainteso la tua spiegazione?
Toby Speight

1
@TobySpeight Nell'indicizzazione basata su 1 il 0 ° elemento è l'ultimo elemento.
Leaky Nun,

12

Python, 61 49 37 36 34 31 byte

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

-12 byte grazie a RootTwo

Altri -12 byte grazie a chepner

-2 byte grazie a johnLate

-3 byte grazie a johnLate


1
Ho cambiato l'intestazione in Python perché funziona anche in Python 3.
Leaky Nun,

1
Puoi giocare a golf una dozzina di byte: usa [::(len(s)-1)or 1]per il primo pedice. E il secondo termine può essere abbreviato in s[:len(s)<2].
RootDue

A costo di ordinamento dell'elenco due volte, si può radersi un altro 12 byte: lambda s:sorted(s)[:1]+sorted(s)[-1:].
Chepner,

salva 6 byte entrolambda s:sorted(s)[::len(s)-1]
Aaron,

La versione corrente ( lambda s:sorted(s)[::len(s)-1]) non funziona per le matrici con un elemento ( ValueError: slice step cannot be zero). Una possibile correzione sarebbe lambda s:sorted(s*2)[::len(s*2)-1](34 byte).
johnLate,

8

Brain-Flak 220 218 byte

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

Provalo online!

Spiegazione

Innanzitutto raddoppia il valore più alto (nel cast l'elenco è solo uno lungo)

(({}))

Quindi utilizza il mio algoritmo di ordinamento delle bolle:

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

Quindi raccoglie il valore massimo dello stack (ovvero il minimo)

({}<...>)

Quindi si apre fino a quando l'altezza della pila è una:

((())){{}{}([][()])}{}

8

JavaScript (ES6), 34 byte

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

sortordina sul posto, quindi posso semplicemente fare riferimento all'indice [0] per il valore più basso e popil valore più alto dall'array, tuttavia fa un ordinamento di stringa per impostazione predefinita, quindi devo passare un comparatore.


Non penso che tu abbia bisogno della (x,y)=>x-yparte, a meno che l'utilizzo sort()con l'algoritmo predefinito non sia considerato incorporato.
Scott,

1
@Scott Ma non voglio un tipo lessicale ...
Neil,

Giusto ... Non l'ho provato con numeri> 10 o <0. Non sapevo che sort()trattasse internamente tutto come stringhe - scusa!
Scott,

5

Mathematica, 18 byte

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

Ordina l'array ed estrae il primo e l'ultimo valore.


5

R, 31 byte

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

Non così originale, ma ehi!


5

Codice macchina ARM, 26 byte

Dump esadecimale (little endian):

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

Questa è una funzione, senza chiamate di sistema o dipendenza dalla libreria. La codifica è Thumb-2, una codifica variabile (2 o 4 byte) per ARM a 32 bit. Come si potrebbe immaginare, non esiste un modo semplice per ordinare e selezionare qui il primo e l'ultimo elemento. Nel complesso non c'è niente di così fantasioso qui, è più o meno lo stesso dell'implementazione di riferimento.

Assembly ungolfed (sintassi 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

Testato su Raspberry Pi 3; ecco lo script di test (C99, input tramite 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));
}

4

Haskell, 27 byte

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

In Haskell, mine maxfornire minimo e massimo di due argomenti, non di un elenco. Non saprei dire se questo è vietato (sembra che invece sia solo minimume maximumsarebbe vietato) quindi per favore fatemi sapere se lo sono e eliminerò prontamente questa risposta.


@nimi FGITW effect, purtroppo ...
ThreeFx

3

Ottava, 20 byte

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

Questo ordina il vettore di input e genera il primo e l'ultimo valore.




3

MATL , 4 byte

S5L)

Provalo online!

Spiegazione

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


3

C, 83 81 79 byte

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

1
la dichiarazione può trasformarsi in ...f(a,s)int*a{...per questo
cat

1
È possibile combinare le espressioni ternarie per ottenere altri 2 byte: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,

In gccè possibile sostituire *a>M?M=*a:0con*a<M?:M=*a
ceilingcat



2

CJam, 10 9 byte

q~$_(p;W>

Provalo online.

Non sono davvero bravo in CJam.

q~          e# eval input
  $         e# sort
   _        e# duplicate
    (       e# pop first
     p      e# print
      ;     e# remove array
       W>   e# get last element

Il solito modo per ottenere il primo elemento di un elenco è 0=(ma sfortunatamente questo non salva alcun byte). Altre due soluzioni a 9 byte: 0W]q~$f=po il blocco senza nome {$2*_,(%}.
Martin Ender,

8 byte: q~$(p)p;. È possibile utilizzare )per ottenere l'ultimo elemento come si usa (per ottenere il primo.
Business Cat

@BusinessCat Questo è quello che avevo originariamente, ma non riesce per l'input a elemento singolo.
PurkkaKoodari,

@ Pietu1998: Oh, hai ragione. Non me ne sono accorto.
Business Cat

2

Python 2, 34 byte

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

2

PHP, 44 byte

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

2

Elaborazione, 59 52 byte

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

L'elaborazione in realtà non mi permette di leggere da stdin che sono stato in grado di trovare, e non so se il suo compilatore Java interno supporta lambdas (ed è passato tanto tempo da quando ho dovuto scrivere Java serio che non ho ricorda come).


Puoi salvare i byte rimuovendo gli spazi dopoint[]
Kritixi Lithos

1

Perl 6 13 byte

*.sort[0,*-1]

Test:

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)

Accidenti, mi hai battuto lì!
bb94,

1

C #, 60 byte

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

Un metodo ingenuo a 93 byte:

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


1

Ottava , 35 byte

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

Questa è una funzione anoynymous. Provalo su ideone .

Il codice evita di utilizzare l'ordinamento. Vale a dire, esegue tutti confronti a coppie "inferiori o uguali" tra elementi dell'input. Il minimo è l'elemento per cui tutti i confronti sono veri. Il massimo è quello per cui è vero un solo confronto.


1

Python, 35 34 byte

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

Versione alternativa:

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

Vecchia versione, 35 byte.

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

Abbastanza semplice: prendi l'elenco di input, aggiungi il primo elemento, ordinalo, quindi prendi il primo e (lunghezza) th elemento dell'elenco risultante. Poiché la lunghezza dell'input dopo aver aggiunto un elemento è lunghezza + 1, questo finisce per prendere il primo e l'ultimo elemento di detto elenco, che sono gli elementi minimo e massimo.


1
Sebbene non sia la risposta più breve in Python, questa è molto creativa! +1
mbomb007

Quello a 34 byte non funziona in Python 3; funziona in 2 e 3. Inoltre, è stato pubblicato dopo questo.
TLW,

@ mbomb007 - bene, golfato. Questo è ora legato alla più breve implementazione di Python, e come bonus funziona sia in 2 che 3.
TLW

1

zsh, 22 byte

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

definisce una funzione lambda che stampa il suo primo arg ( $1) e l'ultimo argomento al comando precedente ( $_) e lo passa $@dopo averlo ordinato in modo che il comando precedente diventi l'invocazione di quel lambda


zsh, 21 byte

funziona bene solo se c'è più di 1 argomento :(

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

ordina $@, lo rende una stringa e sostituisce tutto dal primo spazio all'ultimo con un singolo spazio, quindi lo passa come input al gatto con<<<


utilizzo:

$ ./minmax 23 342 21 10
10 342

1

Scala, 55 byte

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

Eseguire:

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


1

Bash + coreutils, 30 byte

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

Lo script sed stampa, una volta ordinato l'input, il primo e l'ultimo numero intero.


1

dc, 110 byte

?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

Aiutatemi dc! Sei la mia unica speranza!

Grazie a @seshoumara per aver trovato quel bug!

Aggiungerò una spiegazione più tardi. Qui è un po 'rotto:

?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

Non ho registrato come invocare questo, e ora non ricordo. Qualunque cosa stia facendo ora, lo sto facendo male, perché restituisce sempre 0 come elemento più piccolo.
Joe,

1
Pfew! Ci è voluto un po 'da protagonista, ma ho trovato il bug nel tuo codice. È il primo carattere (0) che duplica e inizializza i registri Me m. Ma se nell'elenco di input nessun numero è più piccolo di m=0, o nessun numero è maggiore di M=0, allora si ottiene un risultato errato, perché si è aggiunto artificialmente 0 ai numeri di esempio. La soluzione è quella di sostituire quel primo 0 con ?d, che legge i numeri e si inizializza Me mcon l'ultimo numero, rendendolo così parte del campione. Quindi eseguire il codice in questo modo: echo "8 _2 5" | dc -e "? DdsMsm ....".
seshoumara,

Wow, grazie, @seshoumara! Non me ne sarei mai accorto! (Avevo dimenticato tutto di questa domanda: P)
Joe,

1

Java, 115 byte

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
}

La mia prima soluzione "golf" in assoluto.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.