Wygeneruj bit parzystości

18

Bit parzystości , jest jedną z najprostszych postaci sumy kontrolnej. Najpierw musisz wybrać parzystość, parzystą lub nieparzystą. Powiedzmy, że wybieramy nawet. Teraz potrzebujemy wiadomości do przesłania. Powiedzmy, że nasza wiadomość to „Foo”. Jest to zapisane binarnie jako:

01000110 01101111 01101111

Teraz liczymy całkowitą liczbę 1tam, czyli 15. Ponieważ 15 jest liczbą nieparzystą, musimy dodać jeden dodatkowy bit na końcu naszej wiadomości, a teraz będziemy mieć parzystą liczbę bitów włączonych . Ten ostatni dodany bit jest znany jako „bit parzystości”. Gdybyśmy wybrali nieparzystą parzystość dla naszej sumy kontrolnej, musielibyśmy dodać dodatkowe „0”, aby liczba bitów pozostała nieparzysta.

Wyzwanie:

Musisz napisać program lub funkcję, która określa poprawny bit parzystości dla łańcucha. Twój program musi przyjmować dwa dane wejściowe:

  • Ciąg, s. Jest to komunikat, na podstawie którego zostanie obliczona suma kontrolna. Będzie to ograniczone do 95 drukowalnych znaków ASCII.

  • Znak lub ciąg znaków składający psię ez parzystej lub onieparzystej parzystości.

i wygeneruj wartość true-falsey reprezentującą właściwy bit parzystości. Prawda, jeśli to jest 1, i falsey, jeśli to jest 0.

Wbudowane liczące liczbę „włączonych” bitów w ciągu lub znaku są niedozwolone. Na przykład funkcja f, która to robi: f('a') == 3lub f('foo') == 16jest zbanowana. Wszystko inne, na przykład konwersja bazy, jest uczciwą grą.

Test 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

Jest to kodegolf, więc obowiązują standardowe luki i wygrywa najkrótsza odpowiedź w bajtach.

Tabela liderów

DJMcMayhem
źródło
10
Raczej denerwująco, oma nawet parzystość.
Neil,
Czy możesz wyjaśnić, że „Wbudowane liczące liczbę bitów„ on ”w ciągu lub znaku są niedozwolone.” trochę lepiej? Co z wbudowaną konwersją podstawową? Itd ..
orlp
@DrGreenEggsandHamDJ Komentarze na temat stron stosu są niestabilne i mogą zniknąć bez ostrzeżenia bez powodu, według kaprysu każdego zdolnego użytkownika. W związku z tym bardzo zaleca się, aby specyfikacje integralne dla wyzwania znajdowały się w samym poście, a nie w sekcji komentarzy.
kot
1
@cat Na przykład w Pythonie: str(int(s, 2)).count('1')? Nie, nie uważałbym tego za pojedynczą wbudowaną funkcję, która narusza tę zasadę. Czy moja edycja jest bardziej przejrzysta?
DJMcMayhem
1
@cat O ile mi wiadomo char == single_char_string. Zredagowałem to również w poście.
DJMcMayhem

Odpowiedzi:

9

MATL , 8 7 bajtów

8\hBz2\

Wypróbuj online! Lub zweryfikuj wszystkie przypadki testowe jednocześnie .

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
Luis Mendo
źródło
9

Java, 97 bajtów

Ponieważ, wiesz, 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;}

To jest lambda dla BiFunction<String, Character, Boolean>.

ei owydają się być odwrócone w instrukcji return, ponieważ najwyraźniej moja logika była wsteczna.

CAD97
źródło
5

Python 2, 51 bajtów

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

Jest to oparte na pomyśle Sp3000, aby liczyć jedynki w reprezentacji ciągu listy kodów znaków w postaci binarnej zamiast sumowania dla każdego znaku.

Nową sztuczką jest poradzenie sobie erównież ow tym. Jeśli ebyło nieparzyste i oparzyste, moglibyśmy po prostu wstawić bit parzystości do łańcucha przed wykonaniem liczenia (odwracanie ich, ponieważ „1” jest Prawdą). Niestety nie są. Ale jeśli usuniemy wszystkie oprócz ostatnich dwóch bitów, teraz jest to prawdą.

