Confronta quattro numeri interi, restituisce la parola in base al massimo


9

Questa funzione deve considerare quattro ingressi interi ( a, b, c, d) e restituire una parola binaria basata su cui valori uguali al massimo dei quattro.

Il valore restituito sarà compreso tra 1e 0xF.

Per esempio:

a = 6, b = 77, c = 1, d = 4

ritorni 2(binario 0010; viene impostato solo il secondo bit meno significativo corrispondente al bsolo valore massimo)

a = 4, b = 5, c = 10, d = 10

ritorni 0xC(binario 1100; bit significativi del 3o e 4o minimo impostati corrispondenti ce dpari al valore massimo)

a = 1, b = 1, c = 1, d = 1

ritorna 0xF(binario 1111; tutti e quattro i bit impostati perché tutti i valori equivalgono al massimo)

Ecco una semplice implementazione:

int getWord(int a, int b, int c, int d)
{
    int max = a;
    int word = 1;
    if (b > max)
    {
        max = b;
        word = 2;
    }
    else if (b == max)
    {
        word |= 2;
    }
    if (c > max)
    {
        max = c;
        word = 4;
    }
    else if (c == max)
    {
        word |= 4;
    }
    if (d > max)
    {
        word = 8;
    }
    else if (d == max)
    {
        word |= 8;
    }
    return word;
}

il valore restituito può essere una stringa di 0 e 1, vettore bool / bit o intero


2
Ho una soluzione in un linguaggio da golf, che utilizza i comandi integrati Reverse, Maximum, Equality-check, Join, Convert da binario a intero, Converti da intero a esadecimale. Questo significa che il mio punteggio è 1 a causa del controllo di uguaglianza? Ho la sensazione che questo sia troppo focalizzato su linguaggi regolari, e anche per quelli non è chiaro al 100% quale sia il punteggio per dire un massimo costruito ..: S
Kevin Cruijssen

1
Vorrei suggerire di provare a: 1. cambiare questa domanda in code-golf, che interessa solo il numero di byte. 2. oppure, limitarsi ad una certa lingua (per favore certe versioni del compilatore / interprete), ed elencare tutte le dichiarazioni e gli operatori consentiti e come valutarli.
TSH

5
1 è un'opzione migliore, IMO. Penso che questo costituisca una domanda perfettamente valida per il code-golf e non vedo alcun beneficio che deriverebbe dalla limitazione delle lingue disponibili per le risposte
senox13

2
Ho aggiornato la mia domanda per rimuovere i criteri. Fammi sapere che non è ancora chiaro
Mr Anderson

5
Devo produrre un numero decimale? O posso invece emettere 4 cifre binarie?
TSH

Risposte:


8

Gelatina , 2 byte

Accetta input come [d,c,b,a]. Restituisce un elenco di booleani.

Ṁ=

Provalo online!

M massimo

= uguale a (implica che l'altro argomento è l'argomento originale; vettorializza)


5

R , 17 byte

max(a<-scan())==a

Provalo online!

Restituisce un vettore di booleani. Poiché questo output è stato confermato, questo è preferibile all'output numerico, poiché quello è quasi due volte più lungo:

R , 33 byte

sum(2^which(max(a<-scan())==a)/2)

Provalo online!


4

APL (Dyalog Unicode) , 4 byte SBCS

Funzione prefisso tacito anonimo. Prende [a,b,c,d]come argomento. Restituisce un array bit-booleano. *

⌈/=⌽

Provalo online!

⌈/ Fa il massimo dell'argomento

= uguale (vettorializza)

 il contrario dell'argomento?

* Si noti che APL memorizza matrici di valori booleani utilizzando un bit per valore, quindi ciò restituisce effettivamente una parola di 4 bit, nonostante il modulo di visualizzazione sia 0 0 1 0.



2

Perl 6 , 12 byte

{$_ X==.max}

Provalo online!

Blocco di codice anonimo che accetta un elenco di numeri interi e restituisce un elenco di valori booleani. Se dobbiamo restituire un numero, sono +4 byte con cui avvolgere l'interno del blocco di codice 2:[...].

Spiegazione:

