Bandingkan empat bilangan bulat, kembalikan kata berdasarkan maksimum


9

Fungsi ini harus mengambil empat input bilangan bulat ( a, b, c, d) dan kembali kata biner berdasarkan yang nilai sama dengan maksimum empat.

Nilai pengembalian akan berada di antara 1dan 0xF.

Sebagai contoh:

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

mengembalikan 2(biner 0010; hanya bit terkecil ke-2 yang disetel untuk bmenjadi satu-satunya nilai maks)

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

mengembalikan 0xC(biner 1100; bit signifikan ke-3 dan ke-4 ditetapkan sesuai dengan cdan dmenyamai nilai maks)

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

mengembalikan 0xF(biner 1111; keempat bit diatur karena semua nilai sama dengan maks)

Berikut ini adalah implementasi sederhana:

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

nilai kembali dapat berupa string 0's dan 1's, bool / bit vector, atau integer


2
Saya punya solusi dalam bahasa golf, yang menggunakan bawaan Reverse, Maximum, Equality-check, Gabung, Konversi dari biner ke integer, Konversi dari integer ke heksadesimal. Apakah ini berarti skor saya adalah 1 karena pemeriksaan Kesetaraan? Saya merasa ini terlalu fokus pada bahasa reguler, dan bahkan bagi mereka yang tidak 100% jelas untuk skor apa katakanlah sebuah Maksimum-builtin ..: S
Kevin Cruijssen

1
Saya sarankan Anda mencoba untuk: 1. mengubah pertanyaan ini ke kode-golf, yang hanya peduli tentang jumlah byte. 2. atau, batasi untuk beberapa bahasa tertentu (tolong minta versi / kompiler / penerjemah tertentu), dan daftarkan semua pernyataan dan operator yang diizinkan, dan bagaimana cara menilai mereka.
tsh

5
1 adalah opsi yang lebih baik, IMO. Saya pikir ini membuat pertanyaan kode-golf yang sangat baik dan saya tidak dapat melihat manfaat apa pun yang akan datang dari membatasi bahasa yang tersedia untuk jawaban
senox13

2
Saya memperbarui pertanyaan saya untuk menghapus kriteria. Beri tahu saya, masih belum jelas
Tn. Anderson

5
Haruskah saya mengeluarkan angka desimal? Atau bolehkah saya menghasilkan 4 digit biner?
tsh

Jawaban:


8

Jelly , 2 byte

Mengambil input sebagai [d,c,b,a]. Mengembalikan daftar Boolean.

Ṁ=

Cobalah online!

M aximum

= sama dengan (menyiratkan argumen lain adalah argumen asli; vectorises)


5

R , 17 byte

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

Cobalah online!

Mengembalikan vektor boolean. Karena output ini telah dikonfirmasi, ini lebih disukai daripada output numerik, karena yang hampir dua kali lebih lama:

R , 33 byte

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

Cobalah online!


4

APL (Dyalog Unicode) , 4 byte SBCS

Fungsi awalan diam-diam anonim. Dibawa [a,b,c,d]sebagai argumen. Mengembalikan array bit-Boolean. *

⌈/=⌽

Cobalah online!

⌈/ Apakah argumen maksimal

= sama dengan (vektorisasi)

 kebalikan dari argumen?

* Perhatikan bahwa APL menyimpan array Boolean menggunakan satu bit per nilai, jadi ini memang mengembalikan kata 4-bit, meskipun bentuk tampilannya sedang 0 0 1 0.



2

Perl 6 , 12 byte

{$_ X==.max}

Cobalah online!

Blok kode anonim yang mengambil daftar bilangan bulat dan mengembalikan daftar boolean. Jika kita perlu kembali sebagai angka, +4 byte untuk membungkus bagian dalam blok kode 2:[...].

Penjelasan:

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

OP sekarang mengatakan Anda tidak perlu membungkus.
Adám

2

Japt, 5

