Hasilkan sedikit paritas


18

Sebuah bit paritas , adalah salah satu bentuk yang paling sederhana dari checksum. Pertama, Anda harus memilih paritas, genap atau ganjil. Katakanlah kita memilih genap. Sekarang, kami membutuhkan pesan untuk dikirim. Katakanlah pesan kami adalah "Foo". Ini ditulis dalam biner sebagai:

01000110 01101111 01101111

Sekarang, kita menghitung jumlah total 1di sana, yaitu 15. Karena 15 adalah angka ganjil, kita harus menambahkan satu bit tambahan di akhir pesan kita, dan sekarang kita akan memiliki jumlah genap 'on' . Bit yang ditambahkan terakhir ini dikenal sebagai "bit paritas". Jika kami memilih paritas ganjil untuk checksum kami, kami harus menambahkan ekstra '0' sehingga jumlah bit on tetap aneh.

Tantangan:

Anda harus menulis program atau fungsi yang menentukan bit paritas yang benar untuk sebuah string. Program Anda harus mengambil dua input:

  • Sebuah string s,. Ini adalah pesan yang akan dihitung oleh checksum. Ini akan dibatasi untuk 95 karakter ASCII yang dapat dicetak.

  • Karakter atau string karakter tunggal p, yang akan euntuk paritas genap, atau ountuk paritas ganjil.

dan menghasilkan nilai true-falsey yang mewakili bit paritas yang benar. Sejujurnya jika itu adalah 1, dan palsu jika itu adalah 0.

Builtin yang menghitung jumlah bit "on" dalam string atau karakter tidak diperbolehkan. Misalnya, fungsi fyang melakukan ini: f('a') == 3atau f('foo') == 16diblokir. Hal lain, seperti konversi basis, adalah permainan yang adil.

Tes IO:

(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

Ini codegolf, jadi celah standar berlaku, dan jawaban tersingkat dalam byte menang.

Papan peringkat


10
Agak menyebalkan, obahkan paritas.
Neil

Bisakah Anda mengklarifikasi "Builtin yang menghitung jumlah bit" on "dalam string atau karakter tidak diizinkan." sedikit lebih baik? Bagaimana dengan konversi basis bawaan? Dll ..
orlp

@DrGreenEggsandHamDJ Komentar di situs Stack mudah berubah dan dapat menghilang tanpa peringatan tanpa alasan, atas kemauan pengguna yang mampu. Akibatnya, sangat dianjurkan bahwa spesifikasi yang tidak terpisahkan dari tantangan ada di pos itu sendiri, bukan di bagian komentar.
kucing

1
@cat Misalnya, di python: str(int(s, 2)).count('1')? Tidak, saya tidak akan menganggap itu sebagai fungsi builtin tunggal yang melanggar aturan itu. Apakah hasil edit saya membuatnya lebih jelas?
DJMcMayhem

1
@ kucing Sejauh yang saya ketahui char == single_char_string. Saya juga mengeditnya di posting.
DJMcMayhem

Jawaban:


9

MATL , 8 7 byte

8\hBz2\

Cobalah online! Atau verifikasi semua kasus uji sekaligus .

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 byte

Karena, Anda tahu, Jawa.

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

Ini adalah lambda untuk a BiFunction<String, Character, Boolean>.

edan otampaknya dibalik dalam pernyataan pengembalian karena ternyata logika saya terbalik.


5

Python 2, 51 byte

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

Ini didasarkan pada ide Sp3000 untuk menghitung 1 dalam representasi string dari daftar kode karakter dalam biner daripada menjumlahkan untuk setiap karakter.

Trik baru adalah menangani edan odalam hal ini juga. Jika eganjil dan ogenap, kita bisa menambahkan bit paritas ke string sebelum melakukan penghitungan (membalikkannya karena '1' adalah Truthy). Sayangnya tidak. Tetapi, jika kita menghapus semua kecuali dua bit terakhir mereka, sekarang benar.

e 0b11001|01
o 0b11011|11 

Ini dilakukan dengan menghapus 9karakter pertama dari representasi string.

['0b11001|01', 

Wow, itu cara penanganan yang sangat rapi eo!
Sp3000

4

Jelly, 9 8 byte

OBFSḂ⁼V}

Cobalah online!

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

Terima kasih kepada Dennis untuk satu byte!


1
Saya sendiri mencoba untuk memberikan jawaban Jelly, tetapi aturan chaining itu membuat saya kesal :-)
Luis Mendo

2
@LuisMendo saya berada di kapal yang sama; ini adalah jawaban Jelly pertamaku setelah mencoba mempelajarinya untuk ... terlalu lama: P
Doorknob

