So sánh bốn số nguyên, trả về từ dựa trên tối đa


9

Chức năng này nên mất bốn đầu vào số nguyên ( a, b, c, d) và trả về một từ nhị phân trên cơ sở đó các giá trị tương đương với tối đa bốn.

Giá trị trả về sẽ nằm giữa 10xF.

Ví dụ:

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

trả về 2(nhị phân 0010; chỉ bit có ý nghĩa nhỏ thứ 2 được đặt tương ứng với bgiá trị tối đa duy nhất)

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

trả về 0xC(nhị phân 1100; các bit có ý nghĩa nhỏ nhất thứ 3 và thứ 4 được đặt tương ứng cdbằng với giá trị tối đa)

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

trả về 0xF(nhị phân 1111; tất cả bốn bit được đặt vì tất cả các giá trị bằng max)

Đây là một cách thực hiện đơn giản:

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

giá trị trả về có thể là chuỗi 0 và 1, vectơ bool / bit hoặc số nguyên


2
Tôi có một giải pháp trong ngôn ngữ chơi gôn, sử dụng các nội dung Reverse, Maximum, Equality-check, Tham gia, Chuyển đổi từ nhị phân sang số nguyên, Chuyển đổi từ số nguyên sang thập lục phân. Điều này có nghĩa là điểm của tôi là 1 do kiểm tra Bình đẳng? Tôi có cảm giác điều này tập trung quá nhiều vào các ngôn ngữ thông thường và ngay cả đối với những ngôn ngữ đó không rõ ràng 100% về điểm số cho giả sử Tối đa được xây dựng ..: S
Kevin Cruijssen

1
Tôi sẽ đề nghị bạn thử: 1. thay đổi câu hỏi này thành code-golf, chỉ quan tâm đến số lượng byte. 2. hoặc, hạn chế một số ngôn ngữ nhất định (vui lòng sử dụng phiên bản trình biên dịch / trình thông dịch nhất định) và liệt kê tất cả các câu lệnh và toán tử được phép và cách ghi điểm chúng.
tsh

5
1 là một lựa chọn tốt hơn, IMO. Tôi nghĩ rằng điều này tạo ra một câu hỏi golf mã hoàn toàn tốt và tôi không thể thấy bất kỳ lợi ích nào có được từ việc hạn chế các ngôn ngữ có sẵn cho câu trả lời
senox13

2
Tôi cập nhật câu hỏi của tôi để loại bỏ các tiêu chí. Hãy cho tôi biết điều đó vẫn chưa rõ ràng
Ông Anderson

5
Tôi có nên xuất một số thập phân? Hoặc tôi có thể xuất 4 chữ số nhị phân thay thế?
tsh

Câu trả lời:




4

APL (Dyalog Unicode) , 4 byte SBCS

Chức năng tiền tố ẩn danh. Đưa ra [a,b,c,d]như là đối số. Trả về mảng bit-Boolean. *

⌈/=⌽

Hãy thử trực tuyến!

⌈/ Có tối đa của đối số không

= bằng (vectơ)

 mặt trái của lập luận?

* Lưu ý rằng APL lưu trữ các mảng Booleans bằng cách sử dụng một bit cho mỗi giá trị, do đó, điều này thực sự trả về một từ 4 bit, mặc dù hình thức hiển thị là 0 0 1 0.



2

Perl 6 , 12 byte

{$_ X==.max}

Hãy thử trực tuyến!

Khối mã ẩn danh nhận danh sách các số nguyên và trả về danh sách các booleans. Nếu chúng ta cần trả về dưới dạng số, thì đó là +4 byte để bọc bên trong khối mã 2:[...].

Giải trình:

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

OP bây giờ nói rằng bạn không cần phải bọc.
Adám

2

Japt, 5

m¶Urw

Thử nó!

-4 byte nhờ @Oliver!
-2 byte nhờ @Shaggy!

Đầu vào là mảng 4 phần tử theo định dạng sau:

[d, c, b, a]

