Dört tam sayıyı karşılaştırın, kelimeyi maksimuma göre döndürün


9

Bu fonksiyon, dört tam sayı girişler almak (gerekir a, b, c, dhangi değerleri dört maksimum eşit göre bir ikili kelime) ile döner.

Dönüş değeri 1ve arasında olacaktır 0xF.

Örneğin:

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

döndürür 2(ikili 0010; yalnızca bmaks. değere karşılık gelen yalnızca 2. en küçük anlamlı bit ayarlanır )

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

döndürür 0xC(ikili 1100; maksimum değere karşılık gelen cve dmaksimum değere eşit olan 3. ve 4. en küçük anlamlı bitler kümesi )

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

döndürür 0xF(ikili 1111; tüm değerler maks. değere eşit olduğu için dört bitin tümü ayarlanır)

İşte basit bir uygulama:

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

dönüş değeri 0 ve 1 dizeleri, bool / bit vektörü veya tam sayı olabilir


2
Ben ters, Maksimum, Eşitlik kontrol, Katıl, İkili tamsayı dönüştürmek, tamsayı onaltılık dönüştürmek yerleşikleri kullanan bir golf dilinde bir çözüm var. Bu Eşitlik kontrolü nedeniyle puanımın 1 olduğu anlamına mı geliyor? Bunun normal dillere çok fazla odaklanmış olduğunu hissediyorum ve hatta onlar için bir Maksimum yerleşik diyelim ki puanlama% 100 net değil ..: S
Kevin Cruijssen

1
Ben denemek için tavsiye ederim: 1. sadece bayt sayısı umurumda kod-golf, bu soruyu değiştirmek. 2. veya, belirli bir dil ile kısıtlayın (derleyicinin / yorumlayıcının belirli bir sürümü) ve izin verilen tüm ifadeleri ve operatörleri ve bunları nasıl puanlayacağınızı listeleyin.
tsh

5
1 daha iyi bir seçenektir, IMO. Bu mükemmel bir kod golf soru yapar ve cevaplar için mevcut dilleri kısıtlamaktan gelecek herhangi bir fayda göremiyorum
senox13

2
Ölçütleri kaldırmak için sorumu güncelledim. Hala belirsiz olduğunu bana bildirin
Bay Anderson

5
Ondalık bir sayı çıkarmalı mıyım? Veya bunun yerine 4 ikili basamak verebilir miyim?
tsh

Yanıtlar:


8

Jöle , 2 bayt

Girişi alır [d,c,b,a]. Boole'ların bir listesini döndürür.

Ṁ=

Çevrimiçi deneyin!

M aksimum

= eşittir (diğer argümanın orijinal argüman olduğunu ima eder; vektörleştirir)


5

R , 17 bayt

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

Çevrimiçi deneyin!

Bir booleans vektörü döndürür. Bu çıktı onaylandığından, sayısal çıktıya göre bu tercih edilir, çünkü biri neredeyse iki kat daha uzundur:

R , 33 bayt

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

Çevrimiçi deneyin!


4

APL (Dyalog Unicode) , 4 bayt SBCS

Anonim zımni önek fonksiyonu. Alır [a,b,c,d]argüman olarak. Bir bit-Boolean dizisi döndürür. *

⌈/=⌽

Çevrimiçi deneyin!

⌈/ Maksimum argüman mı

= eşit (vektörler)

 tartışmanın tersi?

* APL, Booleans dizilerini değer başına bir bit kullanarak sakladığına dikkat edin, bu nedenle görüntüleme formuna rağmen bu gerçekten 4 bitlik bir kelime döndürür 0 0 1 0.



2

Perl 6 , 12 bayt

{$_ X==.max}

Çevrimiçi deneyin!

Tamsayıların listesini alan ve booleans listesini döndüren anonim kod bloğu. Sayı olarak geri dönmemiz gerekirse, kod bloğunun içini sarmak +4 bayttır 2:[...].

Açıklama:

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

OP şimdi sarmanıza gerek olmadığını söylüyor.
Adám

2

