Porównaj cztery liczby całkowite, zwracaj słowo w oparciu o maksimum


9

Funkcja ta powinna wziąć cztery wejścia Integer ( a, b, c, d) i powrócić binarne słowo na podstawie których wartości są równe maksymalnie cztery.

Wartość zwracana będzie pomiędzy 1a 0xF.

Na przykład:

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

zwraca 2(binarny 0010; ustawiony jest tylko 2. bit o znaczeniu najmniejszym odpowiadający bjedynej maksymalnej wartości)

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

zwraca 0xC(binarny 1100; trzeci i czwarty najmniej znaczący zestaw bitów odpowiadający ci drówny wartości maksymalnej)

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

zwraca 0xF(binarny 1111; wszystkie cztery bity ustawione, ponieważ wszystkie wartości są równe maksimum)

Oto prosta implementacja:

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

wartością zwracaną może być ciąg zer i jedynek, wektor bool / bit lub liczba całkowita


2
Mam rozwiązanie w języku golfowym, które wykorzystuje wbudowane funkcje Reverse, Maximum, Equality-check, Join, Convert from binary to integer, Convert from integer to hexadecimal. Czy to oznacza, że ​​mój wynik to 1 ze względu na kontrolę równości? Mam wrażenie, że jest to zbytnio skoncentrowane na zwykłych językach, a nawet dla tych nie jest w 100% jasne, co punktacja powiedzmy dla maksymalnej wbudowanej ..: S
Kevin Cruijssen

1
Sugeruję, abyś spróbował: 1. zmienić to pytanie na kod-golf, który dba tylko o liczbę bajtów. 2. lub ogranicz się do określonego języka (proszę poproszę o pewną wersję kompilatora / tłumacza) i wypisz wszystkie dozwolone instrukcje i operatory oraz sposób ich oceny.
tsh

5
1 jest lepszą opcją, IMO. Myślę, że jest to doskonale dobre pytanie do gry w golfa i nie widzę żadnej korzyści, jaką przyniosłoby ograniczenie języków dostępnych dla odpowiedzi
senox13,

2
Zaktualizowałem moje pytanie, aby usunąć kryteria. Daj mi znać, że nadal nie jest jasne
Pan Anderson

5
Czy powinienem podać liczbę dziesiętną? Czy mogę zamiast tego wypisać 4 cyfry binarne?
tsh

Odpowiedzi:


8

Galaretka , 2 bajty

Pobiera dane wejściowe jako [d,c,b,a]. Zwraca listę wartości logicznych.

Ṁ=

Wypróbuj online!

M aximum

= równa (implikuje, że drugi argument jest argumentem oryginalnym; wektoryzacja)


5

R , 17 bajtów

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

Wypróbuj online!

Zwraca wektor wartości logicznych. Ponieważ to wyjście zostało potwierdzone, jest to lepsze niż wyjście numeryczne, ponieważ jest ono prawie dwa razy dłuższe:

R , 33 bajty

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

Wypróbuj online!


4

APL (Dyalog Unicode) , 4 bajty SBCS

Anonimowa ukryta funkcja prefiksu. Bierze się [a,b,c,d]za argument. Zwraca tablicę bitów logicznych. *

⌈/=⌽

Wypróbuj online!

⌈/ Czy maksimum argumentu

= równe (wektoryzacja)

 odwrotność argumentu?

* Zauważ, że APL przechowuje tablice booleanów przy użyciu jednego bitu na wartość, więc to rzeczywiście zwraca 4-bitowe słowo, pomimo że jest wyświetlany 0 0 1 0.



2

Perl 6 , 12 bajtów

{$_ X==.max}

Wypróbuj online!

Anonimowy blok kodu, który pobiera listę liczb całkowitych i zwraca listę wartości logicznych. Jeśli musimy zwrócić jako liczbę, to +4 bajty, aby owinąć wnętrze bloku kodu 2:[...].

Wyjaśnienie:

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

OP mówi teraz, że nie musisz owijać.
Adám

2

Japt, 5

m¶Urw

Spróbuj!

-4 bajty dzięki @Oliver!
-2 bajty dzięki @Shaggy!

