Generar un bit de paridad

18

Un bit de paridad es una de las formas más simples de suma de verificación. Primero, debes elegir la paridad, par o impar. Digamos que elegimos incluso. Ahora, necesitamos un mensaje para transmitir. Digamos que nuestro mensaje es "Foo". Esto está escrito en binario como:

01000110 01101111 01101111

Ahora, contamos el número total de 1's allí, que es 15. Dado que 15 es un número impar, debemos agregar un bit extra al final de nuestro mensaje, y ahora tendremos un número par de bits' on ' . Este último bit agregado se conoce como el "bit de paridad". Si hubiéramos elegido una paridad impar para nuestra suma de verificación, tendríamos que agregar un '0' adicional para que el número de bits permanezca impar.

El reto:

Debe escribir un programa o función que determine cuál es el bit de paridad correcto para una cadena. Su programa debe tomar dos entradas:

  • Una cadena, s. Este es el mensaje sobre el que se calculará la suma de verificación. Esto estará restringido a los 95 caracteres ASCII imprimibles.

  • Un carácter o cadena de un solo carácter p, que será epara paridad par o oparidad impar.

y produce un valor verdadero-falso que representa el bit de paridad correcto. Verdad si es un 1, y falsey si es un 0.

No se permiten las unidades integradas que cuentan el número de bits "encendidos" en una cadena o carácter. Por ejemplo, una función fque hace esto: f('a') == 3o f('foo') == 16está prohibida. Cualquier otra cosa, como la conversión de base, es un juego justo.

Prueba 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

Esto es codegolf, por lo que se aplican las lagunas estándar y gana la respuesta más corta en bytes.

Tabla de clasificación

DJMcMayhem
fuente
10
Bastante molesto, oincluso tiene paridad.
Neil
¿Puede aclarar " No se permiten los builtins que cuentan el número de bits" en "en una cadena o carácter". ¿Un poco mejor? ¿Qué pasa con la conversión de base incorporada? Etc ..
orlp
@DrGreenEggsandHamDJ Los comentarios sobre los sitios de Stack son volátiles y están sujetos a desaparecer sin previo aviso sin ningún motivo, a voluntad de cualquier usuario capacitado. Como resultado, se recomienda encarecidamente que las especificaciones integrales del desafío estén en la publicación misma, no en la sección de comentarios.
gato
1
@cat Por ejemplo, en python str(int(s, 2)).count('1'):? No, no consideraría que se trata de una única función integrada que viola esa regla. ¿Mi edición lo hace más claro?
DJMcMayhem
1
@cat En lo que a mí respecta char == single_char_string. También lo edité en la publicación.
DJMcMayhem

Respuestas:

9

MATL , 8 7 bytes

8\hBz2\

Pruébalo en línea! O verifique todos los casos de prueba a la vez .

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
fuente
9

Java, 97 bytes

Porque, ya sabes, 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;}

Esta es una lambda para a BiFunction<String, Character, Boolean>.

ey oparece estar invertido en la declaración de devolución porque aparentemente mi lógica era al revés.

CAD97
fuente
5

Python 2, 51 bytes

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

Esto se basa en una idea de Sp3000 para contar 1 en la representación de cadena de la lista de códigos de caracteres en binario en lugar de sumar para cada carácter.

El nuevo truco es manejar ey oen esto también. Si efuera impar o opar, podríamos anteponer el bit de paridad a la cadena antes de hacer el conteo (volteándolos porque '1' es Verdad). Lamentablemente, no lo son. Pero, si eliminamos todos menos sus dos últimos bits, ahora es cierto.

e 0b11001|01
o 0b11011|11 

Esto se hace eliminando el primer 9carácter de la representación de cadena.

['0b11001|01', 
xnor
fuente
¡Guau, esa es una forma muy buena de manejar eo!
Sp3000
4

Jalea, 9 8 bytes

OBFSḂ⁼V}

Pruébalo en línea!

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

Gracias a Dennis por un byte!

Pomo de la puerta
fuente
1
Estaba tratando de encontrar una respuesta de Jelly, pero esas reglas de encadenamiento me eluden :-)
Luis Mendo
2
@LuisMendo estoy en el mismo bote; esta es mi primera respuesta de Jelly después de haber estado tratando de aprenderla durante ... demasiado tiempo: P
Pomo de la puerta
Eso V}... ese fue realmente genial !!! (Dennis es un verdadero golfista) +1 Superó todos mis intentos.
Erik the Outgolfer
4