m¶Urw

Cobalah!

-4 byte terima kasih kepada @Oliver!
-2 byte terima kasih kepada @Shaggy!

Input adalah array 4-elemen dalam format berikut:

[d, c, b, a]

Output adalah array bit.


Tentu saja ada;) Tampaknya ada banyak jalan pintas untuk dipelajari.
dana

Jika array boolean merupakan output yang dapat diterima, ini bisa 7 byte
Oliver

@ Lebih Tua, 5 byte ;)
Shaggy

Kalian cukup bagus :) Itu menarik bagaimana rwmengkonversi r("w")menjadi mengurangi dengan berulang kali mendapatkan maks. Sama dengan dikonversi menjadi U.m("===", ...). Bagaimanapun, terima kasih atas tipsnya!
dana

2

kode mesin x86 (MMX / SSE1), 26 byte (4x int16_t)

kode mesin x86 (SSE4.1), 28 byte (4x int32_t atau uint32_t)

kode mesin x86 (SSE2), 24 byte (4x float32) atau 27B ke cvt int32

(Versi terakhir yang mengonversi int32 ke float tidak sepenuhnya akurat untuk bilangan bulat besar yang bulat ke float yang sama. Dengan input float, pembulatan adalah masalah pemanggil dan fungsi ini berfungsi dengan benar jika tidak ada NaN, mengidentifikasi float yang membandingkan == maks. Versi integer bekerja untuk semua input, memperlakukannya sebagai pelengkap yang ditandatangani 2).

Semua ini bekerja dalam mode 16/32/64-bit dengan kode mesin yang sama.

Konvensi pemanggilan stack-args akan memungkinkan untuk mengulang argumen dua kali (menemukan maks dan kemudian membandingkan), mungkin memberi kami implementasi yang lebih kecil, tetapi saya belum mencoba pendekatan itu.

x86 SIMD memiliki bitmap vektor-> integer sebagai instruksi tunggal ( pmovmskbatau movmskpspd), jadi itu wajar untuk ini meskipun instruksi MMX / SSE setidaknya sepanjang 3 byte. Instruksi SSSE3 dan yang lebih baru lebih panjang dari pada SSE2, dan instruksi MMX / SSE1 adalah yang terpendek. Versi berbeda pmax*(packed-integer vertical max) diperkenalkan pada waktu yang berbeda, dengan SSE1 (untuk mmx regs) dan SSE2 (untuk xmm regs) hanya memiliki kata yang ditandatangani (16-bit) dan byte yang tidak ditandatangani.

( pshufwdan pmaxswpada register MMX masih baru dengan Katmai Pentium III, jadi mereka benar-benar membutuhkan SSE1, bukan hanya fitur CPU MMX.)