Dane wejściowe to tablica 4-elementowa w następującym formacie:

[d, c, b, a]

Dane wyjściowe to tablica bitów.


Oczywiście, że tak;) Najwyraźniej jest wiele skrótów do nauki.
dana

Jeśli tablica boolowska jest akceptowalnym wyjściem, może to być 7 bajtów
Oliver

@Oliver, 5 bajtów ;)
Shaggy

Jesteście całkiem dobrzy :) To ciekawe, jak rwkonwertuje na r("w")redukuje, wielokrotnie otrzymując maks. To samo dotyczy konwersji do U.m("===", ...). W każdym razie dzięki za wskazówki!
dana

2

kod maszynowy x86 (MMX / SSE1), 26 bajtów (4x int16_t)

kod maszynowy x86 (SSE4.1), 28 bajtów (4x int32_t lub uint32_t)

kod maszynowy x86 (SSE2), 24 bajty (4x float32) lub 27B na cvt int32

(Ostatnia wersja, która konwertuje int32 na liczbę zmiennoprzecinkową, nie jest idealnie dokładna dla dużych liczb całkowitych, które zaokrąglają do tej samej liczby zmiennoprzecinkowej. Przy wprowadzaniu liczby zmiennoprzecinkowej zaokrąglanie jest problemem osoby wywołującej, a funkcja ta działa poprawnie, jeśli nie ma NaN, identyfikując liczby zmiennoprzecinkowe, które = maksymalnie. Wersje całkowite działają dla wszystkich danych wejściowych, traktując je jak uzupełnienie ze znakiem 2).

Wszystkie działają w trybie 16/32/64-bit z tym samym kodem maszynowym.

Konwencja wywoływania stosu-argumentów umożliwia dwukrotne zapętlenie argumentów (znalezienie maksimum, a następnie porównanie), co może dać nam mniejszą implementację, ale nie próbowałem tego podejścia.

SIM86 x86 ma bitmapę wektor-> liczba całkowita jako pojedynczą instrukcję ( pmovmskblub movmskpspd), więc było to naturalne, mimo że instrukcje MMX / SSE mają co najmniej 3 bajty. Instrukcje SSSE3 i nowsze są dłuższe niż SSE2, a instrukcje MMX / SSE1 są najkrótsze. Różne wersje pmax*(maksymalne upakowane pionowe maksimum) zostały wprowadzone w różnym czasie, przy czym SSE1 (dla rejestrów mmx) i SSE2 (dla rejestrów xmm) miały tylko podpisane słowo (16-bit) i bajt bez znaku.

( pshufwI pmaxswna MMX rejestry są nowe z Pentium III Katmai, tak naprawdę wymagają one SSE1, a nie tylko funkcji bitowy procesor MMX).