Itu V}... yang itu sangat keren !!! (Dennis adalah pegolf sejati) +1 Ini mengalahkan setiap upaya saya.
Erik the Outgolfer

4

C, 62 byte

  • 12 byte disimpan berkat @LevelRiverSt dan @TonHospel.

XOR memiliki properti bagus yang dapat digunakan untuk mengurangi string menjadi satu char, sekaligus menjaga paritas.

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 harus menghitung paritas p dan bahkan 1 byte lebih pendek
Ton Hospel

1
Ruang dalam char *stidak
diunggulkan

2
62 byte: f(s,p)char*s;{for(p/=8;*s;)p^=*s>>4^*s++;p^=p/4;return p%4%3;}The %3akan selalu kembali 0 untuk 0, tetapi bisa kembali 1 atau 2 untuk 1. Hal ini dapat diterima di bawah aturan:truthy if it's a 1
Tingkat Sungai St

1
27030>>((p^p>>4)&15)&1. Ya, tentu saja, err. ;-)
Digital Trauma

@LevelRiverSt Cemerlang! Terima kasih!
Trauma Digital

4

Python, 58 57 byte

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

1
53 (hanya Python 2):lambda s,p:`map(bin,map(ord,s))`.count('1')%2^(p>'e')
Sp3000

Anda dapat menyimpan byte dengan !=p>'e'.
xnor

Tunggu, byte-save saya tidak benar-benar berfungsi karena Python memperlakukannya sebagai ketidakmerataan berantai.
xnor

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

@ xnor Cukup kirim jawaban Anda sendiri.
orlp

3

Pyth, 12 byte

q@"oe"sjCz2w

Suite uji.

         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 byte

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

Sedikit twiddling ternyata lebih pendek daripada mengkonversi ke basis 2 dan menghitung 1s.


2

Perl, 29 byte

Termasuk +2 untuk -p

Jalankan dengan input pada STDIN sebagai string spasi karakter paritas, mis

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

parity.pl

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

2

J, 27 byte

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

Pemakaian

   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 byte

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

1

PowerShell v2 +, 91 byte

Saya menangis di sudut

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

Ya ... jadi, konversi basis tidak cocok untuk PowerShell. Konversi dari string input ke representasi biner $a|%{[convert]::toString(+$_,2)}adalah 32 byte dalam dan dari dirinya sendiri ...

Mengambil input $adan $b, secara eksplisit melakukan casting $asebagai char-array dalam proses. Kami kemudian memeriksa apakah $badalah -eqUAL untuk o, dan -xorbahwa dengan bagian lain dari program tersebut. Untuk bagian itu, kita ambil string input $a, pipa itu melalui loop untuk mengubah setiap huruf menjadi biner, -joinsemua itu bersama-sama membentuk satu string yang solid, dan -replacesemua 0itu tanpa apa-apa. Kami kemudian menghitung .lengthstring itu dan mengambilnya mod-2 untuk menentukan apakah itu genap atau ganjil, yang akan mudah 0atau tidak1 sempurna untuk -xor.

Akan kembali Trueatau Falsesesuai. Lihat uji kasus di bawah ini:

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

Faktor, 85 byte

Untuk beberapa alasan saya tidak dapat membungkus kepala saya dengan yang ini sampai beberapa menit yang lalu, ketika saya menyederhanakan (dan mungkin mempersingkat?) Kodenya.

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

?seperti operator ternary: ia menguji kebenaran item tumpukan ketiga, dan memilih truenilai atau falsenilainya.

Ini kira-kira sama dengan pseduocode mirip-C berikut:

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

Sisa kode ini cukup sederhana:

[                       ! 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

Kode mesin IA-32, 15 byte

Hexdump:

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

Kode perakitan:

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

Ini adalah fungsi yang menerima argumen pertama (string) di ecxdan argumen kedua (char) di dl. Ini mengembalikan hasilnya eax, jadi itu kompatibel denganfastcall konvensi pemanggilan.

Kode ini membengkokkan aturan ketika menggunakan setpoinstruksi:

Builtin yang menghitung jumlah bit "on" dalam string atau karakter tidak diperbolehkan

Instruksi ini diatur alke bit paritas yang dihitung oleh instruksi sebelumnya - jadi saya punya dua nitpicks ini pada aturan:

  • Itu tidak menghitung jumlah bit "pada" - itu menghitung bit paritas secara langsung!
  • Secara teknis, ini adalah instruksi sebelumnya ( xor) yang menghitung bit paritas. The setpoinstruksi hanya bergerak ke almendaftar.

Rincian semantik ini tidak ada artinya, berikut adalah penjelasan tentang apa yang dilakukan kode.

Representasi karakter adalah:

'e' = 01100101
'o' = 01101111

Jika kita menambahkan 1 padanya, mereka memiliki paritas yang tepat:

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

Jadi kita XORsemua karakter string, menginisialisasi alnilai-nilai ini, yang memberikan jawabannya.


Instruksi pertama movzx eax, dlbukannya yang lebih jelas (dan lebih pendek) mov al, dl, karena saya ingin memiliki angka 0 dalam register ( ahdalam hal ini) agar dapat membandingkannya dengan urutan yang benar ( 0, [ecx]bukan [ecx], 0).


1

Julia, 58 47 45 40 byte

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

Ini adalah fungsi yang menerima string dan karakter dan mengembalikan integer.

Untuk mendapatkan jumlah yang ada dalam representasi biner, pertama-tama kita menerapkan binfungsi ke setiap karakter dalam string, yang memberi kita array dari string biner. Kemudian kurangi menjadi satu menggunakan prod(karena *merupakan rangkaian string dalam Julia) dan ambil persimpangan set string itu dan kode karakter untuk 1, yang memberi kita string yang. Indeks terakhir dari string itu adalah jumlah. Kami XOR ini dengan 1 jika karakter yang disediakan adalah o dan 0 sebaliknya, maka dapatkan paritas menggunakan bitwise AND 1.

Cobalah online!(termasuk semua kasus uji)

Disimpan 18 byte berkat Dennis!


1

05AB1E , 15 , 13 byte

Kode:

€ÇbSOÈ„oe²k<^

Input Contoh:

Programming Puzzles and Code-Golf
o

Contoh Output:

1

Penjelasan:

€                 # 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 È

Terima kasih kepada Adnan karena telah menghemat 2 byte.


Wow sangat bagus! Anda dapat bermain golf dua byte dengan menggunakan ²perintah. Ini secara otomatis mendorong input kedua di atas tumpukan. Juga, string dua-char dapat disingkat menggunakan . Jadi "oe"setara dengan . Untuk 13 byte: €ÇbSOÈ„oe²k<^:)
Adnan

05AB1E juga menggunakan encoding CP-1252 , sehingga setiap karakter di sini adalah 1 byte :).
Adnan

@ Adnan: Terima kasih! Menggunakan notepad ++ untuk bytecount dan hanya berasumsi bahwa itu menghitung karakter: P
Emigna

0

Ruby, 57 byte

Jika 0itu falsey di Ruby, ==mungkin bisa dialihkan ke adil -, atau mungkin ada optimasi lain, tetapi tidak.

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

0

Retina , 102 byte

Mengambil string di baris pertama, dan huruf di baris kedua. Menggunakan penyandian ISO 8859-1.

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

Cobalah online

Kelas karakter pada baris pertama cocok dengan karakter apa pun dengan jumlah ganjil dalam representasi biner.

Deskripsi tentang deteksi genap / ganjil dengan regex bekerja di sini .


0

Oktaf, 56 byte

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

Itu bitunpack fungsi, untuk karakter ASCII, mengembalikan mereka dalam rangka little-endian. Jadi dengan meletakkan bendera paritas di akhir string kita, membongkar semuanya, dan menjatuhkan 5 bit terakhir, kita kemudian dapat meringkas seluruh hal mod 2 untuk jawaban akhir kita.

Pemakaian:

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

0

 Common Lisp, 87

(lambda(s p)(=(mod(reduce'+(mapcar'logcount(map'list'char-code s)))2)(position p"oe")))
  • Jumlah log-kode char-kode dari s.
  • Sisa dari ini, ketika dibagi dengan 2, dibandingkan dengan posisi argumen paritas pdalam string "oe"(0 atau 1). Misalnya, jika ada 4 yang, sisanya adalah nol. Jika p o, maka tidak ada bit tambahan yang harus ditambahkan, dan tes kembali salah.

Dicetak cantik

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

0

Java, 91 byte

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

Saya melakukan hal yang sama seperti @ CAT97, tetapi menelanjangi beberapa karakter dengan menggunakan modulo 8 dan menggabungkan @Luis Mendo dan penggunaan int bukan boolean.

Ini adalah lambda untuk a BiFunction<String, Character, Boolean>.


0

Matlab, 49 byte

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

dimana:

  • x adalah string input;
  • p adalah 'e' untuk paritas genap dan 'o' untuk yang ganjil.

Sebagai contoh:

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

ans =

     0

0

Alat Bash dan unix (72 byte)

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

Kecuali ssebagai argumen pertama dan pkedua. Untungnya terakhir 3 bit odan ememiliki paritas ganjil dan genap masing-masing.

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

Memasok input melalui <<<menambahkan karakter umpan baris, tetapi paritasnya \ngenap, jadi itu bukan masalah.

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.