Đầu ra là một mảng các bit.


Tất nhiên là có;) Rõ ràng có rất nhiều phím tắt để học.
dana

Nếu một mảng boolean là một đầu ra chấp nhận được, thì đây có thể là 7 byte
Oliver

@Oliver, 5 byte ;)
Shaggy

Các bạn khá giỏi :) Thật thú vị khi rwchuyển đổi thành r("w")giảm bằng cách liên tục đạt tối đa. Tương tự với việc chuyển đổi thành U.m("===", ...). Trong mọi trường hợp, cảm ơn lời khuyên!
dana

2

Mã máy x86 (MMX / SSE1), 26 byte (4x int16_t)

Mã máy x86 (SSE4.1), 28 byte (4x int32_t hoặc uint32_t)

Mã máy x86 (SSE2), 24 byte (4x float32) hoặc 27B đến cvt int32

(Phiên bản cuối cùng chuyển đổi int32 thành float không hoàn toàn chính xác đối với các số nguyên lớn làm tròn thành cùng một float. Với đầu vào float, làm tròn là vấn đề của người gọi và chức năng này hoạt động chính xác nếu không có NaN, xác định số float so sánh == đến mức tối đa. Các phiên bản số nguyên hoạt động cho tất cả các đầu vào, coi chúng là phần bù 2 đã ký.)

Tất cả đều hoạt động ở chế độ 16/32/64-bit với cùng mã máy.

Một quy ước gọi stack-args sẽ cho phép lặp lại các đối số hai lần (tìm max và sau đó so sánh), có thể cho chúng ta thực hiện nhỏ hơn, nhưng tôi đã không thử cách tiếp cận đó.

x86 SIMD có vectơ-> bitmap nguyên như một lệnh đơn ( pmovmskbhoặc movmskpspd), do đó, điều này là tự nhiên mặc dù các lệnh MMX / SSE dài ít nhất 3 byte. SSSE3 và các hướng dẫn sau này dài hơn SSE2 và các lệnh MMX / SSE1 là ngắn nhất. Các phiên bản khác nhau của pmax*(max-số dọc tối đa) được giới thiệu ở các thời điểm khác nhau, với SSE1 (đối với regx mm) và SSE2 (đối với regs xmm) chỉ có từ đã ký (16 bit) và byte không dấu.

( pshufwpmaxswtrên các thanh ghi MMX là mới với Katmai Pentium III, vì vậy thực sự chúng yêu cầu SSE1, không chỉ là bit tính năng CPU MMX.)