e 0b11001|01
o 0b11011|11 

Odbywa się to poprzez usunięcie pierwszego 9znaku reprezentacji ciągu.

['0b11001|01', 
xnor
źródło
Wow, to naprawdę fajny sposób obsługi eo!
Sp3000 27.04.16
4

Galaretka, 9 8 bajtów

OBFSḂ⁼V}

Wypróbuj 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

Dzięki Dennis za bajt!

Klamka
źródło
1
Sam próbowałem wymyślić odpowiedź galaretki, ale te łańcuchowe zasady mnie wykluczają :-)
Luis Mendo
2
@LuisMendo Jestem w tej samej łodzi; to moja pierwsza odpowiedź na żelki po tym, jak próbowałem się tego nauczyć ... o wiele za długo: P
Klamka
Ten V}... ten był naprawdę fajny !!! (Dennis jest prawdziwym golfistą) +1 Pokonał każdą moją próbę.
Erik the Outgolfer
4

C, 62 bajty

  • 12 bajtów zapisanych dzięki @LevelRiverSt i @TonHospel.

XOR ma niezłą właściwość, którą można wykorzystać do zmniejszenia ciągów znaków do jednego znaku, przy jednoczesnym zachowaniu parzystości.

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

Ideone.

Cyfrowa trauma
źródło
1
27030>>((p^p>>4)&15)&1 powinien obliczyć parzystość p, a jest nawet 1 bajt krótszy
Ton Hospel 26.04.16
1
Przestrzeń w char *sśrodku jest niepotrzebna
Ton Hospel,
2
62 bajtów: zawsze powróci 0 do 0, ale może wrócić 1 lub 2 do 1. Jest to dopuszczalne zgodnie z zasadami:f(s,p)char*s;{for(p/=8;*s;)p^=*s>>4^*s++;p^=p/4;return p%4%3;}%3truthy if it's a 1
Poziom rzeki St
1
27030>>((p^p>>4)&15)&1. Cóż, oczywiście. ;-)
Cyfrowa trauma
@LevelRiverSt Brilliant! dzięki!
Cyfrowa trauma
4

Python, 58 57 bajtów

lambda s,p:sum(bin(ord(c)).count("1")for c in s)&1!=p>'e'
orlp
źródło
1
53 (tylko Python 2):lambda s,p:`map(bin,map(ord,s))`.count('1')%2^(p>'e')
Sp3000,
Możesz zapisać bajt za pomocą !=p>'e'.
XNOR
Czekaj, moje zapisywanie bajtów tak naprawdę nie działa, ponieważ Python traktuje to jako nierówność łańcuchową.
xnor 26.04.16
lambda s,p:`map(bin,map(ord,p+s))`[8:].count('1')%2
xnor 26.04.16
@xnor Po prostu opublikuj swoją odpowiedź.
orlp
3

Pyth, 12 bajtów

q@"oe"sjCz2w

Zestaw testowy.

         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
Klamka
źródło
3

JavaScript (ES6), 84 72 bajtów

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

Kręcenie bitów okazało się krótsze niż konwersja do bazy 2 i liczenie 1s.

Neil
źródło
2

Perl, 29 bajtów

Obejmuje +2 za -p

Uruchom z danymi wejściowymi STDIN jako ciągiem znaków parzystości, np

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

parity.pl

#!/usr/bin/perl -p
$_=unpack"B*",$_|b;$_=1&y;1;
Ton Hospel
źródło
2

J, 27 bajtów

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

Stosowanie

   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
mile
źródło
1

JavaScript (ES6), 69 bajtów

(s,p)=>[...s].map(c=>{for(n=c.charCodeAt();n;n>>=1)r^=n&1},r=p>"e")|r
użytkownik 81655
źródło
1

PowerShell v2 +, 91 bajtów

/ ja płacze w kącie

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

