Bir parite biti oluşturun


18

Bir eşlik biti , bir sağlama toplamı en basit biçimlerinden biridir. Öncelikle, eşit veya tek olan paritesi seçmelisiniz. Diyelim ki eşit seçtik. Şimdi iletmek için bir mesaja ihtiyacımız var. Diyelim ki mesajımız "Foo". Bu ikili olarak şu şekilde yazılır:

01000110 01101111 01101111

Şimdi, 1oradaki toplam ' sayısı 15'i sayıyoruz. 15 tek bir sayı olduğu için mesajımızın sonuna bir bit daha eklemeliyiz ve şimdi çift sayıda' on 'bitimiz olacak . Bu son eklenen bit, "eşlik biti" olarak bilinir. Kontrol toplamımız için garip bir parite seçmiş olsaydık, fazladan bir '0' eklememiz gerekirdi, böylece bitlerin sayısı tuhaf kalır.

Meydan okuma:

Bir dize için doğru eşlik bitinin ne olduğunu belirleyen bir program veya işlev yazmalısınız. Programınız iki giriş almalıdır:

  • Bir dize s,. Bu, sağlama toplamının hesaplanacağı mesajdır. Bu, yazdırılabilir 95 ASCII karakteriyle sınırlandırılacaktır.

  • Eşit parite veya tek parite için polacak bir karakter veya tek karakter dizesi .eo

ve doğru eşlik bitini temsil eden gerçek-falsey bir değer üretirler . Doğruysa a 1, eğer falsey ise 0.

Bir dize veya karakterdeki "on" bit sayısını sayan yapılara izin verilmez. Örneğin, bunu yapan bir işlev f: f('a') == 3veya f('foo') == 16yasaklandı. Temel dönüşüm gibi her şey adil bir oyundur.

Test G / Ç:

(without the quotes)
s: "0"
p: 'e'
output: 0

s: "Foo"
p: 'e'
output: 1

s: "Hello World!"
p: 'o'
output: 0

s: "Alex is right"
p: 'e'
output: 1

s: "Programming Puzzles and Code-Golf" 
p: 'e'
output: 0

s: "Programming Puzzles and Code-Golf" 
p: 'o'
output: 1

Bu kodgolf, bu yüzden standart boşluklar geçerlidir ve bayttaki en kısa cevap kazanır.

Liderler Sıralaması


10
Aksine can sıkıcı bir şekilde, oparite bile var.
Neil

Eğer açıklık Can üzerinde "sayısını çıkmasını sağlamakta '' Bir dize veya karakter bit izin verilmez." biraz daha iyi? Yerleşik taban dönüşümü ne olacak? Vb ..
orlp

@DrGreenEggsandHamDJ Stack siteleri hakkındaki yorumlar uçucudur ve herhangi bir sebep olmaksızın, herhangi bir yetenekli kullanıcının kaprisinde uyarı yapılmaksızın kaybolabilir. Sonuç olarak, zorluğun ayrılmaz özelliklerinin yorum bölümünde değil , yazının kendisinde olması şiddetle tavsiye edilir .
kedi

1
python Örneğin @cat: str(int(s, 2)).count('1')? Hayır, bu kuralı ihlal eden tek bir yerleşik işlev olduğunu düşünmem . Düzenlemem daha açık hale getiriyor mu?
DJMcMayhem

1
@cat Bildiğim kadarıyla char == single_char_string. Bunu yazıya da düzenledim.
DJMcMayhem

Yanıtlar:


9

MATL , 8 7 bayt

8\hBz2\

Çevrimiçi deneyin! Veya tüm test senaryolarını bir kerede doğrulayın .

8\    % Implicitly take first input ('e' or 'o'), and compute modulo 8. Inputs 'e' and 'o' 
      % give 5 or 7 respectively, which have an even or odd number of `1` bits resp.
h     % Implicitly take second input, and concatenate
B     % Convert to binary. Gives 2D array, with one row for each original entry 
z     % Number of nonzero values in that 2D array
2\    % Modulo 2, i.e. compute parity

9

Java, 97 bayt

Çünkü biliyorsunuz Java.

(s,c)->{boolean e=1>0;for(int i:s.getBytes())while(i>0){if(i%2==1)e=!e;i/=2;}return c=='o'?e:!e;}