Đây là callable từ C như unsigned max4_mmx(__m64)với i386 System V ABI, mà đi một __m64arg trong mm0. (Không phải x86-64 System V, được truyền __m64vào 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

Nếu có một pmovmskw, cái gì sẽ lưu packsswband(3 + 2 byte). Chúng tôi không cần and eax, 0x0fpmovmskbtrên một thanh ghi MMX đã không có các byte trên. Các thanh ghi MMX chỉ rộng 8 byte, vì vậy AL 8 bit bao gồm tất cả các bit khác không có thể.

Nếu chúng ta biết đầu vào của chúng ta không âm, chúng ta có thểpacksswb mm1, mm0 tạo ra các byte được ký không âm ở 4 byte trên mm1, để tránh sự cần thiết andsau pmovmskb. Do đó 24 byte.

Gói x86 với độ bão hòa đã ký xử lý đầu vào và đầu ra như đã ký, vì vậy nó luôn bảo toàn bit dấu. ( https://www.felixcloutier.com/x86/packsswb:packssdw ). Thực tế thú vị: gói x86 với độ bão hòa không dấu vẫn xử lý đầu vào như đã ký. Đây có thể là lý do tại sao PACKUSDWkhông được giới thiệu cho đến SSE4.1, trong khi 3 kết hợp kích thước và chữ ký khác tồn tại kể từ MMX / SSE2.


Hoặc với số nguyên 32 bit trong một thanh ghi XMM (và pshufdthay vì pshufw), mỗi lệnh sẽ cần thêm một byte tiền tố, ngoại trừ việc movmskpsthay thế gói / và. Nhưng pmaxsd/ pmaxudcần thêm một byte ...

có thể gọi từ C nhưunsigned max4_sse4(__m128i); với x86-64 System V hoặc MSVC vectorcall ( -Gv), cả hai đều vượt qua __m128i/ __m128d/ __m128args trong XMM regs bắt đầu bằng 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

Hoặc nếu chúng tôi chấp nhận đầu vào là float, chúng tôi có thể sử dụng các hướng dẫn SSE1. Các floatđịnh dạng có thể đại diện cho một loạt các giá trị số nguyên ...

Hoặc nếu bạn nghĩ rằng việc bẻ cong các quy tắc quá xa, hãy bắt đầu với 3 byte 0F 5B C0 cvtdq2ps xmm0, xmm0để chuyển đổi, tạo ra một hàm 27 byte hoạt động cho tất cả các số nguyên có thể biểu diễn chính xác như nhị phân IEEE32 floatvà nhiều kết hợp đầu vào mà một số đầu vào nhận được làm tròn thành bội số của 2, 4, 8 hoặc bất cứ điều gì trong quá trình chuyển đổi. (Vì vậy, nó nhỏ hơn 1 byte so với phiên bản SSE4.1 và hoạt động trên mọi x86-64 chỉ với SSE2.)

Nếu bất kỳ đầu vào float nào là NaN, lưu ý rằng maxps a,bthực hiện chính xác (a<b) ? a : b, giữ cho phần tử từ toán hạng 2 không được sắp xếp . Vì vậy, điều này có thể trả về với bitmap khác không ngay cả khi đầu vào chứa một số NaN, tùy thuộc vào vị trí của chúng.

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

sao chép và xáo trộn với pshufdvẫn là đặt cược tốt nhất của chúng tôi: shufps dst,src,imm8đọc đầu vào cho nửa thấp dst từ dst . Và chúng ta cần một bản sao và xáo trộn không phá hủy cả hai lần, vì vậy cả 3 byte movhlpsunpckhps/ pd đều bị loại bỏ. Nếu chúng tôi thu hẹp đến mức tối đa vô hướng, chúng tôi có thể sử dụng các giá trị đó, nhưng sẽ tốn một hướng dẫn khác để phát trước khi so sánh nếu chúng tôi chưa có tối đa trong tất cả các yếu tố.


Liên quan: SSE4.1 phminposuwcó thể tìm thấy vị trí và giá trị tối thiểu uint16_ttrong một thanh ghi XMM. Tôi không nghĩ rằng đó là một chiến thắng để trừ từ 65535 để sử dụng nó cho tối đa, nhưng hãy xem câu trả lời SO về việc sử dụng nó cho tối đa byte hoặc số nguyên đã ký.


1

Python 3,8 (tiền phát hành) , 67 byte

Hàm Lambda có 4 số nguyên, bit thay đổi kết quả boolean so với giá trị tối đa với một số trợ giúp từ toán tử gán mới của Python 3.8 và trả về bit HOẶC của kết quả

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

Hãy thử trực tuyến!


: = nhắc nhở tôi về những ngày xưa nơi đó là toán tử gán với công thức Lotus Notes. Đoán tôi sẽ phải xem 3,8 vì lợi ích của thời xưa :)
ElPedro



1

JavaScript (ES6), 30 byte

Đưa đầu vào là ([d,c,b,a]). Trả về 4 giá trị Boolean.

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

Hãy thử trực tuyến!


1
OP đã làm rõ rằng bạn thực sự có thể trả về 4 giá trị 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]

Hãy thử trực tuyến!

Đưa đầu vào là [a,b,c,d]và đưa ra một danh sách các booleans.

Được chỉnh sửa thành một hàm thích hợp, sau đó lưu 2 byte bằng cách xóa dấu ngoặc quanh điều kiện.