Ini bisa dipanggil dari C seperti unsigned max4_mmx(__m64)halnya i386 System V ABI, yang meneruskan __m64argumen in mm0. (Tidak x86-64 Sistem V, yang melewati __m64di 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

Jika ada pmovmskw, apa yang akan menyelamatkan packsswbdan and(3 + 2 byte). Kami tidak perlu and eax, 0x0fkarena pmovmskbpada register MMX sudah nol byte atas. Register MMX hanya memiliki lebar 8 byte, jadi 8-bit AL mencakup semua bit yang tidak nol.

Jika kita tahu input kita non-negatif, kita bisapacksswb mm1, mm0 menghasilkan byte yang ditandatangani non-negatif di atas 4 byte mm1, menghindari kebutuhan untuk andsetelah pmovmskb. Jadi 24 byte.

paket x86 dengan saturasi yang telah ditandatangani memperlakukan input dan output sebagai yang ditandatangani, sehingga selalu mempertahankan bit tanda. ( https://www.felixcloutier.com/x86/packsswb:packssdw ). Fakta menyenangkan: paket x86 dengan saturasi yang tidak ditandatangani masih memperlakukan input yang ditandatangani. Ini mungkin mengapa PACKUSDWtidak diperkenalkan sampai SSE4.1, sementara 3 kombinasi ukuran dan signness lainnya ada sejak MMX / SSE2.


Atau dengan bilangan bulat 32-bit dalam register XMM (dan pshufdbukannya pshufw), setiap instruksi akan membutuhkan satu byte awalan lagi, kecuali untuk movmskpsmengganti paket / dan. Tapi pmaxsd/ pmaxudmembutuhkan byte tambahan ekstra ...

callable dari C sebagaiunsigned max4_sse4(__m128i); dengan x86-64 System V, atau MSVC vectorcall ( -Gv), yang keduanya lulus __m128i/ __m128d/ __m128args di regs XMM dimulai dengan 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

Atau jika kami menerima input float, kami dapat menggunakan instruksi SSE1. The floatFormat dapat mewakili berbagai nilai integer ...

Atau jika Anda berpikir bahwa membengkokkan aturan terlalu jauh, mulailah dengan 3-byte 0F 5B C0 cvtdq2ps xmm0, xmm0untuk dikonversi, membuat fungsi 27-byte yang bekerja untuk semua bilangan bulat yang benar-benar mewakili IEEE binary32 float, dan banyak kombinasi input di mana beberapa input mendapatkan dibulatkan menjadi kelipatan 2, 4, 8, atau apa pun selama konversi. (Jadi 1 byte lebih kecil dari versi SSE4.1, dan bekerja pada x86-64 apa saja hanya dengan SSE2.)

Jika salah satu dari input float adalah NaN, perhatikan bahwa maxps a,bmengimplementasikan dengan tepat (a<b) ? a : b, menjaga elemen dari operan ke-2 pada unordered . Jadi dimungkinkan untuk kembali dengan bitmap yang tidak nol bahkan jika inputnya mengandung beberapa NaN, tergantung di mana bitmap itu berada.

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

salin-dan-kocok dengan pshufdmasih taruhan terbaik kami: shufps dst,src,imm8membaca input dari setengah rendah dst dari dst . Dan kita perlu copy-and-shuffle non-destruktif kedua kali, sehingga 3-byte movhlpsdan unpckhps/ pd keduanya keluar. Jika kita mempersempit ke skalar maks, kita bisa menggunakan itu, tetapi membutuhkan instruksi lain untuk disiarkan sebelum membandingkan jika kita belum memiliki maks dalam semua elemen.


Terkait: SSE4.1 phminposuwdapat menemukan posisi dan nilai minimum uint16_tdalam register XMM. Saya tidak berpikir itu menang untuk mengurangi dari 65.535 untuk menggunakannya untuk maks, tetapi lihat jawaban SO tentang menggunakannya untuk maks byte atau bilangan bulat yang ditandatangani.


1

Python 3.8 (pra-rilis) , 67 byte

Fungsi Lambda yang mengambil dalam 4 bilangan bulat, bit menggeser hasil boolean dari perbandingan mereka ke nilai maksimum dengan bantuan dari operator penugasan baru Python 3.8 , dan mengembalikan bitwise ATAU dari hasil

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

Cobalah online!


: = mengingatkan saya pada masa lalu di mana itu adalah operator penugasan dengan rumus Lotus Notes. Kira saya harus melihat pada 3,8 untuk masa lalu :)
ElPedro



1

JavaScript (ES6), 30 byte

Mengambil input sebagai ([d,c,b,a]). Mengembalikan 4 nilai Boolean.

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

Cobalah online!


1
OP telah mengklarifikasi bahwa Anda memang dapat mengembalikan 4 nilai Boolean.
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]

Cobalah online!

Mengambil input sebagai [a,b,c,d]dan menampilkan daftar boolean.

Diedit menjadi fungsi yang tepat, kemudian disimpan 2 byte dengan menghapus tanda kurung di sekitar bersyarat.


