Vergleichen Sie vier Ganzzahlen und geben Sie das Wort basierend auf dem Maximum zurück


9

Diese Funktion sollte vier ganzzahligen Eingänge nehmen ( a, b, c, d) und zurück ein binäres Wort basierend auf welchen Wert das Maximum der vier betragen.

Der Rückgabewert liegt zwischen 1und 0xF.

Beispielsweise:

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

Rückgabe 2(binär 0010; nur das zweitniedrigste Bit wird entsprechend bdem einzigen Maximalwert gesetzt)

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

Rückgabe 0xC(binär 1100; 3. und 4. niedrigstwertige Bits, die dem Maximalwert entsprechen cund diesem entsprechen d)

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

Rückgabe 0xF(binär 1111; alle vier Bits gesetzt, da alle Werte gleich dem Maximum sind)

Hier ist eine einfache Implementierung:

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

Der Rückgabewert kann eine Zeichenfolge aus Nullen und Einsen, ein Bool / Bit-Vektor oder eine Ganzzahl sein


2
Ich habe eine Lösung in einer Golfsprache, die die eingebauten Funktionen Reverse, Maximum, Equality-Check, Join, Konvertieren von Binär in Ganzzahl, Konvertieren von Ganzzahl in Hexadezimal verwendet. Bedeutet dies, dass meine Punktzahl aufgrund der Gleichheitsprüfung 1 ist? Ich habe das Gefühl, dass dies zu sehr auf reguläre Sprachen ausgerichtet ist, und selbst für diese ist es nicht 100% klar, wofür die Wertung ein Maximum ist. S
Kevin Cruijssen

1
Ich würde vorschlagen, dass Sie versuchen: 1. diese Frage in Code-Golf zu ändern, wobei nur die Anzahl der Bytes berücksichtigt wird. 2. oder beschränken Sie sich auf eine bestimmte Sprache (bestimmte Version des Compilers / Interpreters bitte) und listen Sie alle zulässigen Anweisungen und Operatoren sowie deren Bewertung auf.
tsh

5
1 ist eine bessere Option, IMO. Ich denke, dies ist eine vollkommen gute Code-Golf-Frage, und ich sehe keinen Vorteil, der sich aus der Einschränkung der für Antworten verfügbaren Sprachen ergeben würde
senox13

2
Ich habe meine Frage aktualisiert, um die Kriterien zu entfernen. Lassen Sie mich wissen, dass es noch unklar ist
Herr Anderson

5
Soll ich eine Dezimalzahl ausgeben? Oder kann ich stattdessen 4 Binärziffern ausgeben?
tsh

Antworten:


8

Gelee , 2 Bytes

Nimmt Eingabe als [d,c,b,a]. Gibt eine Liste von Booleschen Werten zurück.

Ṁ=

Probieren Sie es online aus!

M aximum

= gleich (impliziert, dass das andere Argument das ursprüngliche Argument ist; vektorisiert)



4

APL (Dyalog Unicode) , 4 Byte SBCS

Anonyme stillschweigende Präfixfunktion. Nimmt [a,b,c,d]als Argument. Gibt ein bit-boolesches Array zurück. *

⌈/=⌽

Probieren Sie es online aus!

⌈/ Macht das Maximum des Arguments

= gleich (vektorisiert)

 das Gegenteil des Arguments?

* Beachten Sie, dass APL Arrays von Booleschen Werten mit einem Bit pro Wert speichert, sodass dies trotz der Anzeigeform tatsächlich ein 4-Bit-Wort zurückgibt 0 0 1 0.



2

Perl 6 , 12 Bytes

{$_ X==.max}

Probieren Sie es online aus!

Anonymer Codeblock, der eine Liste von Ganzzahlen verwendet und eine Liste von Booleschen Werten zurückgibt. Wenn wir als Zahl zurückkehren müssen, sind es +4 Bytes, mit denen das Innere des Codeblocks umbrochen wird 2:[...].

Erläuterung:

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

OP sagt jetzt, dass Sie nicht wickeln müssen.
Adám

2

Japt, 5

m¶Urw

Versuch es!

-4 Bytes dank @Oliver!
-2 Bytes dank @Shaggy!