1
Xin chào và chào mừng đến với PPCG. Khi nó đứng, câu trả lời của bạn có dạng một đoạn trích, không được phép. Vui lòng sửa câu trả lời của bạn để phù hợp với sự đồng thuận I / O của chúng tôi , nghĩa là biến nó thành một chức năng hoặc chương trình đầy đủ.
Jonathan Frech

1
Đã chỉnh sửa. Lần đầu tiên xung quanh. Đánh giá cao những người đứng đầu!
Đánh bại

Bạn có thể giảm xuống còn 37 byte bằng cách hiểu danh sách này trong lambda. Chào mừng bạn đến với PPCG, và tận hưởng kỳ nghỉ của bạn!
Mực giá trị

@ValueInk Xóa khoảng trắng thừa sẽ tiết kiệm thêm một byte.
Jonathan Frech

1

1. Python 3.5, 90 byte

Lấy chuỗi số làm tham số. Trả về chuỗi "nhị phân"

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

thí dụ:

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

Giải trình

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 # (Trình biên dịch tương tác Visual C #) , 26 byte

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

Hãy thử trực tuyến!

Đưa đầu vào ở định dạng [d,c,b,a]. Tất cả những cái khác bên dưới lấy đầu vào là[a,b,c,d]

C # (Trình biên dịch tương tác Visual C #) , 35 byte

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

Trả về một IEnumerable<bool>.

Hãy thử trực tuyến!

C # (Trình biên dịch tương tác Visual C #) , 39 byte

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

Trả về một IEnumerable<int>, đại diện cho bit.

Hãy thử trực tuyến!

C # (Trình biên dịch tương tác Visual C #) , 49 byte

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

In một chuỗi nhị phân thành STDOUT.

Hãy thử trực tuyến!


IEnumerable<bool> được chấp nhận
Adám

0

PHP, 54 byte

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

hoặc là

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

lấy đầu vào từ các đối số dòng lệnh. Chạy với -nrhoặc thử chúng trực tuyến .


0

Đây là phiên bản JS xuất ra dưới dạng nhị phân

cập nhật: Ngắn hơn với tham gia và không cần tra cứu:

JavaScript (Node.js) , 42 byte

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

Hãy thử trực tuyến!

Trước đây, với tra cứu, 49 byte

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

Hãy thử trực tuyến!

Trước đó, với mức giảm, 52 byte:

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

Hãy thử trực tuyến!

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 có vẻ hiển nhiên bây giờ. Cảm ơn!
Pureferret

0

C # (Trình biên dịch tương tác Visual C #) , 51 byte

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

Hãy thử trực tuyến!

Trên đây là một hàm ẩn danh xuất ra bằng cách sửa đổi một đối số . Đầu ra là một mảng 1 và 0.

Dưới đây là một hàm đệ quy đưa ra một số nguyên.

C # (Trình biên dịch tương tác 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);

Hãy thử trực tuyến!

Cả hai hàm đều lấy đầu vào là một mảng 4 phần tử.

[d, c, b, a]

Bạn không cần phải xuất một số nguyên.
Adám

@Adam - cảm ơn :) Tôi nhận ra điều này sau khi đăng trong khi tôi đang làm việc với câu trả lời khác của mình. Trước khi tôi có cơ hội thay đổi, đã có một câu trả lời C # khác sử dụng rất nhiều thủ thuật hay.
dana



0

Mẻ, 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)

Đưa các đối số làm tham số dòng lệnh theo thứ tự ngược lại. Hoạt động bằng cách tính toán tối đa các tham số bằng cách giảm trên chúng và chỉ thêm vào các khác biệt tích cực so với tối đa đang chạy, sau đó ánh xạ lại từng tham số lần này so sánh với tối đa. Thuận tiện cmd/cset/akhông tạo ra một dòng mới, vì vậy các kết quả sẽ tự động được nối với nhau. Đơn %f%giản chỉ cần lưu 5 byte trên những gì sẽ là một cấu trúc lặp đi lặp lại.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.