1
Halo dan selamat datang di PPCG. Seperti berdiri, jawaban Anda memiliki bentuk potongan, yang tidak diizinkan. Harap perbaiki jawaban Anda agar sesuai dengan konsensus I / O kami , yaitu menjadikannya fungsi atau program penuh.
Jonathan Frech

1
Diedit. Pertama kali. Hargai kepala!
Bsoned

Anda bisa menguranginya menjadi 37 byte menggunakan pemahaman daftar ini dalam lambda. Selamat datang di PPCG, dan nikmati masa tinggal Anda!
Nilai Tinta

@ValueInk Menghapus spasi kosong yang berlebihan akan menghemat byte lain.
Jonathan Frech

1

1. Python 3.5, 90 byte

Mengambil urutan angka sebagai parameter. Mengembalikan string "biner"

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

contoh:

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

Penjelasan

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())

Cobalah online!

Mengambil input dalam format [d,c,b,a]. Semua yang lain di bawah mengambil input sebagai[a,b,c,d]

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

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

Mengembalikan sebuah IEnumerable<bool>.

Cobalah online!

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

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

Mengembalikan IEnumerable<int>, yang mewakili bit.

Cobalah online!

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

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

Mencetak string biner ke STDOUT.

Cobalah online!


IEnumerable<bool> bisa diterima.
Adám

0

PHP, 54 byte

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

atau

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

mengambil input dari argumen baris perintah. Jalankan dengan -nratau coba online .


0

Berikut adalah versi JS yang ditampilkan sebagai biner

pembaruan: Lebih pendek dengan bergabung, dan tanpa pencarian:

JavaScript (Node.js) , 42 byte

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

Cobalah online!

Sebelumnya, dengan pencarian, 49 byte

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

Cobalah online!

Sebelumnya, dengan pengurangan, 52 byte:

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

Cobalah 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 sepertinya sudah jelas sekarang. Terima kasih!
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;}

Cobalah online!

Di atas adalah fungsi anonim yang menghasilkan dengan mengubah argumen . Output adalah array dari 1 dan 0.

Di bawah ini adalah fungsi rekursif yang menghasilkan bilangan bulat.

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

Cobalah online!

Kedua fungsi mengambil input sebagai array 4-elemen.

[d, c, b, a]

Anda tidak perlu mengeluarkan bilangan bulat.
Adám

@ Adam - terima kasih :) Saya menyadari ini setelah memposting ketika saya sedang mengerjakan jawaban saya yang lain. Sebelum saya punya kesempatan untuk berubah, ada jawaban C # lain yang menggunakan banyak trik bagus.
dana

0

Python 2 , 35 byte

lambda i:[int(x==max(i))for x in i]

Cobalah online!

Mengambil input dalam format [d, c, b, a] seperti dengan jawaban yang diterima dari Adm jadi saya kira tidak apa-apa.

Alternatif untuk 41 jika tidak ...

Python 2 , 41 byte

lambda i:[int(x==max(i))for x in i][::-1]

Cobalah online!


0

Python 3 , 42 byte

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

Cukup mengembalikan daftar apakah elemen tersebut adalah maks untuk setiap elemen dalam input. -2 byte jika Anda tidak menghitung f=tugas.

Cobalah online!


f=tidak dihitung kecuali dalam fungsi rekursif
ASCII-satunya

0

Batch, 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)

Mengambil argumen sebagai parameter baris perintah dalam urutan terbalik. Bekerja dengan menghitung secara hitung parameter maksimum dengan mengurangi parameternya dan menambahkan hanya perbedaan positif dari running maksimum, kemudian memetakan setiap parameter lagi kali ini membandingkannya dengan maksimum. Mudah cmd/cset/atidak menampilkan baris baru, sehingga hasilnya secara otomatis digabungkan bersama. The %f%hanya menghemat 5 byte pada apa yang akan menjadi sebuah konstruksi berulang.

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.