Bu bir lambda BiFunction<String, Character, Boolean> .

eve ogörünüşe göre mantığım geriye dönük olduğu için dönüş ifadesinde tersine çevrilmiş gibi görünüyor.


5

Python 2, 51 bayt

lambda s,p:`map(bin,map(ord,p+s))`[9:].count('1')%2

Bu, Sp3000'in , her karakter için toplanmak yerine ikili olarak karakter kodları listesinin dize temsilindeki 1'leri sayması fikrine dayanır .

Yeni hüner koluna olduğunu eve obu yanı. eTek ve oçift olsaydı , sayım yapmadan önce parite bitini dizeye başlatabiliriz ('1' Gerçek olduğu için onları çevirmek). Ne yazık ki öyle değiller. Ancak, son iki biti hariç hepsini kaldırırsak, şimdi doğrudur.

e 0b11001|01
o 0b11011|11 

Bu, 9dize temsilinin ilk karakterini kaldırarak yapılır .

['0b11001|01', 

Vay canına, bu çok düzgün bir yol tutuşu eo!
Sp3000

4

Jöle, 9 8 bayt

OBFSḂ⁼V}

Çevrimiçi deneyin!

O         convert each character in argument 1 (left arg) to its codepoint (ord)
 B        convert to binary (list of 0s and 1s)
  F       flatten
   S      sum the entire list, giving the number of 1s in the entire string
    Ḃ     mod 2 (take the last bit)
       }  now, with the second (right) argument...
      V   eval with no arguments. This returns...
            1 for e because it expands to 0e0 (i.e., does 0 exist in [0])
            0 for o because it expands to 0o0 (0 OR 0, false OR false, false)
     ⁼    test equality between the two results

Dennis'e bir bayt için teşekkürler!


1
Kendimi bir Jelly cevabı bulmaya çalışıyordum, ama bu zincirleme kurallar beni seçiyor :-)
Luis Mendo

2
@LuisMendo Aynı gemideyim; Bu uzun zamandır öğrenmeye çalıştıktan sonra ilk Jelly cevabım ... çok uzun: P
Kapı Tokmağı

Bu V}... o gerçekten harikaydı !!! (Dennis gerçek bir golfçüdür) +1 Her girişimimi yendi.
Outgolfer Erik

4

C, 62 bayt

  • @LevelRiverSt ve @TonHospel sayesinde 12 bayt tasarruf edildi.

XOR, pariteyi korurken dizeleri bir karaktere düşürmek için kullanılabileceği güzel bir özelliğe sahiptir.

f(s,p)char*s;{for(p/=8;*s;)p^=*s>>4^*s++;p^=p/4;return p%4%3;}

Ideone.


1
27030>>((p^p>>4)&15)&1 p paritesini hesaplamak gerekir ve hatta 1 bayt daha kısa
Ton Hospel

1
Uzay char *suneeded olduğunu
Ton Hospel

2
62 bayt: f(s,p)char*s;{for(p/=8;*s;)p^=*s>>4^*s++;p^=p/4;return p%4%3;}Her %3zaman 0 için 0 döndürür, ancak 1 için 1 veya 2 döndürebilir. Bu kurallar altında kabul edilebilir:truthy if it's a 1
Level River St

1
27030>>((p^p>>4)&15)&1. Hata, açıkçası. ;-)
Dijital Travma

@LevelRiverSt Brilliant! Teşekkürler!
Dijital Travma

4

Python, 58 57 bayt

lambda s,p:sum(bin(ord(c)).count("1")for c in s)&1!=p>'e'

1
53 (yalnızca Python 2):lambda s,p:`map(bin,map(ord,s))`.count('1')%2^(p>'e')
Sp3000 26:06

İle bir bayt kaydedebilirsiniz !=p>'e' .
xnor

Bekle, bayt kaydım aslında çalışmıyor çünkü Python bunu zincirlenmiş bir eşitsizlik olarak görüyor.
xnor

lambda s,p:`map(bin,map(ord,p+s))`[8:].count('1')%2
xnor

@xnor Sadece kendi cevabınızı gönderin.
orlp

3

Pyth, 12 bayt

q@"oe"sjCz2w

Test odası.

         z    take a line of input
        C     convert to int
       j  2   convert to base 2, array-wise (so, array of 0s and 1s)
      s       sum (count the number of ones)
 @"oe"        modular index into the string to get either "o" or "e"