Die Eingabe ist ein 4-Element-Array im folgenden Format:

[d, c, b, a]

Die Ausgabe ist ein Array von Bits.


Natürlich gibt es;) Es gibt anscheinend viele Abkürzungen zu lernen.
Dana

Wenn ein boolesches Array eine akzeptable Ausgabe ist, kann dies 7 Bytes sein
Oliver

@Oliver, 5 Bytes ;)
Shaggy

Ihr seid ziemlich gut :) Das ist interessant, wie rwKonvertierungen zu r("w")einer Reduzierung führen, indem wiederholt das Maximum erreicht wird. Gleiches gilt für die Umstellung auf U.m("===", ...). Auf jeden Fall danke für die Tipps!
dana

2

x86-Maschinencode (MMX / SSE1), 26 Byte (4x int16_t)

x86-Maschinencode (SSE4.1), 28 Byte (4x int32_t oder uint32_t)

x86-Maschinencode (SSE2), 24 Byte (4x float32) oder 27B an cvt int32

(Die letzte Version, die int32 in float konvertiert, ist für große Ganzzahlen, die auf denselben float runden, nicht genau. Bei float-Eingaben ist das Runden das Problem des Aufrufers, und diese Funktion funktioniert ordnungsgemäß, wenn keine NaNs vorhanden sind, und identifiziert Floats, die == vergleichen bis zum Maximum. Die Ganzzahlversionen funktionieren für alle Eingaben und behandeln sie als vorzeichenbehaftete 2er-Ergänzung.)

Alle diese Funktionen arbeiten im 16/32/64-Bit-Modus mit demselben Maschinencode.

Eine Stack-Args-Aufrufkonvention würde es ermöglichen, die Args zweimal zu durchlaufen (max zu finden und dann zu vergleichen), was uns möglicherweise eine kleinere Implementierung geben würde, aber ich habe diesen Ansatz nicht ausprobiert.

x86 SIMD hat eine Vektor-> Ganzzahl-Bitmap als einzelnen Befehl ( pmovmskboder movmskpsoder pd), daher war dies natürlich, obwohl MMX / SSE-Befehle mindestens 3 Byte lang sind. SSSE3- und spätere Anweisungen sind länger als SSE2, und MMX / SSE1-Anweisungen sind die kürzesten. Verschiedene Versionen von pmax*(gepacktes ganzzahliges vertikales Maximum) wurden zu unterschiedlichen Zeiten eingeführt, wobei SSE1 (für mmx-Regs) und SSE2 (für xmm-Regs) nur vorzeichenbehaftete Wörter (16 Bit) und vorzeichenlose Bytes enthielten.

( pshufwund pmaxswauf MMX-Registern sind Katmai Pentium III neu, daher benötigen sie wirklich SSE1, nicht nur das MMX-CPU-Funktionsbit.)