Tak ... więc konwersja bazy nie jest silnym atutem dla PowerShell. Konwersja ciągu wejściowego na reprezentację binarną $a|%{[convert]::toString(+$_,2)}ma 32 bajty sama w sobie ...

Pobiera dane wejściowe $ai $bjawnie rzutuje $ajako tablicę znaków w procesie. Następnie sprawdzamy, czy $bjest to -eqprzydatne o, i -xorto z drugą połową programu. W tej części bierzemy ciąg wejściowy $a, przepuszczamy go przez pętlę, aby przekonwertować każdą literę na binarną, -joinwszystkie razem, tworząc jeden ciąg ciągły, i -replacewszystkie 0s bez niczego. Następnie liczymy .lengthten ciąg i bierzemy mod-2, aby ustalić, czy jest parzysty czy nieparzysty, co dogodnie będzie albo, 0albo 1idealne dla-xor .

Wróci Truelub Falseodpowiednio. Zobacz przypadki testowe poniżej:

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
AdmBorkBork
źródło
1

Współczynnik, 85 bajtów

Z jakiegoś powodu nie mogłem owinąć głowy nim jeszcze kilka minut temu, kiedy uprościłem (a może skróciłem?) Kod.

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

?jest jak trójskładnikowy: sprawdza prawdziwość trzeciego elementu stosu i wybiera truewartość lub wartośćfalse wartość.

Jest to w przybliżeniu odpowiednik następującego pseduokodu typu C:

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

Reszta kodu jest dość prosta:

[                       ! 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.
kot
źródło
1

Kod maszynowy IA-32, 15 bajtów

Hexdump:

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

Kod zestawu:

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

Jest to funkcja, która odbiera swój pierwszy argument (ciąg) ecxi drugi argument (char) wdl . Zwraca wynik eax, więc jest zgodny z fastcallkonwencją wywoływania.

Ten kod zgina reguły, gdy używa setpo instrukcji:

Wbudowane liczące liczbę „włączonych” bitów w ciągu lub znaku są niedozwolone

Ta instrukcja ustawia al bit parzystości obliczony przez poprzednią instrukcję - więc mam te dwa nitpicks na regułach:

  • Nie liczy liczby bitów „włączonych” - bezpośrednio oblicza bit parzystości!
  • Technicznie rzecz biorąc, poprzednia instrukcja ( xor) oblicza bit parzystości. setpoInstrukcja tylko przenosi go do alrejestru.

Te szczegóły semantyczne na marginesie, oto wyjaśnienie, co robi kod.

Reprezentacje postaci to:

'e' = 01100101
'o' = 01101111

Jeśli dodamy do nich 1, będą one miały odpowiednią parzystość:

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

Więc my XORwszyscy znaki ciągu, inicjując się aldo tych wartości, co daje odpowiedź.


Pierwsza instrukcja jest movzx eax, dlbardziej oczywista (i krótsza) mov al, dl, ponieważ chcę mieć liczbę 0 w rejestrze ( ahw tym przypadku), aby móc porównać ją w odpowiedniej kolejności ( 0, [ecx]zamiast [ecx], 0).

anatolig
źródło
1

Julia, 58 47 45 40 bajtów

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

Jest to funkcja, która akceptuje ciąg i znak i zwraca liczbę całkowitą.

Aby uzyskać liczbę jedynek w reprezentacji binarnej, najpierw stosujemy binfunkcję do każdego znaku w ciągu, co daje nam tablicę ciągów binarnych. Następnie zredukuj je do jednego za pomocą prod(ponieważ *Julia jest konkatenacją łańcucha) i weź ustawione przecięcie tego łańcucha i kod znaku 1, co daje nam ciąg jednych. Ostatni indeks tego ciągu to liczba jedynek. XOR to 1, jeśli podana postać to o i 0 w przeciwnym razie, to uzyskać za pomocą bitowego parzystości i 1.

Wypróbuj online!(obejmuje wszystkie przypadki testowe)

Zaoszczędź 18 bajtów dzięki Dennisowi!

Alex A.
źródło
1

05AB1E , 15 , 13 bajtów

Kod:

€ÇbSOÈ„oe²k<^

Przykładowe dane wejściowe:

Programming Puzzles and Code-Golf
o

Przykładowe dane wyjściowe:

1

Wyjaśnienie:

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

Dzięki Adnan za oszczędność 2 bajtów.

Emigna
źródło
Wow bardzo fajnie! Możesz zagrać w golfa o dwa bajty za pomocą ²polecenia. To automatycznie wypycha drugie wejście na wierzch stosu. Również ciągi dwuznakowe można skracać za pomocą . Więc "oe"jest równoważna . Dla 13 bajtów: €ÇbSOÈ„oe²k<^:)
Adnan
05AB1E wykorzystuje również kodowanie CP-1252 , więc każdy znak ma tutaj 1 bajt :).
Adnan
@Adnan: Dzięki! Użyłem notatnika ++ do bajtecount i po prostu założyłem, że liczy znaki: P
Emigna
0