q          w  test equality to second line of input

3

JavaScript (ES6), 84 72 bayt

(s,p)=>(t=p>'e',[...s].map(c=>t^=c.charCodeAt()),t^=t/16,t^=t/4,t^t/2)&1

Bit çevirme, taban 2'ye dönüştürme ve 1s sayma işleminden daha kısa çıktı .


2

Perl, 29 bayt

İçin +2 içerir -p

STDIN üzerindeki girdi ile eşlik karakter alanı dizesi olarak çalıştırın, ör.

parity.pl <<< "p Programming Puzzles and Code-Golf"

parity.pl

#!/usr/bin/perl -p
$_=unpack"B*",$_|b;$_=1&y;1;

2

J, 27 bayt

'oe'&i.@[=[:~:/^:2@#:3&u:@]

kullanım

   f =: 'oe'&i.@[=[:~:/^:2@#:3&u:@]
   'e' f '0'
0
   'e' f 'Foo'
1
   'o' f 'Hello World!'
0
   'e' f 'Alex is right'
1
   'e' f 'Programming Puzzles and Code-Golf'
0
   'o' f 'Programming Puzzles and Code-Golf'
1

1

JavaScript (ES6), 69 bayt

(s,p)=>[...s].map(c=>{for(n=c.charCodeAt();n;n>>=1)r^=n&1},r=p>"e")|r

1

PowerShell v2 +, 91 bayt

/ köşede ağlıyorum

param([char[]]$a,$b)$b-eq'o'-xor(-join($a|%{[convert]::toString(+$_,2)})-replace0).length%2

Evet ... temel dönüşüm PowerShell için güçlü bir takım değil. Giriş dizesinden ikili temsile dönüştürme$a|%{[convert]::toString(+$_,2)} kendi içinde 32 bayttır ...

Girdi alır $ave $baçıkça $asüreçte bir char-array olarak döküm . Sonra kontrol $bolduğu -eqiçin UAL ove -xorprogramın diğer yarısı söyledi. Bu bölüm için, giriş dizesini alırız $a, her harfi ikiliye dönüştürmek için bir döngü boyunca boru oluştururuz, -joinhepsini birlikte tek bir katı dize oluşturmak ve hiçbir şeyi olmayan -replacetüm 0s. Sonra saymak .lengthİpin ve rahatça ya olacak olan bu mod-2 tek veya çift olup olmadığını belirlemek için almak 0ya 1için mükemmel -xor.

Dönecek Trueya da Falsebuna göre. Aşağıdaki test senaryolarına bakın:

PS C:\Tools\Scripts\golfing> .\generate-parity-bit.ps1 "0" e
False

PS C:\Tools\Scripts\golfing> .\generate-parity-bit.ps1 "Foo" e
True

PS C:\Tools\Scripts\golfing> .\generate-parity-bit.ps1 "Hello World!" o
False

PS C:\Tools\Scripts\golfing> .\generate-parity-bit.ps1 "Alex is right" e
True

PS C:\Tools\Scripts\golfing> .\generate-parity-bit.ps1 "Programming Puzzles and Code-Golf" e
False

PS C:\Tools\Scripts\golfing> .\generate-parity-bit.ps1 "Programming Puzzles and Code-Golf" o
True

1

Faktör, 85 bayt

Nedense kodumu basitleştirdiğimde (ve belki kısalttığımda) birkaç dakika öncesine kadar başımı bunun etrafına dolayamadım.

[ "e" = [ even? ] [ odd? ] ? [ [ >bin ] { } map-as concat [ 49 = ] count ] dip call ]

?üçlü bir işleç gibidir: üçüncü yığın öğesinin doğruluğunu test eder ve ya truedeğeri ya da falsedeğeri seçer .

Aşağıdaki C benzeri pseduocode'a kabaca eşdeğerdir:

void* parity_tester_function = strcmp(p, "e") ? (void *) even?  // it's a function pointer (I think)
                                              : (void *) odd? ;

Kodun geri kalanı oldukça basittir:

[                       ! to count a string's set bits:
    [ >bin ] { } map-as ! get the binary of each character, and map as an array, because you can't have stringy data nested in another string (that's called a type error)
    concat              ! { "a" "B" } concat -> "aB"
    [ 49 = ] count      ! count items in the resulting string which match this condition (in this case, the condition we're testing is whether the character has the same code point as "1")
] dip                   ! take the above function pointer off the stack, apply this anonymous function to the now-top of the stack, then restore the value after the quotation finishes.
                        ! in other words, apply this quotation to the second-to-top item on the stack
call                    ! remember that conditionally chosen function pointer? it's on the top of the stack, and the number of sets bits is second.
                        ! we're gonna call either odd? or even? on the number of set bits, and return the same thing it does.

1

IA-32 makine kodu, 15 bayt

HexDump:

0f b6 c2 40 32 01 0f 9b c0 3a 21 41 72 f6 c3

Montaj kodu:

    movzx eax, dl;
    inc eax;
repeat:
    xor al, [ecx];
    setpo al;
    cmp ah, [ecx];
    inc ecx;
    jb repeat;
    ret;

Bu, ilk argümanını (string) in ecxve ikinci argümanını (char) in alan bir fonksiyondur dl. Sonucu döndürür eax, bu nedenle fastcallarama kuralıyla uyumludur .

Bu kod, setpotalimatı kullandığında kuralları büker :

Bir dize veya karakterdeki "on" bit sayısını sayan yapılara izin verilmez

Bu talimat al, önceki talimatla hesaplanan parite bitine ayarlanır - bu yüzden kurallarda bu iki nitpick var:

  • "Açık" bit sayısını saymaz - parite bitini doğrudan hesaplar!
  • Teknik olarak, xoreşlik bitini hesaplayan önceki talimat ( ). setpoTalimat sadece onu taşır alkayıt.

Bu anlamsal ayrıntılar yoldan çıkar, işte kodun ne yaptığına dair açıklama.

Karakterlerin temsili:

'e' = 01100101
'o' = 01101111

Onlara 1 eklersek, doğru doğru pariteye sahip olurlar:

'e' + 1 = 01100110 (odd parity)
'o' + 1 = 01110000 (even parity)

Bu yüzden XOR, dizenin tüm karakterlerini, albu değerlere başlayarak cevabı veririz .


İlk talimat movzx eax, dldaha açık (ve daha kısa) yerine mov al, dl, çünkü ah( 0, [ecx]daha ziyade [ecx], 0) doğru sırayla karşılaştırmak için bir kayıtta ( bu durumda) 0 sayısı olmasını istiyorum .


1

Julia, 58 47 45 40 bayt

f(s,p)=(p>'e')$endof(prod(bin,s)∩49)&1

Bu, bir dizeyi ve karakteri kabul eden ve bir tamsayı döndüren bir işlevdir.

İkili gösterimde olanların sayısını elde etmek için, önce binişlevi dizedeki her karaktere uygularız , bu da bize bir dizi ikili dizgi verir. Daha sonra bunları kullanarak bire indirin prod( *Julia'da dize birleştirme olduğu için) ve o dizenin ve karakter kodunun set kesişimini alın 1, bu da bize bir dizi dizesi verir. Bu dizenin son dizini, bunların sayısıdır. Sağlanan karakter o ve 0 ise, bunu 1 ile XOR yaparız , sonra biti AND 1 kullanarak pariteyi alırız.

Çevrimiçi deneyin!(tüm test senaryolarını içerir)

Dennis sayesinde 18 bayt kurtardı!


1

05AB1E , 15 , 13 bayt

Kod:

€ÇbSOÈ„oe²k<^

Örnek Giriş:

Programming Puzzles and Code-Golf
o

Örnek Çıktı:

1

Açıklama:

€                 # for each char in string
 Ç                # get ascii value
  b               # convert to binary
   S              # split to single chars (ex: '1101' to '1','1','0','1')
    O             # sum
     È            # check if even
      „oe         # push string "oe"
         ²        # push 2nd input (p)
          k       # get 1-based index of p in "oe"
           <      # decrease (to get either 0-based index)
            ^     # xor with result of È

Adnan'a 2 bayt kazandığı için teşekkürler.


Vay çok güzel! ²Komutunu kullanarak iki bayt arasında golf oynayabilirsiniz . Bu, ikinci girişi otomatik olarak yığının üstüne iter. Ayrıca, iki karakter dizeleri kullanılarak kısaltılabilir . Yani buna "oe"eşdeğerdir . 13 bayt için: €ÇbSOÈ„oe²k<^:)
Adnan

05AB1E ayrıca CP-1252 kodlaması kullanır , bu nedenle buradaki her karakter 1 bayttır :).
Adnan

@Adnan: Teşekkürler! Bayt hesabı için notepad ++ kullanıldı ve sadece karakter sayıldığını varsaydı: P
Emigna

0

Ruby, 57 bayt

0Ruby'de falsey olsaydı ,== muhtemelen sadece değiştirilebilir -ya da başka optimizasyonlar olabilirdi, ama değil.

->s,b{s.gsub(/./){$&.ord.to_s 2}.count(?1)%2==(b>?i?0:1)}

0

Retina , 102 bayt

İlk satırdaki dizeyi ve ikinci satırdaki harfi alır. ISO 8859-1 kodlamasını kullanır.

[12478abdghkmnpsuvyzCEFIJLOQRTWX#%&)*,/;=>@[\]^| ](?=.*¶)
1
[^1](?=.*¶)
0
^(0|10*1)*¶o|^0*1(0|10*1)*¶e

Çevrimiçi deneyin

İlk satırdaki karakter sınıfı, herhangi bir karakteri ikili gösterimdeki tek sayıda karakterle eşleştirir.

Normal ifade ile çift / tek algılamanın burada nasıl çalıştığının açıklaması .


0

Oktav, 56 bayt

f=@(s,p) mod(sum((i=bitunpack([s p]))(1:length(i)-5)),2)

bitunpackFonksiyonu, ASCII karakterleri için, küçük endian sırayla döndürür. Bu nedenle parite bayrağını dizimizin sonuna koyarak, her şeyi paketinden çıkararak ve son 5 biti bırakarak, nihai cevabımız için mod 2'nin tamamını özetleyebiliriz.

Kullanımı:

octave:137> f('Hello World!', 'o')
ans = 0
octave:138> f('Hello World!', 'e')
ans =  1

0

 Yaygın Lisp, 87

(lambda(s p)(=(mod(reduce'+(mapcar'logcount(map'list'char-code s)))2)(position p"oe")))
  • Öğesinin karakter kodlarının günlük sayısını toplayın s.
  • Bunun geri kalanı, 2'ye bölündüğünde p, dizedeki eşlik argümanının konumu "oe"(0 veya 1) ile karşılaştırılır. Örneğin, 4 tane varsa, kalan sıfırdır. P ise o, ek bir bit eklenmemeli ve test yanlış döndürülmelidir.

Oldukça baskılı

(lambda (s p)
  (= (mod (reduce '+ (mapcar 'logcount (map 'list 'char-code s))) 2)
     (position p "oe")))

0

Java, 91 bayt

(s,c)->{s+=c%8;int e=1;for(int i:s.getBytes())while(i>0){if(i%2==1)e^=1;i/=2;}return e==0;}

@ CAT97 ile aynı şeyi yaptım, ancak modulo 8 ve @Luis Mendo'yu bitiştirerek ve boolean yerine int kullanımını kullanarak bazı karakterleri çıkardım.

Bu bir lambdaBiFunction<String, Character, Boolean> .


0

Matlab, 49 bayt

f=@(x,p)mod(sum(sum(dec2bin(x)-'0'))+(p-'e'>0),2)

nerede:

  • x girdi dizesidir;
  • p eşit parite için 'e' ve garip olan için 'o' dur.

Örneğin:

>> f('Programming Puzzles and Code-Golf','e')

ans =

     0

0

Bash ve unix araçları (72 bayt)

f(){ bc<<<"$(xxd -b<<<"$2$1"|cut -b9-64|tail -c +7|tr -dc 1|wc -c)%2" }

Excepts silk olarak ve pparametre olarak verilir. Neyse ki sırasıyla son 3 bit ove etek ve eşit paritesi vardır.

xxd -b        print the concatenation of `p` and `s` in binary
cut -b9-64    parse xxd output
tail -c +7    keep only the last 3 bits of `p`
tr -dc 1      keep only the `1`s
wc -c         count them
bc ...%2      modulo two

Girdi yoluyla <<<bir satır besleme karakteri eklenir, ancak paritesi çifttir \n, bu yüzden bir sorun değildir.

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.