Dies kann von C aus aufgerufen werden, wie unsigned max4_mmx(__m64)beim i386 System V ABI, der ein __m64Argument übergibt mm0. (Nicht x86-64 System V, das geht __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

Wenn es ein pmovmskwgäbe, was hätte das packsswbund das and(3 + 2 Bytes) gespeichert . Wir brauchen nicht, and eax, 0x0fweil pmovmskbin einem MMX-Register die oberen Bytes bereits Nullen sind. MMX-Register sind nur 8 Byte breit, sodass 8-Bit-AL alle möglichen Nicht-Null-Bits abdeckt.

Wenn wir wüssten, dass unsere Eingaben nicht negativ sind, könnten wirpacksswb mm1, mm0 nicht negativ vorzeichenbehaftete Bytes in den oberen 4 Bytes von erzeugen mm1, wodurch die Notwendigkeit von andAfter vermieden wird pmovmskb. Also 24 Bytes.

Das x86-Paket mit vorzeichenbehafteter Sättigung behandelt die Ein- und Ausgabe als vorzeichenbehaftet, sodass das Vorzeichenbit immer erhalten bleibt. ( https://www.felixcloutier.com/x86/packsswb:packssdw ). Unterhaltsame Tatsache: Das x86-Paket mit vorzeichenloser Sättigung behandelt die Eingabe weiterhin als signiert. Dies könnte der Grund sein, warum PACKUSDWerst SSE4.1 eingeführt wurde, während die anderen 3 Kombinationen von Größe und Signatur seit MMX / SSE2 existierten.


Oder mit 32-Bit-Ganzzahlen in einem XMM-Register (und pshufdanstelle von pshufw) würde jeder Befehl ein weiteres Präfixbyte benötigen, außer zum movmskpsErsetzen des Pakets / und. Aber pmaxsdich pmaxudbrauche ein zusätzliches Byte ...

aufrufbare von C alsunsigned max4_sse4(__m128i); mit x86-64 System V oder MSVC vectorcall ( -Gv), die beide passieren __m128i/ __m128d/ __m128args in XMM regs ab 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

Wenn wir Eingaben als akzeptieren float, können wir SSE1-Anweisungen verwenden. Das floatFormat kann einen weiten Bereich von ganzzahligen Werten darstellen ...

Oder wenn Sie der Meinung sind, dass dies die Regeln zu weit biegt, beginnen Sie mit einem 3-Byte- 0F 5B C0 cvtdq2ps xmm0, xmm0Konvertierungsprogramm, das eine 27-Byte-Funktion erstellt, die für alle Ganzzahlen funktioniert, die genau als IEEE-Binär32 dargestellt werden können float, sowie für viele Kombinationen von Eingaben, bei denen einige der Eingaben erhalten werden gerundet auf ein Vielfaches von 2, 4, 8 oder was auch immer während der Konvertierung. (Es ist also 1 Byte kleiner als die SSE4.1-Version und funktioniert auf jedem x86-64 mit nur SSE2.)

Wenn einer der Float-Eingänge NaN ist, beachten Sie, dass maxps a,bgenau implementiert (a<b) ? a : bwird und das Element aus dem 2. Operanden ungeordnet bleibt . Es kann also möglich sein, dass dies mit einer Bitmap ungleich Null zurückkehrt, selbst wenn die Eingabe etwas NaN enthält, je nachdem, wo sie sich befinden.

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

Kopieren und Mischen mit pshufdist immer noch unsere beste Wahl: shufps dst,src,imm8Liest die Eingabe für die untere Hälfte von dst von dst . Und wir brauchen beide Male ein zerstörungsfreies Kopieren und Mischen, also sind 3-Byte movhlpsund unpckhps/ pd beide aus. Wenn wir uns auf ein skalares Maximum beschränken würden, könnten wir diese verwenden, aber es kostet eine weitere Anweisung, vor dem Vergleich zu senden, wenn wir das Maximum nicht in allen Elementen bereits haben.


Verwandte: SSE4.1 phminposuwkann die Position und den Wert des Minimums uint16_tin einem XMM-Register finden. Ich denke nicht, dass es ein Gewinn ist, von 65535 zu subtrahieren, um es für max zu verwenden, aber siehe eine SO-Antwort über die Verwendung für max von Bytes oder vorzeichenbehafteten ganzen Zahlen.


1

Python 3.8 (Vorabversion) , 67 Bytes

Die Lambda-Funktion, die 4 Ganzzahlen akzeptiert, verschiebt das boolesche Ergebnis ihres Vergleichs mit Hilfe des neuen Zuweisungsoperators von Python 3.8 auf den Maximalwert und gibt das bitweise ODER der Ergebnisse zurück

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

Probieren Sie es online aus!


: = erinnert mich an die alten Zeiten, als das der Zuweisungsoperator mit der Lotus Notes-Formel war. Ich
schätze,



1

JavaScript (ES6), 30 Byte

Nimmt Eingabe als ([d,c,b,a]). Gibt 4 Boolesche Werte zurück.

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

Probieren Sie es online aus!


1
OP hat klargestellt, dass Sie tatsächlich 4 Boolesche Werte zurückgeben können.
Adám


1

Python 3 , 59 Bytes 66 Bytes

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

Probieren Sie es online aus!

Nimmt die Eingabe als [a,b,c,d]und gibt eine Liste von Booleschen Werten aus.

Bearbeitet, um eine ordnungsgemäße Funktion zu sein, und dann 2 Byte gespeichert, indem Klammern um die Bedingung entfernt werden.


1
Hallo und willkommen bei PPCG. So wie es aussieht, hat Ihre Antwort die Form eines Ausschnitts, der nicht zulässig ist. Bitte korrigieren Sie Ihre Antwort so, dass sie unserem E / A-Konsens entspricht , dh machen Sie sie zu einer Funktion oder einem vollständigen Programm.
Jonathan Frech

1
Bearbeitet. Zum ersten Mal. Schätzen Sie die Köpfe hoch!
Bsoned

Mit diesem Listenverständnis innerhalb eines Lambdas können Sie es auf 37 Byte reduzieren . Willkommen bei PPCG und genießen Sie Ihren Aufenthalt!
Wert Tinte

@ValueInk Durch Entfernen des überflüssigen Leerzeichens wird noch ein weiteres Byte gespeichert.
Jonathan Frech

1

1. Python 3.5, 90 Bytes

Nimmt die Folge von Zahlen als Parameter. Gibt "binäre" Zeichenfolge zurück

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

Beispiel:

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

Erläuterung

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 # (Visual C # Interactive Compiler) , 26 Byte

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

Probieren Sie es online aus!

Nimmt Eingaben im Format vor [d,c,b,a]. Alle anderen unten nehmen Eingaben als[a,b,c,d]

C # (Visual C # Interactive Compiler) , 35 Byte

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

Gibt ein zurück IEnumerable<bool>.

Probieren Sie es online aus!

C # (Visual C # Interactive Compiler) , 39 Byte

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

Gibt ein zurück IEnumerable<int>, das Bits darstellt.

Probieren Sie es online aus!

C # (Visual C # Interactive Compiler) , 49 Byte

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

Druckt eine Binärzeichenfolge nach STDOUT.

Probieren Sie es online aus!


IEnumerable<bool> ist akzeptabel.
Adám

0

PHP, 54 Bytes

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

oder

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

Nehmen Sie Eingaben von Befehlszeilenargumenten entgegen. Laufen Sie mit -nroder probieren Sie sie online aus .


0

Hier ist eine JS-Version, die als Binärdatei ausgegeben wird

Update: Kürzer mit Join und ohne Lookup:

JavaScript (Node.js) , 42 Byte

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

Probieren Sie es online aus!

Vorherige, mit Nachschlagen, 49 Bytes

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

Probieren Sie es online aus!

Zurück, mit reduzieren, 52 Bytes:

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

Probieren Sie es online aus!

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 scheint jetzt offensichtlich. Vielen Dank!
Pureferret

0

C # (Visual C # Interactive Compiler) , 51 Byte

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

Probieren Sie es online aus!

Oben ist eine anonyme Funktion, die durch Ändern eines Arguments ausgegeben wird . Die Ausgabe ist ein Array von Einsen und Nullen.

Unten finden Sie eine rekursive Funktion, die eine Ganzzahl ausgibt.

C # (Visual C # Interactive Compiler) , 60 Byte

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

Probieren Sie es online aus!

Beide Funktionen werden als 4-Element-Array eingegeben.

[d, c, b, a]

Sie müssen keine Ganzzahl ausgeben.
Adám

@Adam - danke :) Ich habe das nach dem Posten bemerkt, als ich an meiner anderen Antwort gearbeitet habe. Bevor ich mich ändern konnte, gab es eine weitere C # -Antwort, die viele der guten Tricks verwendete.
Dana



0

Stapel, 92 Bytes

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

Nimmt Argumente als Befehlszeilenparameter in umgekehrter Reihenfolge. Funktioniert durch arithmetisches Berechnen des Maximums der Parameter, indem diese reduziert und nur positive Unterschiede zum laufenden Maximum addiert werden. Anschließend wird jeder Parameter erneut zugeordnet und diesmal mit dem Maximum verglichen. Praktischerweise cmd/cset/awird keine neue Zeile ausgegeben, sodass die Ergebnisse automatisch miteinander verknüpft werden. Das %f%spart einfach 5 Bytes bei einem wiederholten Konstrukt.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.