Można to wywołać z poziomu C, podobnie jak unsigned max4_mmx(__m64)w systemie ABI systemu i386 V, który przekazuje __m64argument mm0. (Nie x86-64 System V, który przechodzi __m64w 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

Gdyby istniał pmovmskw, co zaoszczędziłoby packsswbi and(3 + 2 bajty). Nie potrzebujemy, and eax, 0x0fponieważ pmovmskbw rejestrze MMX już zeruje górne bajty. Rejestry MMX mają tylko 8 bajtów szerokości, więc 8-bitowy AL obejmuje wszystkie możliwe niezerowe bity.

Gdybyśmy wiedzieli, że nasze dane wejściowe są nieujemne, moglibyśmypacksswb mm1, mm0 wygenerować nieujemne bajty ze znakiem w górnych 4 bajtach mm1, unikając potrzeby andpóźniejszego pmovmskb. Zatem 24 bajty.

Pakiet x86 z podpisanym nasyceniem traktuje wejście i wyjście jako podpisane, więc zawsze zachowuje bit znaku. ( https://www.felixcloutier.com/x86/packsswb:packssdw ). Ciekawostka: pakiet x86 z niepodpisanym nasyceniem nadal traktuje dane wejściowe jako podpisane. Być może dlatego PACKUSDWzostał wprowadzony dopiero w SSE4.1, podczas gdy pozostałe 3 kombinacje rozmiaru i podpisu istniały od MMX / SSE2.


Lub z 32-bitowymi liczbami całkowitymi w rejestrze XMM (i pshufdzamiast pshufw) każda instrukcja wymagałaby jeszcze jednego bajtu prefiksu, z wyjątkiem movmskpszastąpienia pack / i. Ale pmaxsd/ pmaxudpotrzebujesz dodatkowego dodatkowego bajtu ...

wywoływalne z C jakunsigned max4_sse4(__m128i); w x86-64 System V lub MSVC vectorcall ( -Gv), z których oba przekazują __m128i/ __m128d/ __m128args w regach XMM, zaczynając od 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

Lub jeśli zaakceptujemy dane wejściowe jako float, możemy użyć instrukcji SSE1. floatFormat może reprezentować szeroki zakres liczb całkowitych ...

Lub jeśli uważasz, że to wygina reguły zbyt daleko, zacznij od 3-bajtowego 0F 5B C0 cvtdq2ps xmm0, xmm0do konwersji, tworząc 27-bajtową funkcję, która działa dla wszystkich liczb całkowitych, które są dokładnie reprezentowane jako binarne IEEE32 float, oraz dla wielu kombinacji danych wejściowych, do których trafiają niektóre dane wejściowe zaokrąglona do wielokrotności 2, 4, 8 lub dowolnej innej wartości podczas konwersji. (Więc jest o 1 bajt mniejszy niż wersja SSE4.1 i działa na każdym x86-64 z tylko SSE2.)

Jeśli którekolwiek z danych zmiennoprzecinkowych to NaN, zauważ, że maxps a,bdokładnie to implementuje (a<b) ? a : b, utrzymując element z drugiego argumentu na nieuporządkowanym . Może więc być możliwe zwrócenie z niezerową bitmapą, nawet jeśli wejście zawiera trochę NaN, w zależności od tego, gdzie się znajdują.

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

kopiowanie i tasowanie pshufdjest nadal naszym najlepszym wyborem: shufps dst,src,imm8odczytuje dane wejściowe dla dolnej połowy dst z dst . I potrzebujemy nieniszczącego kopiowania i tasowania za każdym razem, więc 3-bajtowe movhlpsi unpckhps/ pd są wyłączone. Gdybyśmy zawężali do skalarnego maksimum, moglibyśmy je wykorzystać, ale kosztuje to kolejną instrukcję do nadania przed porównaniem, jeśli nie mamy jeszcze maksimum we wszystkich elementach.


Powiązane: SSE4.1 phminposuwmoże znaleźć pozycję i wartość minimum uint16_tw rejestrze XMM. Nie sądzę, aby wygrywanie odejmowało od 65535, aby używać go dla maksimum, ale zobacz odpowiedź SO na temat używania go dla maks. Bajtów lub liczb całkowitych ze znakiem.


1

Python 3.8 (wersja wstępna) , 67 bajtów

Funkcja Lambda, która przyjmuje 4 liczby całkowite, bit przesuwa wynik boolean ich porównania do wartości maksymalnej z pewną pomocą nowego operatora przypisania Pythona 3.8 i zwraca bitową OR wyników

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

Wypróbuj online!


: = przypomina mi dawne czasy, w których był to operator przypisania z formułą Lotus Notes. Chyba będę musiał
rzucić



1

JavaScript (ES6), 30 bajtów

Pobiera dane wejściowe jako ([d,c,b,a]). Zwraca 4 wartości logiczne.

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

Wypróbuj online!


1
OP wyjaśnił, że rzeczywiście można zwrócić 4 wartości logiczne.
Adám


1

Python 3 , 59 bajtów 66 bajtów

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

Wypróbuj online!

Pobiera dane wejściowe jako [a,b,c,d]i wyświetla listę wartości logicznych.

Edytowano, aby była poprawną funkcją, a następnie zapisano 2 bajty, usuwając nawiasy wokół warunku.


1
Witam i witam w PPCG. Na obecnym etapie twoja odpowiedź ma postać krótkiego fragmentu, który jest niedozwolony. Popraw swoją odpowiedź, aby była zgodna z naszym konsensu We / Wy , tj. Uczynić z niej funkcję lub pełny program.
Jonathan Frech,

1
Edytowane. Pierwszy raz w okolicy. Doceń głowy!
Bsoned

Możesz zmniejszyć go do 37 bajtów, korzystając z tej listy w lambda. Witamy w PPCG i życzymy udanego pobytu!
Wartość tuszu

@ValueInk Usunięcie zbędnych białych znaków oszczędza kolejny bajt.
Jonathan Frech,

1

1. Python 3.5, 90 bajtów

Przyjmuje ciąg liczb jako parametry. Zwraca ciąg „binarny”

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

przykład:

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

Wyjaśnienie

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 # (interaktywny kompilator Visual C #) , 26 bajtów

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

Wypróbuj online!

Pobiera dane wejściowe w formacie [d,c,b,a]. Wszystkie pozostałe poniżej przyjmują dane jako[a,b,c,d]

C # (interaktywny kompilator Visual C #) , 35 bajtów

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

Zwraca an IEnumerable<bool>.

Wypróbuj online!

C # (interaktywny kompilator Visual C #) , 39 bajtów

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

Zwraca an IEnumerable<int>, które reprezentują bity.

Wypróbuj online!

C # (interaktywny kompilator Visual C #) , 49 bajtów

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

Drukuje ciąg binarny do STDOUT.

Wypróbuj online!


IEnumerable<bool> jest do przyjęcia.
Adám

0

PHP, 54 bajty

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

lub

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

pobrać dane wejściowe z argumentów wiersza poleceń. Uruchom je -nrlub wypróbuj online .


0

Oto wersja JS, która generuje dane binarne

aktualizacja: Krótsza z łączeniem i bez wyszukiwania:

JavaScript (Node.js) , 42 bajty

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

Wypróbuj online!

Poprzednio, z wyszukiwaniem, 49 bajtów

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

Wypróbuj online!

Poprzednio, ze zmniejszeniem, 52 bajty:

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

Wypróbuj 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
Możesz bezpiecznie usunąć, [0,1][...]ponieważ używasz już istniejącego indeksu0 lub 1.
Arnauld

@Arnauld wydaje się teraz oczywisty. Dzięki!
Pureferret,

0

C # (interaktywny kompilator Visual C #) , 51 bajtów

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

Wypróbuj online!

Powyżej znajduje się anonimowa funkcja, która generuje dane poprzez modyfikację argumentu . Dane wyjściowe to tablica 1 i 0.

Poniżej znajduje się funkcja rekurencyjna, która wypisuje liczbę całkowitą.

C # (interaktywny kompilator Visual C #) , 60 bajtów

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

Wypróbuj online!

Obie funkcje przyjmują dane wejściowe jako tablicę 4-elementową.

[d, c, b, a]

Nie musisz podawać liczby całkowitej.
Adám

@Adam - dzięki :) Zrozumiałem to po opublikowaniu, gdy pracowałem nad drugą odpowiedzią. Zanim miałem szansę się zmienić, pojawiła się kolejna odpowiedź w języku C #, która wykorzystywała wiele dobrych sztuczek.
dana


0

Python 3 , 42 bajty

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

Po prostu zwraca listę, czy element jest wartością maksymalną dla każdego elementu na wejściu. -2 bajty, jeśli nie policzyszf= zadania.

Wypróbuj online!


f=nie liczy się, z wyjątkiem funkcji rekurencyjnych
tylko ASCII

0

Partia, 92 bajty

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

Pobiera argumenty jako parametry wiersza polecenia w odwrotnej kolejności. Działa poprzez arytmetyczne obliczenie maksimum parametrów przez zmniejszenie ich i dodanie tylko dodatnich różnic od działającego maksimum, a następnie ponowne mapowanie każdego parametru, tym razem porównując go z maksimum. Dogodnie cmd/cset/anie generuje nowego wiersza, więc wyniki są automatycznie łączone razem. Po %f%prostu oszczędza 5 bajtów na tym, co byłoby powtarzaną konstrukcją.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.