C, 62 bytes

  • 12 bytes guardados gracias a @LevelRiverSt y @TonHospel.

XOR tiene la buena propiedad de que se puede usar para reducir las cadenas a un carácter, mientras se conserva la paridad.

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

Ideona

Trauma digital
fuente
1
27030>>((p^p>>4)&15)&1 debería calcular la paridad de p y es incluso 1 byte más corto
Ton Hospel
1
El espacio no char *ses necesario
Ton Hospel
2
62 Bytes: f(s,p)char*s;{for(p/=8;*s;)p^=*s>>4^*s++;p^=p/4;return p%4%3;}El %3volverá siempre 0 para un 0, pero puede volver 1 o 2 para un 1. Esto es aceptable bajo las normas:truthy if it's a 1
nivel del río St
1
27030>>((p^p>>4)&15)&1. Bueno, err, obviamente. ;-)
Digital Trauma
@LevelRiverSt ¡Brillante! ¡Gracias!
Trauma digital
4

Python, 58 57 bytes

lambda s,p:sum(bin(ord(c)).count("1")for c in s)&1!=p>'e'
orlp
fuente
1
53 (solo Python 2):lambda s,p:`map(bin,map(ord,s))`.count('1')%2^(p>'e')
Sp3000
Puede guardar un byte con !=p>'e'.
xnor
Espere, mi byte-save en realidad no funciona porque Python lo trata como una desigualdad encadenada.
xnor
lambda s,p:`map(bin,map(ord,p+s))`[8:].count('1')%2
xnor
@xnor Solo publica tu propia respuesta.
orlp
3

Pyth, 12 bytes

q@"oe"sjCz2w

Banco de pruebas.

         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
Pomo de la puerta
fuente
3

JavaScript (ES6), 84 72 bytes

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

El giro de bits resultó ser más corto que la conversión a base 2 y contando 1s.

Neil
fuente
2

Perl, 29 bytes

Incluye +2 para -p

Ejecutar con la entrada en STDIN como cadena de espacio de caracteres de paridad, p. Ej.

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

parity.pl

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

J, 27 bytes

'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
millas
fuente
1

JavaScript (ES6), 69 bytes

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

PowerShell v2 +, 91 bytes

/ yo llora en un rincón

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

Sí ... entonces, la conversión de base no es una buena opción para PowerShell. La conversión de la cadena de entrada a la representación binaria $a|%{[convert]::toString(+$_,2)}es de 32 bytes en sí misma ...

Toma entrada $ay $b, explícitamente, convierte $acomo una matriz de caracteres en el proceso. Luego verificamos si $bes -equal a o, y -xoreso con la otra mitad del programa. Para esa parte, tomamos la cadena de entrada $a, la canalizamos a través de un bucle para convertir cada letra en binario, -jointodas juntas para formar una cadena sólida y -replacetodas las 0s sin nada. Luego contamos el .lengthde esa cadena y la tomamos mod-2 para determinar si es par o impar, lo que convenientemente será 0o 1, perfecto para el -xor.

Volveremos Trueo en Falseconsecuencia. Ver casos de prueba a continuació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
AdmBorkBork
fuente
1

Factor, 85 bytes

Por alguna razón, no pude entender esto hasta hace unos minutos, cuando simplifiqué (¿y quizás acorté?) El código.

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

?es como un operador ternario: prueba la veracidad del tercer elemento de la pila y selecciona el truevalor o el falsevalor.

Es más o menos equivalente al siguiente pseduocode tipo C:

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

El resto del código es bastante simple:

[                       ! 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.
gato
fuente
1

Código de máquina IA-32, 15 bytes

Hexdump:

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

Código de montaje:

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

Esta es una función que recibe su primer argumento (cadena) en ecxy su segundo argumento (char) en dl. Devuelve el resultado eax, por lo que es compatible con la fastcallconvención de llamada.

Este código dobla las reglas cuando usa la setpoinstrucción:

No se permiten las unidades integradas que cuentan el número de bits "encendidos" en una cadena o carácter

Esta instrucción establece alel bit de paridad calculado por la instrucción anterior, por lo que tengo estos dos detalles sobre las reglas:

  • No cuenta el número de bits "on", ¡calcula el bit de paridad directamente!
  • Técnicamente, es la instrucción anterior ( xor) la que calcula el bit de paridad. La setpoinstrucción solo lo mueve al alregistro.

Estos detalles semánticos fuera del camino, aquí está la explicación de lo que hace el código.

Las representaciones de los personajes son:

'e' = 01100101
'o' = 01101111

Si agregamos 1 a ellos, tienen la paridad correcta:

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

Entonces XORtodos los caracteres de la cadena, inicializando ala estos valores, lo que da la respuesta.


La primera instrucción es en movzx eax, dllugar de la más obvia (y más corta) mov al, dl, porque quiero tener el número 0 en un registro ( ahen este caso) para poder compararlo en el orden correcto (en 0, [ecx]lugar de [ecx], 0).

anatolyg
fuente
1

Julia, 58 47 45 40 bytes

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

Esta es una función que acepta una cadena y un carácter y devuelve un entero.

Para obtener el número de unos en la representación binaria, primero aplicamos la binfunción a cada carácter en la cadena, lo que nos da una matriz de cadenas binarias. Luego, reduzca a uno usando prod(ya que *es la concatenación de cadenas en Julia) y tome la intersección establecida de esa cadena y el código de caracteres para 1, lo que nos da una cadena de unos. El último índice de esa cadena es el número de unidades. XOR esto con 1 si el carácter proporcionado es o y 0 de lo contrario, entonces obtenemos la paridad usando bit a bit AND 1.

Pruébalo en línea! (incluye todos los casos de prueba)

¡Ahorró 18 bytes gracias a Dennis!

Alex A.
fuente
1

05AB1E , 15 , 13 bytes

Código:

€ÇbSOÈ„oe²k<^

Entrada de ejemplo:

Programming Puzzles and Code-Golf
o

Salida de ejemplo:

1

Explicación:

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

Gracias a Adnan por guardar 2 bytes.

Emigna
fuente
¡Wow muy agradable! Puedes jugar golf dos bytes usando el ²comando. Esto empuja automáticamente la segunda entrada en la parte superior de la pila. Además, las cadenas de dos caracteres se pueden acortar usando . Entonces "oe"es equivalente a . Para 13 bytes: €ÇbSOÈ„oe²k<^:)
Adnan
05AB1E también usa la codificación CP-1252 , por lo que cada carácter aquí es 1 byte :).
Adnan
@Adnan: ¡Gracias! Usé notepad ++ para el bytecount y simplemente asumí que contaba caracteres: P
Emigna
0

Ruby, 57 bytes

Si 0fue falsey en Ruby, ==probablemente podría cambiarse a solo -, o podría haber otras optimizaciones, pero no lo es.

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

Retina , 102 bytes

Toma la cadena en la primera línea y la letra en la segunda línea. Utiliza la codificación ISO 8859-1.

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

Pruébalo en línea

La clase de caracteres en la primera línea coincide con cualquier carácter con un número impar de unos en la representación binaria.

Descripción de cómo funciona la detección par / impar con expresiones regulares aquí .

mbomb007
fuente
0

Octava, 56 bytes

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

La bitunpackfunción, para caracteres ASCII, los devuelve en orden little-endian. Entonces, colocando la bandera de paridad al final de nuestra cadena, desempacando todo y soltando los últimos 5 bits, podemos resumir todo el mod 2 para nuestra respuesta final.

Uso:

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

 Lisp común, 87

(lambda(s p)(=(mod(reduce'+(mapcar'logcount(map'list'char-code s)))2)(position p"oe")))
  • Suma el logcount de char-codes de s.
  • El resto de esto, cuando se divide por 2, se compara con la posición del argumento de paridad pen la cadena "oe"(0 o 1). Por ejemplo, si hay 4 unidades, el resto es cero. Si p es o, entonces no se debe agregar ningún bit adicional y la prueba devuelve falso.

Bonito estampado

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

Java, 91 bytes

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

Hice lo mismo que @ CAT97, pero eliminé algunos caracteres usando el módulo 8 y concatenado de @Luis Mendo y el uso de int en lugar de boolean.

Esta es una lambda para a BiFunction<String, Character, Boolean>.

miselico
fuente
0

Matlab, 49 bytes

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

dónde:

  • x es la cadena de entrada;
  • p es 'e' para paridad par y 'o' para paridad impar.

Por ejemplo:

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

ans =

     0
PieCot
fuente
0

Herramientas Bash y Unix (72 bytes)

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

Excepciones scomo el primer y pel segundo argumento. Afortunadamente, los últimos 3 bits de oy etiene paridad par e impar, respectivamente.

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

El suministro de la entrada a través de <<<agrega un carácter de avance de línea, pero la paridad de \nes par, por lo que no es un problema.

pgy
fuente