Japt, 5

m¶Urw

Dene!

@Oliver sayesinde -4 bayt!
@Shaggy sayesinde -2 bayt!

Girdi, aşağıdaki biçimde 4 öğeli bir dizidir:

[d, c, b, a]

Çıktı bir bit dizisidir.


Tabii ki var;) Görünüşe göre öğrenecek çok sayıda kısayol var.
Dana

Bir boolean dizisi kabul edilebilir bir çıktıysa, bu 7 bayt olabilir
Oliver

@Oliver, 5 bayt ;)
Shaggy

Siz oldukça iyisiniz :) Bu tekrar tekrar max alarak bir azaltma nasıl rwdönüştürülür ilginç r("w"). İle aynıDönüştürülmekleU.m("===", ...) . Her durumda, ipuçları için teşekkürler!
dana

2

x86 makine kodu (MMX / SSE1), 26 bayt (4x int16_t)

x86 makine kodu (SSE4.1), 28 bayt (4x int32_t veya uint32_t)

x86 makine kodu (SSE2), 24 bayt (4x float32) veya cvt int32 için 27B

(İnt32'yi float'a dönüştüren son sürüm, aynı float'a yuvarlanan büyük tamsayılar için mükemmel bir şekilde doğru değildir. Float girişi ile yuvarlama, arayanın sorunudur ve NaN'ler yoksa, bu işlev doğru şekilde çalışır; Tamsayı sürümleri, tüm girdiler için imzalanmış 2'nin tamamlayıcısı olarak kabul edilir.)

Tüm bunlar aynı makine koduyla 16/32/64 bit modunda çalışır.

Bir yığın-args çağırma kuralı, muhtemelen daha küçük bir uygulama vererek, iki kez argümanlar üzerinde döngü (max bulma ve sonra karşılaştırma) mümkün kılar, ama bu yaklaşımı denemedim.

x86 SIMD'de tek bir komut olarak vektör-> tamsayı bitmap (pmovmskb veya movmskpspd) , bu nedenle MMX / SSE komutları en az 3 bayt uzunluğunda olsa bile bunun için doğaldı. SSSE3 ve sonraki talimatlar SSE2'den daha uzun ve MMX / SSE1 talimatları en kısa olanıdır. pmax*SSE1 (mmx regs için) ve SSE2 (xmm regs için) yalnızca imzalı kelimeye (16 bit) ve imzasız bayta sahip olmak üzere farklı zamanlarda (paketli tamsayı dikey maks) farklı sürümler tanıtıldı.

( pshufwve pmaxswMMX kayıtlarında Katmai Pentium III'te yenidir, bu yüzden sadece MMX CPU özellik biti için değil, SSE1 gerektirirler.)

Bu C olarak çağrılabilir unsigned max4_mmx(__m64)bir geçer i386 Sistem V ABI ile __m64Arg mm0. (Geçen x86-64 Sistem V değil,__m64 içinde 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

Eğer bir pmovmskwşey olsaydı,packsswb ve and(3 + 2 bayt) . İhtiyacımız yok and eax, 0x0fçünkü pmovmskbbir MMX kaydında zaten üst baytları sıfırlar. MMX kayıtları yalnızca 8 bayt genişliğindedir, bu nedenle 8 bit AL olası tüm sıfır olmayan bitleri kapsar.

Girdilerimizin negatif olmadığını bilseydikpacksswb mm1, mm0 , üst 4 baytta negatif olmayan işaretli bayt üretebiliriz mm1, andsonradan ihtiyacını ortadan kaldırabilirizpmovmskb . Böylece 24 bayt.

İmzalı doygunluğa sahip x86 paketi, girdi ve çıktıyı imzalı olarak ele alır, böylece her zaman işaret bitini korur. ( https://www.felixcloutier.com/x86/packsswb:packssdw ). İlginç gerçek: İmzasız doygunluğa sahip x86 paketi, girdiyi hala imzalanmış olarak kabul eder . Bu nedenle PACKUSDWSSE4.1'e kadar kullanılmamış olabilirken , diğer 3 boyut ve imza kombinasyonu MMX / SSE2'den beri mevcuttu.


Veya bir XMM kaydındaki 32 bit tamsayılarla (ve pshufdbunun yerine pshufw), her komutun movmskps/ ve yerine başka bir önek baytına ihtiyacı olacaktır . Ama pmaxsd/ pmaxudekstra ekstra bayt gerekir ...

unsigned max4_sse4(__m128i);x86-64 System V veya MSVC vectorcall ( -Gv) ile olduğu gibi C'den çağrılabilir , her ikisi de XMM kayıtlarında başlayan __m128i/ __m128d/ __m128args ile başlar 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

Veya girişi olarak kabul floatedersek, SSE1 talimatlarını kullanabiliriz. floatBiçim tamsayı değerlerinin geniş bir yelpazede temsil edebilir ...

Veya kuralları çok fazla büktüğünü düşünüyorsanız, 3 baytla başlayın 0F 5B C0 cvtdq2ps xmm0, xmm0 büktüğünü düşünüyorsanız float, dönüştürmek ile başlayın , IEEE ikili dosyası olarak tam olarak temsil edilebilen tüm tamsayılar ve bazı girdilerin aldığı birçok girdi kombinasyonu için çalışan 27 baytlık bir işlev yapın. dönüşüm sırasında 2, 4, 8 veya katlarına yuvarlanır. (Yani SSE4.1 sürümünden 1 bayt daha küçüktür ve sadece SSE2 ile herhangi bir x86-64 üzerinde çalışır.)

Şamandıra girdilerin herhangi NaN, not ise o maxps a,btam uygular (a<b) ? a : b, sırasız üzerinde 2 İşlenenden eleman tutarak . Bu nedenle, giriş, bulundukları yere bağlı olarak bazı NaN içeriyor olsa bile sıfır olmayan bir bitmap ile geri dönmek mümkün olabilir.

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

shuffle'ınızı kopyalayıp pshufdhala en iyi bahis: shufps dst,src,imm8düşük yarısı için giriş okur dst dan dst . Her iki seferde de tahribatsız bir kopyala-karıştır seçeneğine ihtiyacımız var, bu yüzden 3 baytmovhlps ve unpckhps/ pd ikisi de dışarıda. Bir skaler maks'e daralsaydık, bunları kullanabilirdik, ancak zaten tüm öğelerde maksimum değere sahip değiliz, karşılaştırmadan önce yayınlamak için başka bir talimat gerekiyor.


İlgili: SSE4.1 phminposuw, uint16_tbir XMM kaydında minimumun konumunu ve değerini bulabilir . Maksimum için kullanmak için 65535'ten çıkarmanın bir kazanç olduğunu düşünmüyorum, ancak maksimum bayt veya işaretli tamsayılar için kullanma hakkında bir SO cevabı görüyorum .


1

Python 3.8 (ön sürüm) , 67 bayt

4 tamsayı alan Lambda işlevi, bitlerinin boole sonucunu Python 3.8'in yeni atama operatörünün yardımıyla biraz maksimum değere kaydırır ve sonuçların bit yönünü VEYA döndürür

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

Çevrimiçi deneyin!


: = bana Lotus Notes formülüne sahip atama operatörü olduğu eski günleri hatırlatıyor. Sanırım eski zamanlar için 3.8 bakmak zorunda kalacağım :)
ElPedro



1

JavaScript (ES6), 30 bayt

Girişi alır ([d,c,b,a]). 4 Boole değeri döndürür.

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

Çevrimiçi deneyin!


1
OP, gerçekten de 4 Boolean değeri döndürebileceğinizi açıkladı.
Adám


1

Python 3 , 59 bayt 66 bayt

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

Çevrimiçi deneyin!

Girişi alır [a,b,c,d]ve bir booleans listesi çıkarır.

Uygun bir işlev olarak düzenlendi, daha sonra koşullu parantezleri kaldırarak 2 bayt kaydetti.


1
Merhaba ve PPCG'ye hoş geldiniz. Duruşurken cevabınız izin verilmeyen bir pasaj biçimindedir. Lütfen cevabınızı I / O konsensüsümüze uyacak şekilde düzeltin , yani bir işlev veya tam program yapın.
Jonathan Frech

1
Düzenlenen. İlk kez. Dikkat edin!
Bsoned

Bir lambda içindeki bu liste anlayışını kullanarak 37 bayta düşürebilirsiniz . PPCG'ye hoş geldiniz ve konaklamanızın tadını çıkarın!
Değer Mürekkebi

@ValueInk Gereksiz boşlukları kaldırmak başka bir bayt kazandırır.
Jonathan Frech

1

1. Python 3.5, 90 bayt

Sayı dizisini parametre olarak alır. "İkili" dizeyi döndürür

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

misal:

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

açıklama

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 # Etkileşimli Derleyici) , 26 bayt

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

Çevrimiçi deneyin!

Girişi formatta alır [d,c,b,a]. Aşağıdaki diğer tüm girdiler[a,b,c,d]

C # (Visual C # Etkileşimli Derleyici) , 35 bayt

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

Bir döndürür IEnumerable<bool> .

Çevrimiçi deneyin!

C # (Visual C # Etkileşimli Derleyici) , 39 bayt

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

Bir döndürür IEnumerable<int> temsil eden .

Çevrimiçi deneyin!

C # (Visual C # Etkileşimli Derleyici) , 49 bayt

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

STDOUT'a ikili bir dize yazdırır.

Çevrimiçi deneyin!


IEnumerable<bool> olduğu kabul edilebilir.
Adám

0

PHP, 54 bayt

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

veya

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

komut satırı bağımsız değişkenlerinden girdi alır. Birlikte çalışın-nr veya çevrimiçi deneyin .


0

İşte ikili olarak çıkan bir JS sürümü

update: Birleştirmeyle ve arama yapmadan daha kısa:

JavaScript (Node.js) , 42 bayt

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

Çevrimiçi deneyin!

Önceki, arama ile, 49 bayt

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

Çevrimiçi deneyin!

Önceki, azaltma ile 52 bayt:

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

Çevrimiçi deneyin!

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][...]Zaten ikisinden biri olan bir dizini kullandığınızdan güvenle kaldırabilirsiniz0 veya 1.
Arnauld

@Arnauld şimdi belli görünüyor. Teşekkürler!
Pureferret

0

C # (Visual C # Etkileşimli Derleyici) , 51 bayt

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

Çevrimiçi deneyin!

Yukarıda, bir argümanı değiştirerek çıkan anonim bir işlev vardır . Çıktı 1'ler ve 0'lar dizisidir.

Aşağıda bir tamsayı çıkaran özyinelemeli bir işlev vardır.

C # (Visual C # Etkileşimli Derleyici) , 60 bayt

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

Çevrimiçi deneyin!

Her iki fonksiyon da girişi 4 elemanlı bir dizi olarak alır.

[d, c, b, a]

Bir tamsayı çıkarmanıza gerek yoktur.
Adám

@Adam - teşekkürler :) Diğer cevabım üzerinde çalışırken yayınladıktan sonra bunu fark ettim. Değişme şansım olmadan önce, birçok iyi numara kullanan başka bir C # yanıtı vardı.
dana



0

Toplu, 92 bayt

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

Bağımsız değişkenleri ters sırayla komut satırı parametreleri olarak alır. Parametrelerin üst sınırlarını azaltarak ve çalışma maksimum değerinden yalnızca pozitif farklılıklar ekleyerek parametrelerin maksimum sayısını aritmetik olarak hesaplayarak çalışır, ardından bu parametreyi maksimumla karşılaştırarak her parametre üzerinde yeniden eşleştirerek çalışır. Uygun cmd/cset/abir şekilde yeni satır çıktısı olmadığından sonuçlar otomatik olarak bir araya getirilir. %f%Basitçe bir tekrarlanan yapı olacağını üzerinde 5 bayt kaydeder.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.