Genera un bit di parità


18

Un po 'di parità , è una delle forme più semplici di un checksum. Innanzitutto, devi scegliere la parità, pari o dispari. Diciamo che scegliamo pari. Ora, abbiamo bisogno di un messaggio da trasmettere. Diciamo che il nostro messaggio è "Foo". Questo è scritto in binario come:

01000110 01101111 01101111

Ora contiamo il numero totale di 1'in', che è 15. Dato che 15 è un numero dispari, dobbiamo aggiungere un bit in più alla fine del nostro messaggio e ora avremo un numero pari di 'on' bit . Quest'ultimo bit aggiunto è noto come "bit di parità". Se avessimo scelto una parità dispari per il nostro checksum, avremmo aggiunto un ulteriore "0" in modo che il numero di bit on rimanga dispari.

La sfida:

È necessario scrivere un programma o una funzione che determina quale sia il bit di parità corretto per una stringa. Il tuo programma deve avere due input:

  • Una stringa, s. Questo è il messaggio su cui verrà calcolato il checksum. Questo sarà limitato ai 95 caratteri ASCII stampabili.

  • Una stringa di caratteri o caratteri singoli p, che sarà eper parità pari o oper parità dispari.

e produce un valore di verità-falsità che rappresenta il bit di parità corretto. Verità se è una 1e falsità se è una 0.

I builtin che contano il numero di bit "on" in una stringa o in un carattere non sono consentiti. Ad esempio, una funzione fche fa ciò: f('a') == 3o f('foo') == 16è vietata. Qualsiasi altra cosa, come la conversione di base, è un gioco equo.

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

Questo è codegolf, quindi si applicano scappatoie standard e vince la risposta più breve in byte.

Classifica


10
Piuttosto fastidioso, oha anche la parità.
Neil,

Puoi chiarire "Non sono ammessi i builtin che contano il numero di" on "bit in una stringa o in un carattere." un po 'meglio? Che dire della conversione di base integrata? Ecc.
orlp

@DrGreenEggsandHamDJ I commenti sui siti Stack sono volatili e soggetti a sparire senza preavviso senza motivo, per capriccio di qualsiasi utente abile. Di conseguenza, è fortemente incoraggiato che le specifiche integrali della sfida siano nel post stesso, non nella sezione commenti.
gatto

1
@cat Per esempio, in pitone: str(int(s, 2)).count('1')? No, non la considero una singola funzione integrata che viola tale regola. La mia modifica lo rende più chiaro?
DJMcMayhem

1
@cat Per quanto mi riguarda char == single_char_string. L'ho anche modificato nel post.
DJMcMayhem

Risposte:


9

MATL , 8 7 byte

8\hBz2\

Provalo online! Oppure verifica tutti i casi di test contemporaneamente .

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

Perché, sai, 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;}

Questo è un lambda per a BiFunction<String, Character, Boolean>.

ee osembrano essere invertiti nell'istruzione return perché apparentemente la mia logica era all'indietro.


5

Python 2, 51 byte

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

Questo si basa sull'idea di Sp3000 di contare 1 nella rappresentazione in forma di stringa dell'elenco di codici di caratteri in formato binario anziché somma per ogni carattere.

Il nuovo trucco è gestire ee anche oin questo. Se efosse pari e dispari o, potremmo semplicemente anteporre il bit di parità alla stringa prima di fare il conteggio (girandoli perché '1' è Verità). Sfortunatamente, non lo sono. Ma, se rimuoviamo tutti tranne i loro ultimi due bit, ora è vero.

e 0b11001|01
o 0b11011|11 

Questo viene fatto rimuovendo il primo 9carattere della rappresentazione di stringa.

['0b11001|01', 

Wow, è un modo davvero semplice di gestirlo eo!
Sp3000,

4

Gelatina, 9 8 byte

OBFSḂ⁼V}

Provalo 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

Grazie a Dennis per un byte!


1
Stavo cercando di trovare una risposta da Jelly, ma quelle regole del concatenamento mi eludono :-)
Luis Mendo,

2
@LuisMendo Sono nella stessa barca; questa è la mia prima risposta di Jelly dopo aver cercato di impararla per ... troppo tempo: P
Maniglia della porta