{          }  # Anonymous code block
 $_           # With the input
    X==       # Which values are equal
       .max   # To the maximum element

OP ora dice che non è necessario avvolgere.
Adám,

2

Japt, 5

m¶Urw

Provalo!

-4 byte grazie a @Oliver!
-2 byte grazie a @Shaggy!

L'input è un array di 4 elementi nel seguente formato:

[d, c, b, a]

L'output è un array di bit.


Certo che c'è;) Apparentemente ci sono molte scorciatoie da imparare.
dana,

Se un array booleano è un output accettabile, questo può essere 7 byte
Oliver

@Oliver, 5 byte ;)
Shaggy

Ragazzi, siete abbastanza bravi :) È interessante il modo in cui la rwconversione r("w")fa una riduzione ottenendo ripetutamente il massimo. Lo stesso con la conversione U.m("===", ...). In ogni caso, grazie per i suggerimenti!
dana,

2

codice macchina x86 (MMX / SSE1), 26 byte (4x int16_t)

codice macchina x86 (SSE4.1), 28 byte (4x int32_t o uint32_t)

codice macchina x86 (SSE2), 24 byte (4x float32) o 27B per cvt int32

(L'ultima versione che converte int32 in float non è perfettamente accurata per numeri interi grandi che arrotondano allo stesso float. Con l'input float, l'arrotondamento è il problema del chiamante e questa funzione funziona correttamente se non ci sono NaN, identificando float che confrontano == al massimo. Le versioni intere funzionano per tutti gli input, trattandoli come complemento firmato 2).

Tutti questi funzionano in modalità 16/32/64 bit con lo stesso codice macchina.

Una convenzione di chiamata di stack-args consentirebbe di eseguire il ciclo degli args due volte (trovare max e quindi confrontare), probabilmente dandoci un'implementazione più piccola, ma non ho provato questo approccio.

x86 SIMD ha bitmap vettoriale-> intero come una singola istruzione ( pmovmskbo movmskpso pd), quindi è stato naturale per questo, anche se le istruzioni MMX / SSE sono lunghe almeno 3 byte. Le istruzioni SSSE3 e successive sono più lunghe di SSE2 e le istruzioni MMX / SSE1 sono le più brevi. Sono pmax*state introdotte versioni diverse di (max verticale intero compresso) in momenti diversi, con SSE1 (per registri mmx) e SSE2 (per registri xmm) con solo parola con segno (16 bit) e byte senza segno.

( pshufwe pmaxswsui registri MMX sono nuovi con Katmai Pentium III, quindi richiedono SSE1, non solo il bit funzione CPU MMX.)

Questo è richiamabile da C come unsigned max4_mmx(__m64)con l'i386 System V ABI, che passa un __m64argomento mm0. (Non x86-64 System V, che passa __m64in xmm0!)

   line         code bytes
    num  addr   
     1                         global max4_mmx
     2                             ;; Input 4x int16_t in mm0
     3                             ;; output: bitmap in EAX
     4                             ;; clobbers: mm1, mm2
     5                         max4_mmx:
     6 00000000 0F70C8B1           pshufw    mm1, mm0, 0b10110001   ; swap adjacent pairs
     7 00000004 0FEEC8             pmaxsw    mm1, mm0
     8                         
     9 00000007 0F70D14E           pshufw    mm2, mm1, 0b01001110   ; swap high/low halves
    10 0000000B 0FEECA             pmaxsw    mm1, mm2
    11                         
    12 0000000E 0F75C8             pcmpeqw   mm1, mm0               ; 0 / -1
    13 00000011 0F63C9             packsswb  mm1, mm1               ; squish word elements to bytes, preserving sign bit
    14                         
    15 00000014 0FD7C1             pmovmskb  eax, mm1          ; extract the high bit of each byte
    16 00000017 240F               and       al, 0x0F          ; zero out the 2nd copy of the bitmap in the high nibble
    17 00000019 C3                 ret

size = 0x1A = 26 bytes

Se ci fosse un pmovmskw, cosa avrebbe salvato il packsswbe il and(3 + 2 byte). Non è necessario and eax, 0x0fperché pmovmskbsu un registro MMX azzera già i byte superiori. I registri MMX hanno una larghezza di soli 8 byte, quindi AL a 8 bit copre tutti i possibili bit diversi da zero.

Se sapessimo che i nostri input non sono negativi, potremmopacksswb mm1, mm0 produrre byte con segno non negativo nei 4 byte superiori di mm1, evitando la necessità di andafter pmovmskb. Quindi 24 byte.

Il pacchetto x86 con saturazione firmata tratta l'input e l'output come firmato, quindi conserva sempre il bit di segno. ( https://www.felixcloutier.com/x86/packsswb:packssdw ). Curiosità: il pacchetto x86 con saturazione non firmata considera ancora l' input come firmato. Questo potrebbe essere il motivo per cui PACKUSDWnon è stato introdotto fino a SSE4.1, mentre le altre 3 combinazioni di dimensioni e firma esistevano da MMX / SSE2.


O con numeri interi a 32 bit in un registro XMM (e pshufdinvece di pshufw), ogni istruzione avrebbe bisogno di un byte di prefisso in più, ad eccezione della movmskpssostituzione del pacchetto / e. Ma pmaxsd/ pmaxudho bisogno di un byte extra in più ...

richiamabile da C comeunsigned max4_sse4(__m128i); con x86-64 System V o MSVC vectorcall ( -Gv), entrambi i quali passano __m128i/ __m128d/ / __m128args in registri XMM a partire da xmm0.

    20                         global max4_sse4
    21                             ;; Input 4x int32_t in xmm0
    22                             ;; output: bitmap in EAX
    23                             ;; clobbers: xmm1, xmm2
    24                         max4_sse4:
    25 00000020 660F70C8B1         pshufd    xmm1, xmm0, 0b10110001   ; swap adjacent pairs
    26 00000025 660F383DC8         pmaxsd    xmm1, xmm0
    27                         
    28 0000002A 660F70D14E         pshufd    xmm2, xmm1, 0b01001110   ; swap high/low halves
    29 0000002F 660F383DCA         pmaxsd    xmm1, xmm2
    30                         
    31 00000034 660F76C8           pcmpeqd   xmm1, xmm0               ; 0 / -1
    32                         
    33 00000038 0F50C1             movmskps  eax, xmm1          ; extract the high bit of each dword
    34 0000003B C3                 ret

size = 0x3C - 0x20 = 28 bytes

O se accettiamo input as float, possiamo usare le istruzioni SSE1. Il floatformato può rappresentare una vasta gamma di valori interi ...

Oppure, se pensi che stia piegando troppo le regole, inizia con un 3 byte 0F 5B C0 cvtdq2ps xmm0, xmm0da convertire, creando una funzione di 27 byte che funzioni per tutti gli interi che sono esattamente rappresentabili come binario IEEE32 floate molte combinazioni di input in cui alcuni degli input ottengono arrotondato a un multiplo di 2, 4, 8 o qualsiasi altra cosa durante la conversione. (Quindi è 1 byte più piccolo della versione SSE4.1 e funziona su qualsiasi x86-64 con solo SSE2.)

Se uno qualsiasi degli ingressi float è NaN, nota che maxps a,bimplementa esattamente (a<b) ? a : b, mantenendo inalterato l'elemento del 2 ° operando . Quindi potrebbe essere possibile che questo ritorni con una bitmap diversa da zero anche se l'input contiene un po 'di NaN, a seconda di dove si trovano.

unsigned max4_sse2(__m128);

    37                         global max4_sse2
    38                             ;; Input 4x float32 in xmm0
    39                             ;; output: bitmap in EAX
    40                             ;; clobbers: xmm1, xmm2
    41                         max4_sse2:
    42                         ;    cvtdq2ps  xmm0, xmm0
    43 00000040 660F70C8B1         pshufd    xmm1, xmm0, 0b10110001   ; swap adjacent pairs
    44 00000045 0F5FC8             maxps     xmm1, xmm0
    45                         
    46 00000048 660F70D14E         pshufd    xmm2, xmm1, 0b01001110   ; swap high/low halves
    47 0000004D 0F5FCA             maxps     xmm1, xmm2
    48                         
    49 00000050 0FC2C800           cmpeqps   xmm1, xmm0               ; 0 / -1
    50                         
    51 00000054 0F50C1             movmskps  eax, xmm1          ; extract the high bit of each dword
    52 00000057 C3                 ret

size = 0x58 - 0x40 = 24 bytes

copia-e-mescola con pshufdè ancora la nostra migliore scommessa: shufps dst,src,imm8legge l'input per la metà bassa di dst da dst . E abbiamo bisogno di una copia e shuffle non distruttiva entrambe le volte, quindi 3 byte movhlpse unpckhps/ pd sono entrambi fuori. Se ci limitassimo a un massimo scalare, potremmo usarli, ma costa un'altra istruzione da trasmettere prima del confronto se non abbiamo già il massimo in tutti gli elementi.


Correlati: SSE4.1 phminposuwpuò trovare la posizione e il valore del minimo uint16_tin un registro XMM. Non penso che sia una vittoria sottrarre da 65535 per usarlo per max, ma vedo una risposta SO sull'utilizzo per max di byte o numeri interi con segno.


1

Python 3.8 (pre-release) , 67 byte

Funzione lambda che accetta 4 numeri interi, il bit sposta il risultato booleano del loro confronto al valore massimo con l'aiuto del nuovo operatore di assegnazione di Python 3.8 e restituisce l'OR bit a bit dei risultati

lambda a,b,c,d:((m:=max(a,b,c,d))==d)<<3|(m==c)<<2|(m==b)<<2|(a==m)

Provalo online!


: = mi ricorda i vecchi tempi in cui quello era l'operatore di assegnazione con la formula di Lotus Notes. Immagino che dovrò dare un'occhiata a 3.8 per l'amor dei vecchi tempi :)
ElPedro


1

05AB1E , 3 2 byte

ZQ

Input come elenco di [d,c,b,a], output come elenco di valori booleani.

Provalo online o verifica tutti i casi di test .

Spiegazione:

Z    # Take the maximum of the implicit input-list
 Q   # Check for each in the (implicit) input-list if it equals this value
     # (and output implicitly as result)

OP è stato aggiornato - non è necessario convertire in esadecimale.
Adám,

1

JavaScript (ES6), 30 byte

Accetta input come ([d,c,b,a]). Restituisce 4 valori booleani.

a=>a.map(x=>x==Math.max(...a))

Provalo online!


1
OP ha chiarito che puoi effettivamente restituire 4 valori booleani.
Adám,


1

Python 3 , 59 byte 66 byte

def f(l):
 n=max(a)
 for i in 0,1,2,3:a[i]=a[i]==n
 return a[::-1]

Provalo online!

Accetta input as [a,b,c,d]e genera un elenco di valori booleani.

Modificato per essere una funzione corretta, quindi salvato 2 byte rimuovendo le parentesi attorno al condizionale.


1
Ciao e benvenuto in PPCG. Allo stato attuale, la tua risposta ha la forma di uno snippet, che non è consentito. Correggi la tua risposta per renderla conforme al nostro consenso I / O , ovvero renderla una funzione o un programma completo.
Jonathan Frech,

1
Modificato. Prima volta. Apprezzo il testa a testa!
Bsoned

Puoi ridurlo a 37 byte usando questa comprensione dell'elenco all'interno di una lambda. Benvenuto in PPCG e goditi il ​​tuo soggiorno!
Value Ink

@ValueInk La rimozione dello spazio bianco superfluo consente di salvare ancora un altro byte.
Jonathan Frech,

1

1. Python 3.5, 90 byte

Prende la sequenza di numeri come parametri. Restituisce una stringa "binaria"

import sys;v=[*map(int,sys.argv[1:])];m=max(v);s=""
for e in v:s=str(int(e==m))+s
print(s)

esempio:

$ ./script.py 6 77 1 4 77
10010

Spiegazione

import sys
# convert list of string parameters to list of integers
v=[*map(int,sys.argv[1:])]
# get max
m=max(v)
# init outstring
s=""
# walk through list
for e in v:
    # prepend to outstring: int(True)=>1, int(False)=>0
    s=str(int(e==m))+s
# print out result
print(s)

1

C # (compilatore interattivo Visual C #) , 26 byte

n=>n.Select(a=>a==n.Max())

Provalo online!

Accetta input nel formato [d,c,b,a]. Tutti gli altri in basso accettano input come[a,b,c,d]

C # (compilatore interattivo Visual C #) , 35 byte

n=>n.Select((a,b)=>n[3-b]==n.Max())

Restituisce un IEnumerable<bool>.

Provalo online!

C # (compilatore interattivo Visual C #) , 39 byte

n=>n.Select((a,b)=>n[3-b]==n.Max()?1:0)

Restituisce un IEnumerable<int>, che rappresenta i bit.

Provalo online!

C # (compilatore interattivo Visual C #) , 49 byte

n=>{for(int i=4;i-->0;Write(n[i]==n.Max()?1:0));}

Stampa una stringa binaria su STDOUT.

Provalo online!


IEnumerable<bool> è accettabile
Adám,

0

PHP, 54 byte

while($i<4)$argv[++$i]<max($argv)||$r+=1<<$i-1;echo$r;

o

while($i<4)$argv[++$i]<max($argv)||$r+=1<<$i;echo$r/2;

accetta input dagli argomenti della riga di comando. Corri con -nro provali online .


0

Ecco una versione JS che emette come binario

aggiornamento: più breve con join e senza la ricerca:

JavaScript (Node.js) , 42 byte

a=>a.map(x=>+(x==Math.max(...a))).join('')

Provalo online!

Precedente, con ricerca, 49 byte

a=>a.map(x=>[0,1][+(x==Math.max(...a))]).join('')

Provalo online!

Precedente, con riduzione, 52 byte:

a=>a.reduce((y,x)=>y+[0,1][+(x==Math.max(...a))],'')

Provalo online!

fa=>a.map(x=>+(x==Math.max(...a))).join('')
console.log(f([ 4, 1,77, 6])) // 0010
console.log(f([10,10, 5, 4])) // 1100
console.log(f([ 1, 1, 1, 1])) // 1111


1
[0,1][...]01

@Arnauld sembra ovvio ora. Grazie!
Pureferret,

0

C # (compilatore interattivo Visual C #) , 51 byte

x=>{for(int m=x.Max(),i=4;i-->0;)x[i]=x[i]==m?1:0;}

Provalo online!

Sopra è una funzione anonima che esce modificando un argomento . L'output è un array di 1 e 0.

Di seguito è una funzione ricorsiva che genera un numero intero.

C # (compilatore interattivo Visual C #) , 60 byte

int f(int[]x,int i=3)=>i<0?0:2*f(x,i-1)|(x[i]==x.Max()?1:0);

Provalo online!

Entrambe le funzioni accettano input come un array di 4 elementi.

[d, c, b, a]

Non è necessario generare un numero intero.
Adám

@Adam - grazie :) L'ho capito dopo aver pubblicato mentre stavo lavorando sull'altra mia risposta. Prima che avessi la possibilità di cambiare, c'era un'altra risposta C # che utilizzava molti buoni trucchi.
dana,


0

Python 3 , 42 byte

f=lambda a:list(map(lambda x:x==max(a),a))

Restituisce semplicemente un elenco se l'elemento è il massimo per ciascun elemento nell'input. -2 byte se non conteggi l' f=assegnazione.

Provalo online!


f=non conta se non nelle funzioni ricorsive
solo ASCII il

0

Lotto, 92 byte

@set m=%1
@set f=@for %%i in (%*)do @
%f%set/a"m=m+(m-=%%i)*(m>>31)
%f%cmd/cset/a!(m-%%i)

Accetta gli argomenti come parametri della riga di comando in ordine inverso. Funziona calcolando aritmeticamente il massimo dei parametri riducendo su di essi e aggiungendo solo differenze positive dal massimo corrente, quindi mappando nuovamente su ciascun parametro questa volta confrontandolo con il massimo. Convenientemente cmd/cset/anon genera una nuova riga, quindi i risultati vengono automaticamente concatenati insieme. Il %f%salva semplicemente 5 byte su quello che sarebbe un costrutto ripetuto.

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.