Rubinowy, 57 bajtów

Jeśli 0w Ruby był falsey, ==prawdopodobnie można go zmienić na just -, lub mogą istnieć inne optymalizacje, ale tak nie jest.

->s,b{s.gsub(/./){$&.ord.to_s 2}.count(?1)%2==(b>?i?0:1)}
Wartość tuszu
źródło
0

Siatkówka , 102 bajty

Bierze ciąg w pierwszym wierszu, a litera w drugim wierszu. Wykorzystuje kodowanie ISO 8859-1.

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

Wypróbuj online

Klasa znaków w pierwszym wierszu odpowiada dowolnemu znakowi z nieparzystą liczbą jedności w reprezentacji binarnej.

Opis działania detekcji parzystej / nieparzystej z wyrażeniem regularnym tutaj .

mbomb007
źródło
0

Oktawa, 56 bajtów

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

bitunpackFunkcja, dla znaków ASCII, zwraca je w ostrokońcej kolejności. Tak więc, umieszczając flagę parzystości na końcu naszego ciągu, rozpakowując całość i upuszczając ostatnie 5 bitów, możemy następnie podsumować cały mod 2 dla naszej ostatecznej odpowiedzi.

Stosowanie:

octave:137> f('Hello World!', 'o')
ans = 0
octave:138> f('Hello World!', 'e')
ans =  1
dcsohl
źródło
0

 Common Lisp, 87

(lambda(s p)(=(mod(reduce'+(mapcar'logcount(map'list'char-code s)))2)(position p"oe")))
  • Zsumuj logcount kodów znaków z s.
  • Pozostała część, podzielona przez 2, jest porównywana z pozycją argumentu parzystości pw ciągu "oe"(0 lub 1). Na przykład, jeśli są 4, reszta to zero. Jeśli p jest o, to nie należy dodawać żadnego dodatkowego bitu, a test zwraca false.

Dość drukowane

(lambda (s p)
  (= (mod (reduce '+ (mapcar 'logcount (map 'list 'char-code s))) 2)
     (position p "oe")))
rdzeń rdzeniowy
źródło
0

Java, 91 bajtów

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

Zrobiłem to samo co @ CAT97, ale usunąłem niektóre postacie, używając modulo 8 i konkatenacji @Luis Mendo i użycia int zamiast boolean.

To jest lambda dla BiFunction<String, Character, Boolean>.

miselico
źródło
0

Matlab, 49 bajtów

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

gdzie:

  • x jest łańcuchem wejściowym;
  • p oznacza „e” dla parzystej parzystości i „o” dla nieparzystej.

Na przykład:

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

ans =

     0
PieCot
źródło
0

Narzędzia Bash i Unix (72 bajty)

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

Z wyjątkiem spierwszego i pdrugiego argumentu. Na szczęście ostatnie 3 bity oi eposiada parzyste i nieparzyste parytetu odpowiednio.

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

Podanie danych wejściowych przez <<<dodaje znak przesunięcia wiersza, ale parzystość \njest parzysta, więc nie stanowi problemu.

pgy
źródło