Quello V}... quello era davvero bello !!! (Dennis è un vero giocatore di golf) +1 Ha battuto ogni mio tentativo.
Erik the Outgolfer,

4

C, 62 byte

  • 12 byte salvati grazie a @LevelRiverSt e @TonHospel.

XOR ha la bella proprietà che può essere utilizzato per ridurre le stringhe fino a un carattere, preservando la parità.

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 dovrebbe calcolare la parità di p ed è anche più breve di 1 byte
Ton Hospel il

1
Lo spazio char *sè libero
Ton Hospel,

2
62 byte: f(s,p)char*s;{for(p/=8;*s;)p^=*s>>4^*s++;p^=p/4;return p%4%3;}The %3sarà sempre restituire 0 per un 0, ma può restituire 1 o 2 per un 1. Questo è accettabile secondo le regole:truthy if it's a 1
livello del fiume St

1
27030>>((p^p>>4)&15)&1. Bene, ovviamente, ovviamente. ;-)
Digital Trauma,

@LevelRiverSt Brilliant! Grazie!
Trauma digitale,

4

Python, 58 57 byte

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

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

È possibile salvare un byte con !=p>'e'.
xnor

Aspetta, il mio byte-save in realtà non funziona perché Python lo considera una disuguaglianza incatenata.
xnor

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

@xnor Basta pubblicare la tua risposta.
orlp,

3

Pyth, 12 byte

q@"oe"sjCz2w

Suite di test.

         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

La modifica dei bit si è rivelata più breve rispetto alla conversione in base 2 e al conteggio di 1s.


2

Perl, 29 byte

Include +2 per -p

Esegui con l'input su STDIN come stringa di spazio del carattere di parità, ad es

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:@]

uso

   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

/ me piange in un angolo

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

Sì ... quindi, la conversione di base non è adatta per PowerShell. La conversione dalla stringa di input alla rappresentazione binaria$a|%{[convert]::toString(+$_,2)} è di 32 byte in sé e per sé ...

Accetta input $ae $b, esplicitamente, esegue $ail cast come char-array nel processo. Quindi controlliamo se $bè -eqnormale oe -xorquello con l'altra metà del programma. Per quella parte, prendiamo la stringa di input, la inseriamo $ain un ciclo per convertire ogni lettera in binario, -jointutte quelle insieme per formare una stringa solida e -replacetutte le 0s senza nulla. Quindi contiamo la .lengthstringa di quella stringa e la prendiamo mod-2 per determinare se è pari o dispari, che sarà convenientemente 0o1 , perfetto per il-xor .

Tornerà Trueo di Falseconseguenza. Vedi i casi di test di seguito:

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

Fattore, 85 byte

Per qualche motivo non ho potuto avvolgere la testa intorno a questo fino a pochi minuti fa, quando ho semplificato (e forse abbreviato?) Il codice.

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

?è come un operatore ternario: verifica la veridicità del terzo oggetto dello stack e seleziona il truevalore o il falsevalore.

È approssimativamente equivalente al seguente pseduocode simile a C:

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

Il resto del codice è piuttosto semplice:

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

Codice macchina IA-32, 15 byte

hexdump:

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

Codice dell'Assemblea:

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

Questa è una funzione che riceve il suo primo argomento (stringa) in ecxe il secondo argomento (carattere) in dl. Restituisce il risultato eax, quindi è compatibile confastcall convenzione di chiamata.

Questo codice piega le regole quando utilizza l' setpoistruzione:

I builtin che contano il numero di bit "on" in una stringa o in un carattere non sono consentiti

Questa istruzione imposta alil bit di parità calcolato dall'istruzione precedente, quindi ho questi due suggerimenti sulle regole:

  • Non conta il numero di bit "on" - calcola direttamente il bit di parità!
  • Tecnicamente, è l'istruzione precedente ( xor) che calcola il bit di parità. L' setpoistruzione lo sposta solo nel alregistro.

Questi dettagli semantici fuori mano, ecco la spiegazione su cosa fa il codice.

Le rappresentazioni dei personaggi sono:

'e' = 01100101
'o' = 01101111

Se aggiungiamo 1 a loro, capita che abbiano la giusta parità:

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

Quindi abbiamo XORtutti i caratteri della stringa, inizializzandoli ala questi valori, che danno la risposta.


La prima istruzione è movzx eax, dlinvece della più ovvia (e più breve) mov al, dl, perché voglio avere il numero 0 in un registro ( ahin questo caso) per poterlo confrontare nell'ordine giusto ( 0, [ecx]piuttosto che [ecx], 0).


1

Julia, 58 47 45 40 byte

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

Questa è una funzione che accetta una stringa e un carattere e restituisce un numero intero.

Per ottenere il numero di quelli nella rappresentazione binaria, applichiamo prima la binfunzione a ciascun carattere nella stringa, che ci fornisce una matrice di stringhe binarie. Quindi riducili in uno usando prod(poiché *è la concatenazione di stringhe in Julia) e prendi l'intersezione impostata di quella stringa e il codice carattere per 1, che ci fornisce una stringa di quelli. L'ultimo indice di quella stringa è il numero di quelli. XOR questo con 1 se il carattere fornito è o e 0 altrimenti, quindi otteniamo la parità usando bit a bit AND 1.

Provalo online!(include tutti i casi di test)

Risparmiato 18 byte grazie a Dennis!


1

05AB1E , 15 , 13 byte

Codice:

€ÇbSOÈ„oe²k<^

Esempio di input:

Programming Puzzles and Code-Golf
o

Esempio di output:

1

Spiegazione:

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

Grazie ad Adnan per aver salvato 2 byte.


Wow molto bello! Puoi giocare a golf di due byte usando il ²comando. Questo spinge automaticamente il secondo input in cima allo stack. Inoltre, è possibile abbreviare le stringhe a due caratteri usando . Quindi "oe"è equivalente a . Per 13 byte: €ÇbSOÈ„oe²k<^:)
Adnan,

05AB1E usa anche codifica CP-1252 , quindi ogni carattere qui è 1 byte :).
Adnan,

@Adnan: grazie! Ho usato Notepad ++ per il bytecount e ho appena ipotizzato che contasse i caratteri: P
Emigna,

0

Rubino, 57 byte

Se 0fosse un falso in Ruby, ==probabilmente potrebbe essere commutato solo -o potrebbero esserci altre ottimizzazioni, ma non lo è.

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

0

Retina , 102 byte

Prende la stringa sulla prima riga e la lettera sulla seconda riga. Utilizza la codifica ISO 8859-1.

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

Provalo online

La classe di caratteri sulla prima riga corrisponde a qualsiasi carattere con un numero dispari di quelli nella rappresentazione binaria.

Descrizione di come anche / dispari rilevamento con regex lavora qui .


0

Ottava, 56 byte

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

Il bitunpack funzione, per i caratteri ASCII, li restituisce in ordine little-endian. Quindi mettendo il flag di parità alla fine della nostra stringa, spacchettando il tutto e rilasciando gli ultimi 5 bit, possiamo quindi riassumere il tutto mod 2 per la nostra risposta definitiva.

Uso:

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

0

 Lisp comune, 87

(lambda(s p)(=(mod(reduce'+(mapcar'logcount(map'list'char-code s)))2)(position p"oe")))
  • Somma il conteggio dei log dei codici caratteri di s .
  • Il resto di questo, quando diviso per 2, viene confrontato con la posizione dell'argomento di parità pnella stringa "oe"(0 o 1). Ad esempio, se ce ne sono 4, il resto è zero. Se p lo è o, non è necessario aggiungere alcun bit aggiuntivo e il test restituisce false.

Pretty-stampati

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

Ho fatto lo stesso di @ CAT97, ma ho eliminato alcuni caratteri usando il modulo 8 e il concatenato di @Luis Mendo e l'uso di int invece di booleano.

Questo è un lambda per a BiFunction<String, Character, Boolean>.


0

Matlab, 49 byte

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

dove:

  • x è la stringa di input;
  • p è 'e' per parità pari e 'o' per quello dispari.

Per esempio:

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

ans =

     0

0

Strumenti di Bash e Unix (72 byte)

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

Tranne scome primo e pcome secondo argomento. Fortunatamente gli ultimi 3 bit di oe ehanno parità pari e dispari rispettivamente.

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

Fornire l'input tramite <<<aggiunge un carattere di avanzamento riga, ma la parità di \nè pari, quindi non è un problema.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.